web-dev-qa-db-ja.com

INSERT INTOを複数回挿入する

'DataSource'というユーザーに関するすべての情報を含むテーブルがあります。 「First Name」、「Surname」、および「Address」という列があります(他にも例があります)。 「アドレス」と「ユーザー」という2つのテーブルがあります。私がしたいことは、DataSourceのユーザーのAddress列を取得し、それをAddressテーブルに追加することです。次に、First Name、Surname、およびAddressID(Addressの挿入時に作成される)を取得して、Userテーブルに追加します。 (基本的に、DataSourceからのデータを2つのテーブルに分割し、Addressテーブルから自動生成されたAddressIDを介して2つのテーブルの間にAddressIDリンクを設定します)。

以下のコードを取得しましたが、期待どおりに動作していません。 Userテーブルはループで満たされているため、すべてのユーザーに行数が挿入されます(たとえば、DataSourceテーブルに2人のユーザーがいる場合、各ユーザーは2回挿入され、毎回すべてのアドレスIDが与えられます)。

DECLARE @ids TABLE (address_id INT);

INSERT INTO dbo.Address(address) 
OUTPUT INSERTED.address_id INTO @ids
SELECT [Address]    
FROM dbo.[DataSource]


SET IDENTITY_INSERT dbo.[Users] OFF      

INSERT INTO dbo.[Users]
        ( 
          first_name,
          surname ,
          address_id            
        )

SELECT  first_name, surname,i.address_id,        
FROM dbo.[DataSource], @ids i

正しいアドレスがユーザーに1回割り当てられるように、基本的にこれを順次行うにはどうすればよいですか?これは時間に敏感な操作ではないため、パフォーマンスは重要ではありませんが、データの整合性は重要です。

ありがとう

4
TryNCode

ここでデカルト積を実行しています:

...
FROM dbo.[DataSource], @ids i

どのaddress_idがどのユーザーに対応するかを知る必要があり、そのためには句が必要です。このような何かがそれを行います:

INSERT INTO dbo.[Users]
        ( 
          first_name,
          surname ,
          address_id            
        )

SELECT  first_name, surname, Address.address_id,        
FROM dbo.[DataSource]
INNER JOIN dbo.Address ON Address.address = DataSource.Address

さらなる検討;これは、同じアドレスを持つ2人のユーザーがいない場合、または同じアドレスを持つ2人のユーザーが同じaddress_idを持つことが望ましい場合に、うまく機能します。

3
JoseTeixeira