假设我有一个带有身份字段的表.如果它还不存在,我想在其中插入一条记录.在下面的示例中,我检查存储在@ Field1中的值是否已存在于表中.如果没有,我插入一条新记录:
表的定义:
MyTable (MyTableId int Identity not null, Field1 int not null, Field2 int not null)
Run Code Online (Sandbox Code Playgroud)
这是我检查值是否已存在的方法,并在必要时插入
merge MyTable as t
using (@Field1, @Field2) as s (Field1,Field2)
on (t.Field1=s.Field1)
when not matched then
insert (Field1,Field2) values (s.Field1,s.Field2);
Run Code Online (Sandbox Code Playgroud)
在表中尚不存在记录时获取标识值可以通过添加:
output Inserted.MyTableId
Run Code Online (Sandbox Code Playgroud)
但如果记录已经在表中(即如果有匹配)怎么办?
我找到的唯一方法是在执行Merge语句后查询表:
select MyTableId from MyTable where Field1=@Field1
Run Code Online (Sandbox Code Playgroud)
有没有办法直接从Merge获取标识值?
Ada*_*Dev 28
在记录已存在的情况下,您可以将匹配的id存储到变量中,如下所示:
DECLARE @MatchedId INTEGER;
MERGE MyTable as t
....
....
WHEN MATCHED THEN
UPDATE SET @MatchedId = t.MyTableId;
Run Code Online (Sandbox Code Playgroud)
更新:
这是一个完整的例子.这证明了一种方式:
DECLARE @UpdateVariable bit
DECLARE @ChangeResult TABLE (ChangeType VARCHAR(10), Id INTEGER)
DECLARE @Data TABLE (Id integer IDENTITY(1,1), Val VARCHAR(10))
INSERT @Data ([Val]) VALUES ('A');
MERGE @data AS TARGET
USING (SELECT 'A' AS Val UNION ALL SELECT 'B' AS Val) AS SOURCE ON TARGET.Val = SOURCE.Val
WHEN NOT MATCHED THEN
INSERT ([Val])
VALUES (SOURCE.Val)
WHEN MATCHED THEN
UPDATE SET @UpdateVariable = 1
OUTPUT $action, inserted.Id INTO @ChangeResult;
SELECT * FROM @data
SELECT * FROM @ChangeResult
Run Code Online (Sandbox Code Playgroud)
要点是:
Dan*_*ner 24
这是一种替代的,稍微简单的方法(在我看来):
DECLARE @Id [int];
MERGE INTO [MyTable] AS [t]
USING (VALUES
(@FieldA, @FieldB)
)
AS [x] (FieldA, FieldB)
ON [t].[FieldA] = [x].[FieldA]
AND [t].[FieldB] = [x].[FieldB]
WHEN NOT MATCHED BY TARGET THEN
INSERT (FieldA, FieldB)
VALUES (FieldA, FieldB)
WHEN MATCHED THEN
UPDATE SET @Id = [t].[Id]
IF @Id IS NULL
BEGIN
SET @Id = CAST(SCOPE_IDENTITY() as [int]);
END
SELECT @Id;
Run Code Online (Sandbox Code Playgroud)
如果merge语句导致匹配,@Id则将设置为匹配行的标识.如果不匹配,将插入新行,并准备好从中选择新标识SCOPE_IDENTITY().
这里有其他选择:
DECLARE @FakeVar BIT
MERGE MyTable AS T
USING VALUES((@Field1, @Field2)) AS S (Field1, Field2)
ON (T.Field1 = S.Field1)
WHEN NOT MATCHED THEN
INSERT (Field1, Field2)
VALUES (S.Field1, T.Field2)
WHEN MATCHED THEN
UPDATE SET @FakeVar = NULL -- do nothing, only force "an update" to ensure output on updates
OUTPUT INSERTED.MyTableId ;
Run Code Online (Sandbox Code Playgroud)
如果您查看 OUTPUT 文档
INSERTED 是列前缀,指定插入或更新操作添加的值。
你只需要在更新集子句上做“某事”