我想在数据库表中添加一行,但如果存在具有相同唯一键的行,我想更新该行.
例如,
insert into table (id, name, age) values(1, "A", 19)
Run Code Online (Sandbox Code Playgroud)
假设唯一的密钥是id,在我的数据库中有一行id = 1.在这种情况下,我想用这些值更新该行.通常这会产生错误.如果我使用insert IGNORE它将忽略错误,但它仍然不会更新.
这里一个非常常见的问题是如何进行upsert,这是MySQL调用的INSERT ... ON DUPLICATE UPDATE,标准支持作为MERGE操作的一部分.
鉴于PostgreSQL不直接支持它(在第9.5页之前),你是如何做到这一点的?考虑以下:
CREATE TABLE testtable (
id integer PRIMARY KEY,
somedata text NOT NULL
);
INSERT INTO testtable (id, somedata) VALUES
(1, 'fred'),
(2, 'bob');
Run Code Online (Sandbox Code Playgroud)
现在,假设你想"UPSERT"的元组(2, 'Joe'),(3, 'Alan'),因此新表的内容是:
(1, 'fred'),
(2, 'Joe'), -- Changed value of existing tuple
(3, 'Alan') -- Added new tuple
Run Code Online (Sandbox Code Playgroud)
这是人们在讨论时所谈论的内容upsert.至关重要的是,任何方法在同一个表上存在多个事务时都必须是安全的 - 通过使用显式锁定,或以其他方式抵御由此产生的竞争条件.
关于PostgreSQL中的重复更新,在Insert上广泛讨论了这个主题?,但这是关于MySQL语法的替代品,随着时间的推移,它已经成长为一些无关的细节.我正在研究明确的答案.
这些技术对于"插入如果不存在,否则什么都不做"也很有用,即"插入...复制键忽略".
使用一个MySQL查询时,是否存在一种简单的方法,INSERT当它不存在时,或者UPDATE它是否存在?
我有一个Competitions结果表,一方面保存团队成员的名字和他们的排名.
另一方面,我需要维护一个独特的竞争对手名称表:
CREATE TABLE Competitors (cName nvarchar(64) primary key)
Run Code Online (Sandbox Code Playgroud)
现在我在第一个表中有大约200,000个结果,当竞争对手表空时,我可以执行此操作:
INSERT INTO Competitors SELECT DISTINCT Name FROM CompResults
Run Code Online (Sandbox Code Playgroud)
查询只需要大约5秒钟就可以插入大约11,000个名称.
到目前为止,这不是一个关键应用程序,因此我可以考虑每月截断一次竞争对手表,当我收到大约10,000行的新竞争结果时.
但是,当新的和现有的竞争对手增加新的结果时,最佳做法是什么?我不想截断现有的竞争对手表
我只需要为新的竞争对手执行INSERT语句,如果它们存在则不执行任何操作.
我正在进行插入查询,如果已经存在唯一键,则需要将大多数列更新为新值.它是这样的:
INSERT INTO lee(exp_id, created_by,
location, animal,
starttime, endtime, entct,
inact, inadur, inadist,
smlct, smldur, smldist,
larct, lardur, lardist,
emptyct, emptydur)
SELECT id, uid, t.location, t.animal, t.starttime, t.endtime, t.entct,
t.inact, t.inadur, t.inadist,
t.smlct, t.smldur, t.smldist,
t.larct, t.lardur, t.lardist,
t.emptyct, t.emptydur
FROM tmp t WHERE uid=x
ON DUPLICATE KEY UPDATE ...;
//update all fields to values from SELECT,
// except for exp_id, created_by, location, animal,
// starttime, endtime
Run Code Online (Sandbox Code Playgroud)
我不确定该UPDATE子句的语法应该是什么.我如何引用该SELECT子句中的当前行?
我正在INSERT ... ON DUPLICATE KEY UPDATE为PRIMARY KEY下表中的a 做一个:
DESCRIBE users_interests;
Run Code Online (Sandbox Code Playgroud)
+------------+---------------------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+---------------------------------+------+-----+---------+-------+
| uid | int(11) | NO | PRI | NULL | |
| iid | int(11) | NO | PRI | NULL | |
| preference | enum('like','dislike','ignore') | YES | | NULL | |
+------------+---------------------------------+------+-----+---------+-------+
Run Code Online (Sandbox Code Playgroud)
但是,即使这些值应该是唯一的,我也会看到2行受到影响.
INSERT INTO users_interests (uid, iid, preference) VALUES (2, 2, 'like')
ON DUPLICATE KEY UPDATE …Run Code Online (Sandbox Code Playgroud) 我有一个table1包含三列和一堆行的表:
[key_col|col_a|col_b]
Run Code Online (Sandbox Code Playgroud)
我想用一组值更新col_a(即保持col_b不变),如下所示:
INSERT INTO table1 AS t1 (key_col, col_a) VALUES ("k1", "foo"), ("k2", "bar");
Run Code Online (Sandbox Code Playgroud)
但它不起作用,我该怎么做?
我想ON DUPLICATE KEY UPDATE在Zend Framework 1.5中使用,这可能吗?
例
INSERT INTO sometable (...)
VALUES (...)
ON DUPLICATE KEY UPDATE ...
Run Code Online (Sandbox Code Playgroud) 从我的代码(Java)我想确保在执行代码后数据库(DB2)中存在一行.
我的代码现在执行了一个select,如果没有返回结果,它会执行insert.我真的不喜欢这个代码,因为它在多线程环境中运行时会让我遇到并发问题.
我想要做的是将这个逻辑放在DB2而不是我的Java代码中.DB2有insert-or-update声明吗?或者我可以使用的任何类似的东西?
例如:
insertupdate into mytable values ('myid')
Run Code Online (Sandbox Code Playgroud)
另一种方法可能是始终执行insert并捕获"SQL-code -803主键已存在",但我想尽可能避免这种情况.
我经常发现自己创建了Dictionary一个非平凡的值类(例如List),然后在填充数据时总是编写相同的代码模式.
例如:
var dict = new Dictionary<string, List<string>>();
string key = "foo";
string aValueForKey = "bar";
Run Code Online (Sandbox Code Playgroud)
也就是说,我想插入"bar"与key对应的列表"foo",其中key "foo"可能不会映射到任何内容.
这是我使用不断重复的模式的地方:
List<string> keyValues;
if (!dict.TryGetValue(key, out keyValues))
dict.Add(key, keyValues = new List<string>());
keyValues.Add(aValueForKey);
Run Code Online (Sandbox Code Playgroud)
有更优雅的方式吗?
相关问题没有这个问题的答案:
insert-update ×10
mysql ×6
upsert ×4
sql ×3
.net ×1
c# ×1
database ×1
db2 ×1
dictionary ×1
insert ×1
php ×1
postgresql ×1
sql-merge ×1
sql-server ×1