1

テーブルLanguageTextに対応するレコードが必要なテーブルItemsがあります。LanguageTextのID(Identity)は、ItemsテーブルのItems.LanguageTextIdフィールドに登録されています。

私が達成したいのは、Items.LanguageTextIdにnullが含まれるすべてのレコードのLanguageTextとItemsをマージし、これらのItemレコードのitemname / textをLanguageTextに挿入し、LanguageTextIdを新しく挿入されたLanguageTextレコードのID値で更新することです(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 $ action、INSERTED.IDで何かを行うことはできますか?それとも、これを行うためのより良い方法はありますか?

前もって感謝します、

マイク

4

3 に答える 3

7

これは、テーブル変数へのmerge..outputとそれに続く更新で行うことができます。

SQL フィドル

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;

結果

クエリ 2 :

select * from Items;

結果

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

クエリ 3 :

select * from ItemsLanguageText;

結果

| ITEMSLANGUAGETEXTID |   TEXT |
--------------------------------
|                  13 | Name 1 |
|                  14 | Name 2 |
|                  15 | Name 3 |
于 2012-11-07T18:14:34.083 に答える
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

于 2012-11-07T11:57:06.030 に答える
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;
于 2012-11-07T13:49:24.887 に答える