📅  最后修改于: 2020-11-30 07:48:27             🧑  作者: Mango
在本节中,我们将借助CREATE DOMAIN和CREATE TYPE命令来了解PostgreSQL用户定义数据类型的工作方式,并查看其示例。
除了内置数据类型外, PostgreSQL还提供了以下命令来生成用户定义的数据类型:
Commands | Description |
---|---|
CREATE DOMAIN | It generates a user-defined data type with constraints, For Example, CHECK, NOT NULL, etc. |
CREATE TYPE | The create type command is used to generate a composite type, which is used in stored procedures as per the data types of returned values. |
现在,让我们看看CREATE DOMAIN和CREATE TYPE命令如何处理PostgreSQL用户定义的数据。
在PostgreSQL中,域在模式范围内具有唯一的名称,因为Domain是具有选择性约束的数据类型,例如CHECK,NOT NULL 。对于合并具有共同约束的字段的组织,域始终是有益的。
例如,假设我们有一些包含相似列的表,这些列不包含NULL和空格。
换句话说,我们可以说某些表可能包含text列,它们需要CHECK约束来确保值不为null并保持空格扩展。
让我们看一个示例示例,以了解Domain数据类型如何工作。
我们将在CREATE命令的帮助下创建一个新表作为收件人,并使用INSERT命令插入一些值。
要将收件人创建到组织数据库中,我们使用CREATE命令。
“收件人”表包含以下列,例如“收件人ID”,“名字”,“姓氏”和“电子邮件”。
CREATE TABLE Recipients (
Recipient_ID SERIAL PRIMARY KEY,
First_name VARCHAR NOT NULL,
Last_name VARCHAR NOT NULL,
Email VARCHAR NOT NULL,
CHECK (
First_name !~ '\s'
AND Last_name !~ '\s'
)
);
输出量
执行上述命令后,我们将获得以下消息,该消息显示“收件人”表已成功创建到“组织”数据库中。
我们在上表中使用了CHECK约束,即First_name和Last_name列不接收空格和空值。
因此,在这里我们可以创建为person_name域,并在各个列中重用它来定义CHECK约束。
在下面的命令中,我们使用CREATE DOMAIN命令使用VARCHAR数据类型生成一个名为person_name的新域,该域不使用空格和NULL值:
CREATE DOMAIN person_name AS
VARCHAR NOT NULL CHECK (value!~ '\s');
输出量
执行完上述命令后,我们将获得以下消息窗口,显示已成功为“收件人”表创建了person_name域。
创建域之后,我们可以使用person_name域作为First_name和Last_name列的数据类型,作为一致的内置类型,如下面的命令所示:
CREATE TABLE Recipients1 (
Recipient_ID SERIAL PRIMARY KEY,
First_name person_name,
Last_name person_name,
Email VARCHAR NOT NULL
);
输出量
执行完上述命令后,我们将获得以下消息窗口,该窗口显示已成功创建“收件人1”表。
注意:
成功创建Recipients1表后,我们将使用INSERT命令在其中插入一些值。
在下面的命令中,我们将一些值插入Recipients1表中。
INSERT INTO Recipients (First_name, Last_name, Email)
VALUES('Mike',' W Ross','rossmike11@gmail.com');
输出量
实施上述命令后,PostgreSQL为关系“收件人”违反了检查约束“ recipients_check”而引发以下错误新行,因为last_name列包含空格,如下面的屏幕快照所示:
要解决以上错误,我们将在不提供任何空格的情况下提供Last_name,如以下命令所示:
INSERT INTO Recipients (First_name, Last_name, Email)
VALUES('Mike','Ross','rossmike11@gmail.com');
输出量
成功执行以上命令后,我们将获得以下消息窗口,该窗口显示特定值已插入到“收件人”表中。
我们将按照以下过程在psql中查看域:
步骤1
首先,我们将在本地系统中打开psql ,然后连接到要创建表的数据库。
第2步
为了连接组织数据库,我们将输入以下命令:
postgres=# \c Organization
输出量
执行上述命令后,我们将获得以下输出:
第三步
现在,我们将输入以下命令以查看组织数据库中的域。
Organization=# \dD
输出量
实施上述命令后,我们将获得以下输出,该输出显示现有域,即组织数据库中存在的person_name:
我们可以单独使用DROP DOMAIN或ALTER DOMAIN命令删除或修改域。
DROP DOMAIN IF EXISTS person_name;
输出量
执行上述命令后,我们将收到以下错误消息:我们不能删除person_name类型,因为其他对象依赖它。
因此,在上面的命令中,我们使用CASCADE,因为它用于自动删除对象,具体取决于表。
DROP DOMAIN IF EXISTS person_name CASCADE;
输出量
执行上述命令后,我们将获得以下结果,显示person_name域已成功删除。
PostgreSQL CREATE TYPE命令为我们提供了一个复合类型,该复合类型可用作函数的返回类型。
例如:如果我们想要一个函数,该函数返回多个值: item _id,item_name和item_price
步骤1
首先,我们将创建诸如Item_details之类的类型,如下面的命令所示:
CREATE TYPE Item_details AS (
item_id INT,
item_name VARCHAR,
item_price Numeric(5,2)
);
输出量
执行完上述命令后,我们将获得以下消息窗口,该窗口显示item_details类型已成功创建。
第2步
之后,我们将item_details数据类型用作函数的返回类型,如以下命令所示:
CREATE OR REPLACE FUNCTION get_Item_details (I_id INT)
RETURNS Item_details AS
$$
SELECT item_id, item_name, item_price
FROM items
WHERE item_id = I_id ;
$$
LANGUAGE SQL;
输出量
执行上述命令后,我们将获得以下消息窗口,该窗口显示该函数已成功创建。
第三步
最后,我们将在SELECT命令的帮助下调用get_Item_details()函数:
SELECT * FROM get_Item_details(3);
输出量
实现上述命令后,我们将获得以下输出,其中显示特定的id项目,即Audi A7 。
就像我们使用Drop domain命令删除域一样,我们可以使用DROP TYPE命令删除用户定义的数据类型,并且我们可以使用ALTER TYPE命令修改用户定义的数据类型。
DROP TYPE IF EXISTS Item_details;
输出量
我们将得到与上述类似的错误(放置域),因为其他对象在执行上述命令时都依赖于该错误,所以无法删除类型Item_details。
要解决此错误,我们使用CASCADE,因为CASCADE用于自动删除对象,具体取决于表。
DROP TYPE IF EXISTS Item_details CASCADE;
输出量
执行完上述命令后,我们将获得以下消息窗口,该窗口显示指定的类型已成功删除。
如果使用的是psql程序,则可以在以下命令的帮助下列出现有数据库中的所有用户定义类型:
\dT or \dT+
例如,我们将按照以下过程在psql中查看类型:
步骤1
首先,我们将在本地系统中打开psql ,然后连接到要创建表的数据库。
第2步
为了连接组织数据库,我们将输入以下命令:
postgres=# \c Organization
第三步
现在,我们将输入以下命令以查看组织数据库中的域。
Organization=# \dT
输出量
实现上述命令后,我们将获得以下输出,其中显示了现有的TYPE,即组织数据库中存在的Item_details:
Organization=# \dT+
输出量
执行上述命令后,我们将获得以下输出,该命令显示现有的TYPE,这是Organization数据库中存在的Item_details:
在最有用的操作的PostgreSQL用户定义数据类型部分中,我们学习了以下主题: