gpi*_*ino 129 database postgresql rules
某些SQL服务器具有一个功能,INSERT如果它违反主/唯一键约束,则跳过该功能.例如,MySQL有INSERT IGNORE.
什么是模仿的最好方式INSERT IGNORE,并ON DUPLICATE KEY UPDATE与PostgreSQL的?
war*_*ren 150
使用PostgreSQL 9.5,这是现在的本机功能(就像MySQL已经有几年了):
INSERT ......在冲突中没有/更新("UPSERT")
9.5为"UPSERT"操作提供支持.INSERT扩展为接受ON CONFLICT DO UPDATE/IGNORE子句.此子句指定在发生可能的重复违规时要采取的替代操作.
...
新语法的进一步示例:
INSERT INTO user_logins (username, logins)
VALUES ('Naomi',1),('James',1)
ON CONFLICT (username)
DO UPDATE SET logins = user_logins.logins + EXCLUDED.logins;
Run Code Online (Sandbox Code Playgroud)
Eog*_*anM 97
编辑:如果你错过了沃伦的回答,那么PG9.5现在已经有了这个原因; 时间升级!
在Bill Karwin的回答的基础上,阐明基于规则的方法将是什么样的(从同一个数据库中的另一个模式转移,并使用多列主键):
CREATE RULE "my_table_on_duplicate_ignore" AS ON INSERT TO "my_table"
WHERE EXISTS(SELECT 1 FROM my_table
WHERE (pk_col_1, pk_col_2)=(NEW.pk_col_1, NEW.pk_col_2))
DO INSTEAD NOTHING;
INSERT INTO my_table SELECT * FROM another_schema.my_table WHERE some_cond;
DROP RULE "my_table_on_duplicate_ignore" ON "my_table";
Run Code Online (Sandbox Code Playgroud)
注意:该规则适用于所有INSERT操作,直到删除规则,因此不是特别的.
Mag*_*der 31
尝试做一个更新.如果它没有修改任何意味着它不存在的行,那么插入也是如此.显然,您在事务中执行此操作.
如果您不想在客户端添加额外的代码,您当然可以将其包装在一个函数中.在这种想法中,你还需要一个非常罕见的竞争条件的循环.
文档中有一个例子:http://www.postgresql.org/docs/9.3/static/plpgsql-control-structures.html,示例40-2就在底部.
这通常是最简单的方法.你可以用规则做一些魔术,但它可能会变得更加混乱.我建议在任何一天使用wrap-in-function方法.
这适用于单行或几行值.如果你正在处理大量的行,例如来自子查询,你最好把它分成两个查询,一个用于INSERT,一个用于UPDATE(当然是一个适当的连接/子选择 - 不需要写你的主要过滤两次)
han*_*ari 24
对于那些拥有Postgres 9.5或更高版本的人来说,新的ON CONFLICT DO NOTHING语法应该有效:
INSERT INTO target_table (field_one, field_two, field_three )
SELECT field_one, field_two, field_three
FROM source_table
ON CONFLICT (field_one) DO NOTHING;
Run Code Online (Sandbox Code Playgroud)
对于我们这些拥有早期版本的人来说,这种正确的联接将起作用:
INSERT INTO target_table (field_one, field_two, field_three )
SELECT source_table.field_one, source_table.field_two, source_table.field_three
FROM source_table
LEFT JOIN target_table ON source_table.field_one = target_table.field_one
WHERE target_table.field_one IS NULL;
Run Code Online (Sandbox Code Playgroud)
Key*_*eyo 23
要获得插入忽略逻辑,您可以执行以下操作.我发现只需从文字值的select语句中插入效果最好,然后就可以使用NOT EXISTS子句屏蔽重复的键.为了获得重复逻辑的更新,我怀疑需要一个pl/pgsql循环.
INSERT INTO manager.vin_manufacturer
(SELECT * FROM( VALUES
('935',' Citroën Brazil','Citroën'),
('ABC', 'Toyota', 'Toyota'),
('ZOM',' OM','OM')
) as tmp (vin_manufacturer_id, manufacturer_desc, make_desc)
WHERE NOT EXISTS (
--ignore anything that has already been inserted
SELECT 1 FROM manager.vin_manufacturer m where m.vin_manufacturer_id = tmp.vin_manufacturer_id)
)
Run Code Online (Sandbox Code Playgroud)
小智 20
INSERT INTO mytable(col1,col2)
SELECT 'val1','val2'
WHERE NOT EXISTS (SELECT 1 FROM mytable WHERE col1='val1')
Run Code Online (Sandbox Code Playgroud)
小智 13
正如@hanmari 在他的评论中提到的。插入 postgres 表时,冲突 (..) do nothing 是用于不插入重复数据的最佳代码。:
query = "INSERT INTO db_table_name(column_name)
VALUES(%s) ON CONFLICT (column_name) DO NOTHING;"
Run Code Online (Sandbox Code Playgroud)
ON CONFLICT 代码行将允许插入语句仍然插入数据行。查询和值代码是从 Excel 插入日期到 postgres db 表的示例。我在 postgres 表中添加了约束,用于确保 ID 字段是唯一的。我没有在相同的数据行上运行删除,而是添加了一行 sql 代码,从 1 开始对 ID 列重新编号。示例:
q = 'ALTER id_column serial RESTART WITH 1'
Run Code Online (Sandbox Code Playgroud)
如果我的数据有一个 ID 字段,我不会将其用作主要 ID/序列 ID,而是创建一个 ID 列并将其设置为序列。我希望这些信息对每个人都有帮助。*我没有软件开发/编码方面的大学学位。我在编码方面所知道的一切,都是我自己学习的。
Bil*_*win 12
看起来PostgreSQL支持称为规则的模式对象.
http://www.postgresql.org/docs/current/static/rules-update.html
您可以ON INSERT为给定的表创建规则,NOTHING如果存在具有给定主键值的行,或者使其执行UPDATE而不是INSERTif存在具有给定主键值的行.
我自己没试过,所以我不能从经验中说话或提供一个例子.
此解决方案避免使用规则:
BEGIN
INSERT INTO tableA (unique_column,c2,c3) VALUES (1,2,3);
EXCEPTION
WHEN unique_violation THEN
UPDATE tableA SET c2 = 2, c3 = 3 WHERE unique_column = 1;
END;
Run Code Online (Sandbox Code Playgroud)
但它有一个性能缺陷(请参阅PostgreSQL.org):
包含 EXCEPTION 子句的块比没有 EXCEPTION 子句的块进入和退出的成本要高得多。因此,不要在不需要的情况下使用 EXCEPTION。
| 归档时间: |
|
| 查看次数: |
113642 次 |
| 最近记录: |