Sql server 使用具有相同源的SQL Server合并命令(&);目标表
我试图使用MERGE命令插入或更新一个表,但是我总是得到一个“0行受影响”。我的目标很简单:如果存在更新,否则插入。我做错了什么 注意:表的主键是组合键=[date]+sip+dip+端口 其中date是datetime,所有其他字段都是intSql server 使用具有相同源的SQL Server合并命令(&);目标表,sql-server,merge,Sql Server,Merge,我试图使用MERGE命令插入或更新一个表,但是我总是得到一个“0行受影响”。我的目标很简单:如果存在更新,否则插入。我做错了什么 注意:表的主键是组合键=[date]+sip+dip+端口 其中date是datetime,所有其他字段都是int merge iplog as t using (SELECT * from iplog Where [date]='20120101' and sip=1 and dip=2 and port=80) as s on t.[date]=s.[date]
merge iplog as t
using (SELECT * from iplog Where [date]='20120101' and sip=1 and dip=2 and port=80) as s
on t.[date]=s.[date] and t.sip=s.sip and t.dip=s.dip and t.port=s.port
when matched then
update set t.size=t.size+s.size
when not matched then
insert values ('20120101',1,2,80,1);
如果当前没有一个与
date
、sip
、dip
和port
匹配的值,我认为您希望插入一个新值,但不清楚在UPDATE
条件下您想要的大小。我选择了1:
create table iplog (
[date] date not null,
sip int not null,
dip int not null,
port int not null,
size int not null
)
GO
merge iplog as t
using (SELECT '20120101' as [date] , 1 as sip , 2 as dip , 80 as port) as s
on t.[date]=s.[date] and t.sip=s.sip and t.dip=s.dip and t.port=s.port
when matched then
update set t.size=t.size+1 --What should this be?
when not matched then
insert values ('20120101',1,2,80,1);
select * from iplog
您将注意到,源现在根本不引用目标表
旁注-我建议避免使用诸如
date
之类的SQL关键字作为列名。我猜您的逻辑是错误的
你的逻辑是:
if source is empty* then insert my row
*源在以下情况下为空:
SELECT '20120101' as [date] , 1 as sip , 2 as dip , 80 as port
返回0行
事实上,您正在尝试将目标与空源合并。这是逻辑错误
你应该写这样的东西
IF EXISTS(SELECT * from iplog Where [date]='20120101' and sip=1 and dip=2 and port=80)
BEGIN
UPDATE
iplog
SET
t.size=t.size+1
WHERE
[date]='20120101' and sip=1 and dip=2 and port=80
END
ELSE
BEGIN
INSERT INTO iplog VALUES ('20120101',1,2,80,1)
END
更新:
想象一下合并是如何工作的:
源为空,目标为空
MERGE
在不匹配时可以有两种子句
首先,
[ WHEN NOT MATCHED [ BY TARGET ] [ AND <clause_search_condition> ]
THEN <merge_not_matched> ]
第二,
[ WHEN NOT MATCHED BY SOURCE [ AND <clause_search_condition> ]
THEN <merge_matched> ] [ ...n ]
[当源不匹配时[和]
然后][…n]
这意味着对于目标中的每一行,如果源代码中没有一对,则可以在目标上执行更新或删除操作。不可能做插入
<merge_matched>::=
{ UPDATE SET <set_clause> | DELETE }
::=
{更新集|删除}
要使MERGE
适合您,您不需要使用empy源代码。您的源代码是带有WHERE
子句的SELECT
,因此它可能成为空源代码。因此,您应该使用某种编码逻辑使其非空,使用一些临时表或表变量或复杂的联接或并集。。但这样一来,您的代码可能会变得不可读。在这种情况下,最好放弃MERGE
的想法,然后执行经典的条件UPDATE
或INSERT
当您的目标是“不匹配时”,目标表如何成为源表?这到底意味着什么?我计划在一个过程中使用它,比如:InsertOrUpdate(DateTime.Date,sourceIP,DestIP,Port,PacketSize)。因此,如果respetive记录存在,它将增加数据包大小,否则将插入一个带有值的新记录。这是可能的吗?当然可以用MERGE实现,但首先不需要空的源代码,如表格变量、临时表、公共表表达式,但要填充源代码表,还需要某种条件逻辑。合并非常有用,但它不适合任何地方。
<merge_not_matched>::=
{
INSERT [ ( column_list ) ]
{ VALUES ( values_list )
| DEFAULT VALUES }
}