使用merge语句插入目标后,使用Identity更新Source表中的字段

时间:2012-11-07 10:38:55

标签: sql sql-server sql-server-2008

我有一个表项,它应该在表LanguageText中有相应的记录。 LanguageText的ID(标识)在我的Items表的Items.LanguageTextId字段中注册。

我想要完成的是在Items.LanguageTextId中将所有记录的所有记录的LanguageText和Items合并,并在LanguageText中插入这些Item记录的itemname / text,并使用新插入的LanguageText记录中的ID值更新LanguageTextId (SCOPE_IDENTITY()?)

插入工作正常:

MERGE [dbo].[LanguageText] AS target
USING (SELECT [Items].* from [dbo].Items ) AS source 
ON (TARGET.Id = SOURCE.LanguageTextId) 
WHEN NOT MATCHED By Target THEN 
    INSERT   
       ([Text])
 VALUES
       (source.[ItemName]);

但我不知道如何更新我的物品.Languagetextid,我能做些什么: OUTPUT $动作,INSERTED.ID? 或者有更好的方法来完成这个吗?

提前致谢,

麦克

3 个答案:

答案 0 :(得分:7)

您可以使用merge..output到表变量然后进行更新来执行此操作。

SQL Fiddle

MS SQL Server 2008架构设置

create table Items
(
  ItemsId int identity primary key,
  ItemName nvarchar(50) not null,
  ItemsLanguageTextId int null
);

create table ItemsLanguageText
(
  ItemsLanguageTextId int identity primary key,
  Text nvarchar(50) not null
);

insert into Items values('Name 1', null);
insert into Items values('Name 2', null);
insert into Items values('Name 3', null);

查询1

declare @T table
(
  ItemsId int,
  ItemsLanguageTextId int
);

merge ItemsLanguageText as T
using (
        select ItemsId, ItemName
        from Items
        where ItemsLanguageTextId is null
      ) as S
on 0 = 1
when not matched then
  insert (Text) values (S.ItemName)
output S.ItemsId, inserted.ItemsLanguageTextId
  into @T;

update Items
set ItemsLanguageTextId = T.ItemsLanguageTextId
from @T as T
where T.ItemsId = Items.ItemsId;

<强> Results

查询2

select * from Items;

<强> Results

| ITEMSID | ITEMNAME | ITEMSLANGUAGETEXTID |
--------------------------------------------
|       1 |   Name 1 |                  13 |
|       2 |   Name 2 |                  14 |
|       3 |   Name 3 |                  15 |

查询3

select * from ItemsLanguageText;

<强> Results

| ITEMSLANGUAGETEXTID |   TEXT |
--------------------------------
|                  13 | Name 1 |
|                  14 | Name 2 |
|                  15 | Name 3 |

答案 1 :(得分:2)

我认为您正在寻找的是添加WHEN MATCHED。

例如

WHEN MATCHED THEN UPDATE SET.... etc etc
WHEN NOT MATCHED THEN INSERT ... etc etc

您可以查看此MERGE交易文档,了解有关如何正确使用MERGE的详细信息。 http://technet.microsoft.com/en-us/library/bb510625.aspx

答案 2 :(得分:0)

当谈到SQL时,我仍然是一个菜鸟...我想它无法通过合并完成,所以我尝试使用带有游标的存储过程循环记录并执行我想要的操作它要做:

CREATE PROCEDURE [dbo].[PM_CreateItemsLanguageTexts]
AS
DECLARE @ITEMNAME NVARCHAR(50);
DECLARE @ITEMID BIGINT;

BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;

--Declare Cursor so we can iterate each record
Declare c Cursor For Select Id, ItemName From dbo.Items WHERE NameId is null 
Open c 
--Fetch First
Fetch next From c into @ITEMID, @ITEMNAME

--As long as we are 'on a roll' go with the flow..
While @@Fetch_Status=0 
Begin

   PRINT @ITEMNAME;
   PRINT @ITEMID;

   --FIRST INSERT A NEW TEXT RECORD IN ItemsLauguageText
   INSERT dbo.ItemsLauguageText(Text) VALUES (@ITEMNAME);    

   --UPDATE THE ITEMS RECORD NAMEID FIELD WITH THE LATEST IDENTITY / ID VALUE
    UPDATE dbo.Items SET NameID = CAST(SCOPE_IDENTITY() AS bigint)  WHERE dbo.Items.Id = @ITEMID; 

Fetch next From c into @ITEMID,@ITEMNAME
End
End

CLOSE C;
DEALLOCATE C;