Kuk*_*ula 2 sql postgresql upsert
我创建了下表:
CREATE TABLE t1(
a INT UNIQUE,
b varchar(100) NOT NULL,
c INT,
d INT DEFAULT 0,
PRIMARY KEY (a,b));
Run Code Online (Sandbox Code Playgroud)
在单行上,此 SQL 语句效果很好(SQL 是在代码中生成的):
INSERT INTO t1 (a, b, c, d)
VALUES($params.1, '${params.2}', $params.3, params.4)
ON CONFLICT (a,b) DO
UPDATE SET d=params.4
Run Code Online (Sandbox Code Playgroud)
是否可以一次更新插入多行?对于每次更新, 的值params.4都是不同的。
var sqlStr = 'INSERT INTO t1 (a, b, c, d) VALUES '
for(let i =0 i < params.length; i++){
sqlStr += `(${params[i].1}, '${params[i].2}', ${params[i].3}, ${params[i].4}),`
}
sqlStr = sqlStr.substring(0, sqlStr .length - 2) +')';
sqlStr += 'ON CONFLICT (a,b) DO UPDATE SET **d=???**' <-- this is the problem
Run Code Online (Sandbox Code Playgroud)
params[i].4每行都有不同的值,并且该ON CONFLICT语句仅出现一次(不是每行)并且SET不支持WHERE.
例如,如果我的表有以下行:
a | b | c | d
---+---+---+---
1 | 1 | 1 | 1
2 | 2 | 2 | 2
Run Code Online (Sandbox Code Playgroud)
我的新输入是[(1,'1',1,11),(2,'2',2,22),(3,'3',3,3)].
有两个冲突 -(1,1)和(2,2)。结果应该是:
a | b | c | d
---+---+---+---
1 | 1 | 1 | 11
2 | 2 | 2 | 22
3 | 3 | 3 | 3
Run Code Online (Sandbox Code Playgroud)
UPSERT ( INSERT ... ON CONFLICT ... DO UPDATE) 跟踪自动命名的特殊表中排除的行EXCLUDED。手册:
请注意,特殊
excluded表用于参考最初建议插入的值
所以这真的非常简单:
INSERT INTO t1 (a, b, c, d)
VALUES (...)
ON CONFLICT (a,b) DO UPDATE
SET d = EXCLUDED.d; -- that's all !!!
Run Code Online (Sandbox Code Playgroud)
除了更简单和更快之外,与您提出的解决方案还有细微的极端情况差异。手册:
请注意,所有每行
BEFORE INSERT触发器的影响都反映在excluded值中,因为这些影响可能导致该行被排除在插入之外。
另外,列DEFAULT值已应用到EXCLUDED未给出输入的行中。(就像DEFAULT 0你的专栏一样d。)
两者通常都是您想要的。
| 归档时间: |
|
| 查看次数: |
3567 次 |
| 最近记录: |