假设一个表结构MyTable(KEY, datafield1, datafield2...).
通常我想要更新现有记录,或者如果新记录不存在则插入新记录.
实质上:
IF (key exists)
run update command
ELSE
run insert command
Run Code Online (Sandbox Code Playgroud)
写这个的最佳表现方式是什么?
我想运行一组查询来将一些数据插入到SQL表中,但前提是满足某些条件的记录.该表有4个字段:( idprimary)fund_id,date和price
我在查询3个字段:fund_id,date和price.
所以我的查询会是这样的:
INSERT INTO funds (fund_id, date, price)
VALUES (23, '2013-02-12', 22.43)
WHERE NOT EXISTS (
SELECT *
FROM funds
WHERE fund_id = 23
AND date = '2013-02-12'
);
Run Code Online (Sandbox Code Playgroud)
所以我只想在匹配fund_id和date不存在的记录时插入数据.如果以上是正确的,那么我觉得这是一种非常低效的方法,因为每次都必须运行一个额外的select语句.
有没有更好的方法来实现上述目标?
编辑:澄清既不是fund_id也不date是唯一的字段; 将存在共享相同fund_id或日期的记录,但没有记录应具有与另一个相同的fund_id和日期.
在SQL Server 2005中执行原子"UPSERT"(在哪里存在UPDATE,否则为INSERT)的正确模式是什么?
我在SO上看到了很多代码(例如,请参阅检查是否存在行,否则插入),其中包含以下两部分模式:
UPDATE ...
FROM ...
WHERE <condition>
-- race condition risk here
IF @@ROWCOUNT = 0
INSERT ...
Run Code Online (Sandbox Code Playgroud)
要么
IF (SELECT COUNT(*) FROM ... WHERE <condition>) = 0
-- race condition risk here
INSERT ...
ELSE
UPDATE ...
Run Code Online (Sandbox Code Playgroud)
其中<condition>将是对自然键的评估.上述方法似乎都不能很好地处理并发问题.如果我不能拥有两个具有相同自然键的行,则似乎所有上述风险都会在竞争条件场景中插入具有相同自然键的行.
我一直在使用以下方法,但我很惊讶不要在人们的回复中看到它,所以我想知道它有什么问题:
INSERT INTO <table>
SELECT <natural keys>, <other stuff...>
FROM <table>
WHERE NOT EXISTS
-- race condition risk here?
( SELECT 1 FROM <table> WHERE <natural keys> )
UPDATE ...
WHERE <natural keys>
Run Code Online (Sandbox Code Playgroud)
请注意,此处提到的竞争条件与早期代码中的竞争条件不同.在早期的代码中,问题是幻读(在UPDATE/IF之间或在另一个会话的SELECT/INSERT之间插入行).在上面的代码中,竞争条件与DELETE有关.在(WHERE NOT EXISTS)执行之后但在INSERT执行之前,是否有可能由另一个会话删除匹配的行?目前还不清楚WHERE …
我从多个进程插入一个SQL数据库.过程有时可能会尝试将重复数据插入表中.我试图以一种处理重复的方式编写查询,但我仍然得到:
System.Data.SqlClient.SqlException: Violation of UNIQUE KEY constraint 'UK1_MyTable'. Cannot insert duplicate key in object 'dbo.MyTable'.
The statement has been terminated.
Run Code Online (Sandbox Code Playgroud)
我的查询看起来像:
INSERT INTO MyTable (FieldA, FieldB, FieldC)
SELECT FieldA='AValue', FieldB='BValue', FieldC='CValue'
WHERE (SELECT COUNT(*) FROM MyTable WHERE FieldA='AValue' AND FieldB='BValue' AND FieldC='CValue' ) = 0
Run Code Online (Sandbox Code Playgroud)
约束'UK1_MyConstraint'表示在MyTable中,3个字段的组合应该是唯一的.
我的问题:
请注意,我知道还有其他方法可以解决"INSERT if not exists"的原始问题,例如(摘要):
我应该使用其中一种方法吗?
编辑1个 SQL用于创建表:
CREATE TABLE [dbo].[MyTable](
[Id] [bigint] IDENTITY(1,1) NOT NULL,
[FieldA] [bigint] NOT NULL,
[FieldB] [int] NOT NULL,
[FieldC] [char](3) NULL,
[FieldD] [float] …Run Code Online (Sandbox Code Playgroud) 我使用MERGE声明作为UPSERT添加新记录或更新当前记录.我有多个线程通过多个连接和多个语句驱动数据库(每个线程一个连接和语句).我一次批处理语句50.
我duplicate key在考试期间遇到违规行为,我感到非常惊讶.我希望这是不可能的,因为MERGE它将作为单个交易执行,或者是它?
我的Java代码如下:
private void addBatch(Columns columns) throws SQLException {
try {
// Set parameters.
for (int i = 0; i < columns.size(); i++) {
Column c = columns.get(i);
// Column type is an `enum` with a `set` method appropriate to its type, e.g. setLong, setString etc.
c.getColumnType().set(statement, i + 1, c.getValue());
}
// Add the insert as a batch.
statement.addBatch();
// Ready to execute?
if (++batched >= MaxBatched) {
statement.executeBatch(); …Run Code Online (Sandbox Code Playgroud) 我有这样的查询:
IF EXISTS(SELECT 1 FROM table1 WHERE col1 = ? LIMIT 1) THEN
DELETE FROM table2 WHERE col2 = ?
END IF
Run Code Online (Sandbox Code Playgroud)
但我不知道为什么上面的查询不起作用.这也不起作用:
IF EXISTS(SELECT 1 FROM table1 WHERE col1 = ? LIMIT 1) BEGIN
DELETE FROM table2 WHERE col2 = ?
END
Run Code Online (Sandbox Code Playgroud)
MySQL告诉我有一个语法错误,我该如何解决?
我有我认为是一个完全无关紧要的查询 - 如果不存在具有匹配ID的值,则将值插入表中:
BEGIN
INSERT INTO [dbo].[Contact_Categories](Contact_Category_ID, Description)
VALUES (1, 'Internal')
WHERE NOT EXISTS( SELECT * FROM [dbo].[Contact_Categories] WHERE Contact_Category_ID = 1)
END
Run Code Online (Sandbox Code Playgroud)
我在where语句周围出错了.为什么?我如何实现目标?
我正在使用 FluentMigrator 将一个数据库架构迁移到另一个数据库架构。我有一个案例,我想在添加新数据之前检查某些数据(特别是一行)是否存在。
if (!Schema.Table("MyTable").Something().Exists)
Insert.IntoTable("MyTable").Row(new { Id = 100, Field="Value" });
Run Code Online (Sandbox Code Playgroud)
如何首先检查该行是否存在?
所以,我正在编写一个SQL查询,就像你一样,我偶然发现了一个问题.我想要做的是每次唯一用户访问某个页面时在数据库中触发查询.唯一性是通过session_id()完成的,因为它通常非常可靠.
我想要的是一个SQL查询,它将一行数据插入两列,但只有这两列不具有相同的值.
如果用户x访问了名为的页面page1,那么在数据库中,它将记录如下所示:
+------------+---------+
| page_name | user_id |
+------------+---------+
| page1 | x |
+------------+---------+
Run Code Online (Sandbox Code Playgroud)
我将如何编写一个检查表的查询,以查看插入的数据是否重复?
我当前的查询如下(它只是一个标准的插入查询):
INSERT INTO `page_views` (`page_name`, `user_id`) VALUES ('.$pageName.', \''.session_id().'\')
Run Code Online (Sandbox Code Playgroud) sql ×4
sql-server ×4
mysql ×3
upsert ×3
atomic ×1
database ×1
exists ×1
if-statement ×1
insert ×1
java ×1
php ×1
sql-insert ×1