这是我要在表中插入多行的PostgreSQL查询的简化版本:
INSERT INTO my_table (a, b, datasource)
VALUES
('foo', 'bar', 'my source'),
('foo', DEFAULT, 'my source'),
(DEFAULT, 'bar', 'my source');
请注意,DEFAULT
值可能出现在列a
或b
中。
这很好,但是我只想插入满足某些条件的行,此外,删除重复的值对于所有要插入的行都是恒定的也是很好的。
因此,我尝试将其更改为以下内容:
INSERT INTO my_table (a, b, datasource)
SELECT v.*, 'my source'
FROM (VALUES ('foo', 'bar'), ('foo', DEFAULT), (DEFAULT, 'bar')) AS v (a, b)
WHERE v.a = 'foo';
这将导致错误:DEFAULT is not allowed in this context
。
我该如何解决?
可能值得注意的是,实际上,WHERE
条件实际上很复杂并且涉及其他表。此外,一次要插入几千行,并以编程方式生成值表达式。可以这样做,以便输出表的文字默认值而不是DEFAULT
,但是这需要在数据库外部进行硬编码,这是我要避免的(因为如果在数据库中更改它们而忘记了,更新硬编码的值,将会引起问题。
答案 0 :(得分:0)
由于我找不到更优雅的东西(如当前缺乏其他答案所证明),我最终使用了将这些值首先插入临时表中的建议。 PostgreSQL使创建具有相同默认值但没有其他一些不必要内容的“克隆”表(using the LIKE
keyword)变得非常容易:
CREATE TEMPORARY TABLE temp_table (
LIKE my_table INCLUDING DEFAULTS
);
INSERT INTO temp_table (a, b)
VALUES
('foo', 'bar'),
('foo', DEFAULT),
(DEFAULT, 'bar');
然后,只需使用临时表代替之前的VALUES
子句即可。
INSERT INTO my_table (a, b, datasource)
SELECT a, b, 'my source'
FROM temp_table
WHERE a = 'foo';
一个小警告是您无法避免将NOT NULL
约束复制到临时表中。例如,如果datasource
列为NOT NULL
(并且没有默认值),则必须在第一个INSERT
查询中添加该值(或占位符),或删除列。