我有一个要在PostgreSQL数据库中执行的SQL文件,该文件包含用于创建表和复合类型的SQL语句,然后将一些值插入到创建的表和复合类型中.

CREATE TYPE address_object AS (
    state char(2),
    zip char(10)
);

CREATE TYPE embedded_address AS (
    state char(2),
    zip char(10),
    preaddr address_object  
);

CREATE TYPE address_value AS (
    state char(2),
    zip char(10)
);

CREATE TYPE person AS (
    name char(20),
    age numeric,
    address address_object
);

CREATE TABLE customerval (
    custno numeric,
    addr address_value
);

CREATE TABLE extaddr OF address_object;

CREATE TABLE customerobj (
    custno numeric,
    addr address_object  
);

CREATE TABLE embextaddr OF embedded_address;

CREATE TABLE emp (
    emp_id numeric,
    emp_info person
);

CREATE TABLE empref (
    emp_id numeric,
    emp_info person  
);

CREATE TABLE extper OF person;

-- Insert data
INSERT INTO customerval VALUES (100, ROW('CA'::char(2), '94065'::char(10)));
INSERT INTO extaddr VALUES (ROW(LEFT('CA', 2), CAST('94065' AS CHAR(10))));
INSERT INTO extaddr VALUES (ROW(LEFT('CA',2),CAST('98765' AS char(10))));
INSERT INTO extaddr VALUES (ROW(LEFT('CA' ,2),CAST('95117' AS char(10))));
INSERT INTO embextaddr VALUES (ROW(LEFT('CA',2),CAST('95117' AS char(10), NULL))));

当我运行该文件时,我收到一些错误,例如第一个INSERT语句: 错误:类型字符(2)的值太长 2STATEMENT:插入extaddr值(ROW(LEFT(‘CA’,2),CAST(‘94065’as CHAR(10); Psql:file.sql:53:错误:类型字符(2)的值太长

在数据库中创建表和复合类型,并且第一次插入成功.由于上述错误,最后三条INSERT语句失败.

INSERT INTO extaddr VALUES (ROW(LEFT('CA', 2), CAST('94065' AS CHAR(10))));```.

推荐答案

拆下外部的row() constructors.

您可能会认为CREATE TABLE my_table OF my_type;会创建一个只有一列类型为my_type的表--事实并非如此.From the doc:

创建类型化表时,列的数据类型由基础复合类型确定

每一行都遵循类型的 struct ,只有在遇到类型类型的情况时才需要封装值,比如第一个插入中的customerval.address_value.Demo at db<>fiddle:

INSERT INTO customerval VALUES (100, ROW('CA','94065')::address_value);
INSERT INTO extaddr VALUES ('CA', '94065'),
                           ('CA', '98765'),
                           ('CA', '95117');
INSERT INTO embextaddr VALUES ('CA','95117',NULL);

我猜left()在那里是因为你觉得'CA'对于char(2)来说太长了.实际发生的情况是,PostgreSQL只看到一个值进入(由您的row()调用产生),并试图将其写入第一列,它发现第一列是不同类型的char(2).所以它试图对整个过程进行强制转换--不匹配,因此出现错误.Here's the doc on that:

VALUES子句或query提供的值从左到右与显式或隐式列列表相关联.

显式或隐式列列表中不存在的每一列都将使用缺省值填充,如果没有,则使用其声明的缺省值或NULL填充.

如果任何列的表达式不是正确的数据类型,则将try 自动类型转换.

只有当您试图将too many个值填充到具有too few columns个值的表中时,才会报告字段号不匹配,但在本例中,它假定第一列(char(2))中只有一个值(从row()产生).报告失败的自动强制转换try 的类型不匹配.


如果你把这些值打包成这样,你也可以用().*来解包:

INSERT INTO extaddr VALUES ((row('CA', '94065')).*),
                           ((row('CA', '98765')).*),
                           ((row('CA', '95117')).*);

Sql相关问答推荐

如何将多个 Select 查询从一个表中组合出来

有没有一种正确的方法来利用SQL UNION来从三个潜在查询中 Select 最大值?

Select 起始参数和截止参数之间的间隔,包括与期间重叠的参数

如何嵌套两条SQL语句

替换上一个或下一个值中的空值并添加其价格日期

在SQL GROUP BY中的某些行之后执行计算

从结果SQL查询中排除空值

如何在Postgres中为单值输入多行?

使用与JOIN一起使用的查询后进行分页和排序

将具有嵌套 XML 的列转换为 SQL 中的表格格式?

如何在Hive SQL中分别按多列进行分组?

如何在 postgres 中旋转某些数据字段

SQL 按 id 运行总计并受条件限制(在窗口上)

如何将特定值从 JSON 列中的一个字段移动到 PostgreSQL 中的另一个字段?

在 SQL 中使用循环遍历按时间顺序排列的数据

为数组中的每个元素从表中收集最大整数

如何从 2 个 SQLite 表构建嵌套对象?

如何在一个存储过程中创建全局临时表,并在另一个存储过程中使用它

连接表时避免重复

从多个连接返回 1 行到同一个表 - SQL Server