bestsource

SQL Server에서 데이터를 두 테이블에 동시에 삽입하려면 어떻게 해야 합니까?

bestsource 2023. 8. 22. 22:16
반응형

SQL Server에서 데이터를 두 테이블에 동시에 삽입하려면 어떻게 해야 합니까?

테이블 구조가 다음과 같이 생겼다고 가정해 보겠습니다.

CREATE TABLE [dbo].[table1] (
    [id] [int] IDENTITY(1,1) NOT NULL,
    [data] [varchar](255) NOT NULL,
    CONSTRAINT [PK_table1] PRIMARY KEY CLUSTERED ([id] ASC)
)

CREATE TABLE [dbo].[table2] (
    [id] [int] IDENTITY(1,1) NOT NULL,
    [table1_id] [int] NOT NULL,
    [data] [varchar](255) NOT NULL,
    CONSTRAINT [PK_table2] PRIMARY KEY CLUSTERED ([id] ASC)
)

[id]첫 번째 테이블의 필드는 다음에 해당합니다.[table1_id]제2의 필드제가 하고 싶은 것은 한 번의 거래로 두 테이블에 데이터를 삽입하는 것입니다.다음과 같이 INSERT-SELECT-INSERT를 수행하여 이 작업을 수행하는 방법을 이미 알고 있습니다.

BEGIN TRANSACTION;
DECLARE @id [int];
INSERT INTO [table1] ([data]) VALUES ('row 1');
SELECT @id = SCOPE_IDENTITY();
INSERT INTO [table2] ([table1_id], [data]) VALUES (@id, 'more of row 1');
COMMIT TRANSACTION;

행을 몇 개만 삽입하는 그런 작은 경우에도 좋습니다.하지만 제가 해야 할 일은 수십만 줄, 어쩌면 백만 줄을 한꺼번에 집어넣는 것입니다.데이터는 다른 테이블에서 가져온 것이므로 단일 테이블에 데이터를 삽입하는 것이 쉬울 것입니다. 이 작업을 수행해야 합니다.

INSERT INTO [table] ([data])
SELECT [data] FROM [external_table];

하지만 이를 어떻게 수행하고 데이터를 두 개의 데이터로 나누겠습니까?[table1]그리고.[table2]여전히 업데이트 중입니다.[table2]적절한[table1_id]내가 하고 있는 동안?그게 가능하긴 해?

사용해 보십시오.

insert into [table] ([data])
output inserted.id, inserted.data into table2
select [data] from [external_table]

업데이트: Re:

Denis - 이것은 제가 하고 싶은 것과 매우 가까운 것처럼 보이지만, 아마도 당신이 저를 위해 다음 SQL 문을 고쳐주실 수 있을까요?기본적으로 [table1]의 [data]와 [table2]의 [data]는 [external_table]과 다른 두 개의 열을 나타냅니다.위에 게시한 문은 [data] 열이 동일하기를 원하는 경우에만 작동합니다.

INSERT INTO [table1] ([data]) 
OUTPUT [inserted].[id], [external_table].[col2] 
INTO [table2] SELECT [col1] 
FROM [external_table] 

외부 열을 출력할 수 없습니다.insert진술, 그래서 나는 당신이 이런 것을 할 수 있다고 생각합니다.

merge into [table1] as t
using [external_table] as s
on 1=0 --modify this predicate as necessary
when not matched then insert (data)
values (s.[col1])
output inserted.id, s.[col2] into [table2]
;

저도 이 문제로 어려움을 겪었고, 가장 좋은 방법은 커서를 사용하는 것이라는 것을 알게 되었습니다.

OUTPUT으로 Denis 솔루션을 시도해 보았지만, 그가 언급한 것처럼 insert 문으로 외부 열을 출력하는 것은 불가능하며, select로 여러 행을 삽입하면 MERGE가 작동하지 않습니다.

외부 테이블의 각 행에 대해 커서를 사용하여 INSERT를 수행한 다음 다른 INSERT에 @IDENTITY를 사용합니다.

DECLARE @OuterID int

DECLARE MY_CURSOR CURSOR 
  LOCAL STATIC READ_ONLY FORWARD_ONLY
FOR 
SELECT  ID FROM   [external_Table]

OPEN MY_CURSOR
FETCH NEXT FROM MY_CURSOR INTO @OuterID

WHILE @@FETCH_STATUS = 0
BEGIN 
INSERT INTO [Table]   (data)
    SELECT data
    FROM     [external_Table] where ID = @OuterID 

    INSERT INTO [second_table] (FK,OuterID)
    VALUES(@OuterID,@@identity)

    FETCH NEXT FROM MY_CURSOR INTO @OuterID
END
CLOSE MY_CURSOR
DEALLOCATE MY_CURSOR

SQL Server가 'INSERT ALL' 문을 지원하도록 주의하십시오.Oracle은 이미 다음과 같은 기능을 갖추고 있습니다(SQL Cookbook).

insert all
  when loc in ('NEW YORK', 'BOSTON') THEN
   into dept_east(deptno, dname, loc) values(deptno, dname, loc)
  when loc in ('CHICAGO') THEN
   into dept_mid(deptno, dname, loc) values(deptno, dname, loc)
  else
   into dept_west(deptno, dname, loc) values(deptno, dname, loc)
select deptno, dname, loc
  from dept
BEGIN TRANSACTION;

DECLARE @tblMapping table(sourceid int, destid int)

INSERT INTO [table1] ([data]) 
OUTPUT source.id, new.id
Select [data] from [external_table] source;

INSERT INTO [table2] ([table1_id], [data])
Select map.destid, source.[more data] 
from [external_table] source
    inner join @tblMapping map on source.id=map.sourceid;

COMMIT TRANSACTION;
Create table #temp1
(
 id int identity(1,1),
 name varchar(50),
 profession varchar(50)
)

Create table #temp2
(
 id int identity(1,1),
 name varchar(50),
 profession varchar(50)
)

----- 기본 쿼리 -------

insert into #temp1(name,profession)

output inserted.name,inserted.profession into #temp2

select 'Shekhar','IT'

제안한 트랜잭션을 반복하는 저장 프로시저를 작성할 수 있습니다.반복기는 원본 데이터가 들어 있는 테이블의 커서가 됩니다.

또 다른 옵션은 두 개의 삽입물을 개별적으로 실행하여 FK 열을 null로 유지한 다음 업데이트를 실행하여 올바르게 풀링하는 것입니다.

한 레코드에서 다른 레코드로 일치하는 두 테이블 내에 자연스럽게 저장된 것이 없는 경우 임시 GUID 열을 만들고 데이터에 이 열을 채우고 두 필드에 모두 삽입합니다.그런 다음 적절한 FK로 업데이트하고 GUID를 제거할 수 있습니다.

예:

CREATE TABLE [dbo].[table1] ( 
    [id] [int] IDENTITY(1,1) NOT NULL, 
    [data] [varchar](255) NOT NULL, 
    CONSTRAINT [PK_table1] PRIMARY KEY CLUSTERED ([id] ASC),
    JoinGuid UniqueIdentifier NULL
) 

CREATE TABLE [dbo].[table2] ( 
    [id] [int] IDENTITY(1,1) NOT NULL, 
    [table1_id] [int] NULL, 
    [data] [varchar](255) NOT NULL, 
    CONSTRAINT [PK_table2] PRIMARY KEY CLUSTERED ([id] ASC),
    JoinGuid UniqueIdentifier NULL
) 


INSERT INTO Table1....

INSERT INTO Table2....

UPDATE b
SET table1_id = a.id
FROM Table1 a
JOIN Table2 b on a.JoinGuid = b.JoinGuid
WHERE b.table1_id IS NULL

UPDATE Table1 SET JoinGuid = NULL
UPDATE Table2 SET JoinGuid = NULL

언급URL : https://stackoverflow.com/questions/3712678/how-can-i-insert-data-into-two-tables-simultaneously-in-sql-server

반응형