sql - INSERT SELECT FROM VALUES 类型转换

标签 sql postgresql sql-types

通常需要从 SELECT 表达式中插入(例如用 WHERE 子句限定),但这会使 postgresql 对列类型感到困惑。

例子:

CREATE TABLE example (a uuid primary key, b numeric);
INSERT INTO example 
SELECT a, b 
FROM (VALUES ('d853b5a8-d453-11e7-9296-cec278b6b50a', NULL)) as data(a,b);
=> ERROR:  column "a" is of type uuid but expression is of type text

这可以通过显式输入值来解决:

INSERT INTO example 
SELECT a, b 
FROM (VALUES ('d853b5a8-d453-11e7-9296-cec278b6b50a'::uuid, NULL::numeric)) as data(a,b);

但这很麻烦,而且会增加维护负担。有什么方法可以让 postgres 理解 VALUES 表达式与表行具有相同的类型,即类似于

VALUES('d853b5a8-d453-11e7-9296-cec278b6b50a', NULL)::example%ROWTYPE

编辑:

使用 (data::example).* 的建议很简洁,但不幸的是,当与 WHERE 子句结合使用时,它似乎完全搞砸了 postgres 查询规划器:

INSERT INTO example 
SELECT (data::example).* 
FROM (VALUES ('d853b5a8-d453-11e7-9296-cec278b6b50a', NULL)) as data 
WHERE NOT EXISTS (SELECT * FROM example 
                  WHERE (data::example) 
                  IS NOT DISTINCT FROM example);

对于一张大 table ,这需要几分钟。

最佳答案

可以将记录转换为表格的行类型:

INSERT INTO example 
SELECT (data::example).*
FROM (
    VALUES 
      ('d853b5a8-d453-11e7-9296-cec278b6b50a', NULL),
      ('54514c89-f188-490a-abbb-268f9154ab2c', 42)
) as data;

data::example 将整个行转换为 example 类型的记录。 (...).* 然后将其转换为表类型 example

中定义的列

关于sql - INSERT SELECT FROM VALUES 类型转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47535937/

相关文章:

mysql - SQL中的SQL连接和子查询

postgresql - IBM 云 : Connecting SQuirreL to Databases for PostgreSQL gives SSL error

mysql - SQL 整数类型

sql - SQL Server 中为 null 时的情况

android - 按总和排序(分数)desc 返回错误结果

postgresql - Postgresql 中的分割和顺序连接字符串部分

mySQL 表创建失败 - 错误 1064

php - 如何实现 SQL 语句来创建 either/or 功能

java - 关于从终端编译 Java 程序的 JDBC 驱动程序问题