浏览有关如何创建“好”UPSERT语句shown here的各种示例,我创建了以下代码(我更改了列名称):
BEGIN TRANSACTION
IF EXISTS (SELECT *
FROM Table1 WITH (UPDLOCK, SERIALIZABLE), Table2
WHERE Table1.Data3 = Table2.data3)
BEGIN
UPDATE Table1
SET Table1.someColumn = Table2.someColumn,
Table1.DateData2 = GETDATE()
FROM Table1
INNER JOIN Table2 ON Table1.Data3 = Table2.data3
END
ELSE
BEGIN
INSERT INTO Table1 (DataComment, Data1, Data2, Data3, Data4, DateData1, DateData2)
SELECT
'some comment', data1, data2, data3, data4, GETDATE(), GETDATE()
FROM
Table2
END
COMMIT TRANSACTION
我的问题是,它永远不会发生INSERT
部分。 INSERT
单独工作正常。当前脚本仅执行更新部分。
我知道插入只是好的,如果它可以插入它找到的整个数据(因为选择查询)?否则它将无法工作。如果是这样,我该如何改进呢?
我还阅读了MERGE
条款,并希望避免使用它。
//编辑:
在尝试了几个在互联网上找到的样本并在这里解释之后,我重新做了如下逻辑:
BEGIN TRANSACTION
BEGIN
UPDATE table1
SET something
WHERE condition is met
UPDATE table2
SET helpColumn = 'DONE'
WHERE condition is met
END
BEGIN
INSERT INTO table1(data)
SELECT data
FROM table2
WHERE helpColumn != 'DONE'
END
COMMIT TRANSACTION
尝试其他解决方案时,INSERT
通常会失败或运行很长时间(在几张桌子上,我可以接受,但不好,如果您计划将整个数据从一个数据库迁移到另一个数据库)。
我认为这可能不是最好的解决方案。但是现在它有效,有什么意见吗?
答案 0 :(得分:0)
而不是
if (something )
update query
else
insert query
像这样构建你的逻辑:
update yourTable
etc
where some condition is met
insert into yourTable
etc
select etc
where some condition is met.
答案 1 :(得分:0)
一般情况下,你不能像往常那样检查这个。如果表1中存在,则必须检查表2中的每个ID。如果存在,则更新表1,否则插入表1.这可以通过以下方式完成。
我们将使用SQL中的CURSORS
在表2中针对每个ID进行迭代DECLARE @ID int
DECLARE mycursor CURSOR
FOR
SELECT ID FROM Table2 FORWARD_ONLY --Any Unique Column
OPEN mycursor
FETCH NEXT FROM mycursor
INTO @ID
WHILE @@FETCH_STATUS = 0
BEGIN
IF EXISTS (SELECT 1 FROM Table1 WHERE ID = @ID)
UPDATE t1 SET t1.data= T2.data --And whatever else you want to update
FROM
Table1 t1
INNER JOIN
Table2 t2
ON t1.ID = t2.ID --Joining column
WHERE t1.id = @ID
ELSE
INSERT INTO Table1
SELECT * FROM Table2 WHERE ID = @ID
FETCH NEXT FROM mycursor
INTO @ID
END
CLOSE mycursor
DEALLOCATE mycursor