【发布时间】:2016-08-23 09:07:50
【问题描述】:
我想向 Informix 数据库表中添加一行,但是当存在具有相同唯一键的行时,我想更新该行。
我找到了 MySQL here 的解决方案,如下所示,但 Informix 需要它:
INSERT INTO table (id, name, age) VALUES(1, "A", 19) ON DUPLICATE KEY UPDATE name="A", age=19
【问题讨论】:
我想向 Informix 数据库表中添加一行,但是当存在具有相同唯一键的行时,我想更新该行。
我找到了 MySQL here 的解决方案,如下所示,但 Informix 需要它:
INSERT INTO table (id, name, age) VALUES(1, "A", 19) ON DUPLICATE KEY UPDATE name="A", age=19
【问题讨论】:
您可能应该使用MERGE 语句。
给定一个合适的table:
create table table (id serial not null primary key, name varchar(20) not null, age integer not null);
此 SQL 有效:
MERGE INTO table AS dst
USING (SELECT 1 AS id, 'A' AS name, 19 AS age
FROM sysmaster:'informix'.sysdual
) AS src
ON dst.id = src.id
WHEN NOT MATCHED THEN INSERT (dst.id, dst.name, dst.age)
VALUES (src.id, src.name, src.age)
WHEN MATCHED THEN UPDATE SET dst.name = src.name, dst.age = src.age
Informix 有一些有趣的规则,允许在不需要双引号的情况下使用关键字作为标识符(事实上,除非您在环境中设置了 DELIMIDENT,否则双引号只是字符串周围单引号的替代方案)。
【讨论】:
INSERT ... ON DUPLICATE KEY UPDATE ... 相差甚远。
您可以使用MERGE 语句尝试相同的行为:
示例,创建目标表:
CREATE TABLE target
(
id SERIAL PRIMARY KEY CONSTRAINT pk_tst,
name CHAR(1),
age SMALLINT
);
创建一个临时源表,插入你想要的记录:
CREATE TEMP TABLE source
(
id INT,
name CHAR(1),
age SMALLINT
) WITH NO LOG;
INSERT INTO source (id, name, age) VALUES (1, 'A', 19);
合并将是:
MERGE INTO target AS t
USING source AS s ON t.id = s.id
WHEN MATCHED THEN
UPDATE
SET t.name = s.name, t.age = s.age
WHEN NOT MATCHED THEN
INSERT (id, name, age)
VALUES (s.id, s.name, s.age);
您会看到记录已插入,然后您可以:
UPDATE source
SET age = 20
WHERE id = 1;
然后再次测试 MERGE。
另一种方法是创建一个存储过程,基本上你会做INSERT语句并检查SQL错误代码,如果是-100你去UPDATE。
类似:
CREATE PROCEDURE sp_insrt_target(v_id INT, v_name CHAR(1), v_age SMALLINT)
ON EXCEPTION IN (-100)
UPDATE target
SET name = v_name, age = v_age
WHERE id = v_id;
END EXCEPTION
INSERT INTO target VALUES (v_id, v_name, v_age);
END PROCEDURE;
【讨论】:
MERGE 甚至不接近 INSERT ... ON DUPLICATED KEY UPDATE ...。在上面的示例中,只需在源表中添加具有重复 id 的另一行,例如INSERT INTO source (id, name, age) VALUES (1, 'A', 19); INSERT INTO source (id, name, age) VALUES (1, 'B', 20); 再试一次。 Informix 数据库会抱怨Could not insert new row - duplicate value in a UNIQUE INDEX column。