programing

SQL Server:동시에 두 개의 테이블에 삽입할 수 있습니까?

padding 2023. 4. 8. 08:00
반응형

SQL Server:동시에 두 개의 테이블에 삽입할 수 있습니까?

내 데이터베이스에는 다음과 같은 세 개의 테이블이 있습니다.Object_Table,Data_Table그리고.Link_Table링크 테이블에는 오브젝트 레코드의 ID와 데이터 레코드의 ID라는2개의 열만 포함됩니다.

데이터를 복사하고 싶다DATA_TABLE특정 오브젝트 ID에 링크되어 대응하는 레코드를 삽입합니다.Data_Table그리고.Link_Table다른 오브젝트 ID를 지정합니다.

테이블 변수를 선택하고 반복할 때마다 2개의 삽입을 반복함으로써 이 작업을 수행할 수 있습니다.

이게 최선의 방법인가요?

편집 : 루프를 피하고 싶은 이유는 두 가지입니다.첫 번째는 게으르고 루프/템프 테이블에는 더 많은 코드가 필요하기 때문입니다.코드가 많을수록 실수할 곳이 많아지고 두 번째 이유는 퍼포먼스에 대한 우려입니다.

모든 데이터를 한 번에 복사할 수 있는데 각 레코드에 새 ID가 있는 새 데이터 레코드에 링크하려면 어떻게 해야 합니까?

한마디로 '아니요'

한 번의 트랜잭션:네.

BEGIN TRANSACTION
   DECLARE @DataID int;
   INSERT INTO DataTable (Column1 ...) VALUES (....);
   SELECT @DataID = scope_identity();
   INSERT INTO LinkTable VALUES (@ObjectID, @DataID);
COMMIT

좋은 소식은 위의 코드도 atomic임을 보증하고 단일 함수 호출에1개의 SQL 스트링을 사용하여 클라이언트애플리케이션에서 서버에 송신할 수 있다는 것입니다.테이블 하나에 트리거를 적용하여 단일 삽입 효과를 얻을 수도 있습니다.그러나 최종적으로는 두 개의 문장이므로 모든 삽입에 대해 트리거를 실행하지는 않을 수 있습니다.

아직 두 개 필요해INSERT진술은 했지만, 당신이 원하는 것은IDENTITY첫 번째 삽입에서 두 번째 삽입으로 사용합니다.이 경우, 당신은 아마 그것을 들여다보는 것이 좋을지도 모릅니다.OUTPUT또는OUTPUT INTO: http://msdn.microsoft.com/en-us/library/ms177564.aspx

다음은 테이블 변수를 사용하여 제가 겪은 상황을 설정해 놓은 것입니다.

DECLARE @Object_Table TABLE
(
    Id INT NOT NULL PRIMARY KEY
)

DECLARE @Link_Table TABLE
(
    ObjectId INT NOT NULL,
    DataId INT NOT NULL
)

DECLARE @Data_Table TABLE
(
    Id INT NOT NULL Identity(1,1),
    Data VARCHAR(50) NOT NULL
)

-- create two objects '1' and '2'
INSERT INTO @Object_Table (Id) VALUES (1)
INSERT INTO @Object_Table (Id) VALUES (2)

-- create some data
INSERT INTO @Data_Table (Data) VALUES ('Data One')
INSERT INTO @Data_Table (Data) VALUES ('Data Two')

-- link all data to first object
INSERT INTO @Link_Table (ObjectId, DataId)
SELECT Objects.Id, Data.Id
FROM @Object_Table AS Objects, @Data_Table AS Data
WHERE Objects.Id = 1

OUTPUT 절로 안내한 다른 답변 덕분에 솔루션을 시연할 수 있습니다.

-- now I want to copy the data from from object 1 to object 2 without looping
INSERT INTO @Data_Table (Data)
OUTPUT 2, INSERTED.Id INTO @Link_Table (ObjectId, DataId)
SELECT Data.Data
FROM @Data_Table AS Data INNER JOIN @Link_Table AS Link ON Data.Id = Link.DataId
                INNER JOIN @Object_Table AS Objects ON Link.ObjectId = Objects.Id 
WHERE Objects.Id = 1

하지만 실생활에서는 다음과 같은 오류 때문에 그렇게 간단하지 않은 것으로 밝혀졌다.

OUTPUT INTO 절은 (기본 키, 외부 키) 관계의 어느 쪽에도 있을 수 없습니다.

나는 여전히 할 수 있다OUTPUT INTO임시 테이블과 일반 인서트로 마무리합니다.루프는 피할 수 있지만 임시 테이블은 피할 수 없습니다.

사용하는 것을 강조하고 싶다.

SET XACT_ABORT ON;

여러 sql 문이 있는 MSQL 트랜잭션의 경우.

참조: https://msdn.microsoft.com/en-us/library/ms188792.aspx 매우 좋은 예를 제시합니다.

따라서 최종 코드는 다음과 같습니다.

SET XACT_ABORT ON;

BEGIN TRANSACTION
   DECLARE @DataID int;
   INSERT INTO DataTable (Column1 ...) VALUES (....);
   SELECT @DataID = scope_identity();
   INSERT INTO LinkTable VALUES (@ObjectID, @DataID);
COMMIT

Link 테이블은 Object 테이블과 Data 테이블 간의 many:many 관계를 캡처하는 것처럼 들립니다.

스토어드 프로시저를 사용하여 거래를 관리하는 것이 좋습니다.[ Object ]테이블 또는 [Data]테이블에 삽입할 경우 새 ID를 가져와 [Link]테이블에 삽입합니다.

이것에 의해, 모든 로직을 1개의 sproc에 캡슐화한 채로 할 수 있습니다.

어느 정도 원폭적인 액션을 원하신다면 반드시 트랜잭션으로 포장해 드리겠습니다.그렇게 하면 두 가지 모두 발생했거나 둘 다 필요에 따라 발생하지 않았음을 확인할 수 있습니다.

삽입문에 필요한 열 이름을 선택하여 보기를 만들고 INSERT 트리거 대신을 추가한 다음 이 보기에 삽입할 수 있습니다.

Oracle에서 다중 삽입을 수행하기 전에 삽입을 수행하기 위해 트리거가 정의된 뷰에 삽입을 포함하는 트릭을 사용할 수 있습니다.SQL Server에서 이 작업을 수행할 수 있습니까?

삽입은 한 번에 하나의 테이블에서만 작동할 수 있습니다.다중 삽입에는 여러 개의 문이 있어야 합니다.

테이블 변수를 통해 루핑할 필요가 있는지 모르겠습니다. 한 테이블에 매스 인서트를 사용하고 다른 테이블에 매스 인서트를 사용하면 안 될까요?

덧붙여서 Object_Table에서 데이터를 복사하는 것을 의미한다고 생각합니다.그렇지 않으면 질문은 의미가 없습니다.

//첫 번째 테이블과 같은 것을 삽입하는 경우

$qry = "INSERT INTO table (one, two, three) VALUES('$one','$two','$three')";

$result = @mysql_query($qry);

$qry2 = "INSERT INTO table2 (one,two, three) VVALUES('$one','$two','$three')";

$result = @mysql_query($qry2);

//또는 테이블1의 특정 부분을 삽입하는 경우

 $qry = "INSERT INTO table (one, two, three) VALUES('$one','$two','$three')";


  $result = @mysql_query($qry);

 $qry2 = "INSERT INTO table2 (two) VALUES('$two')";

 $result = @mysql_query($qry2);

//잘못된 것처럼 보이는 건 알지만, 작동하기 때문에 쿼리를 계속 추가할 수 있습니다.

    "$qry"-number and number in @mysql_query($qry"")

17개의 테이블이 있습니다.

-- ================================================
-- Template generated from Template Explorer using:
-- Create Procedure (New Menu).SQL
--
-- Use the Specify Values for Template Parameters 
-- command (Ctrl-Shift-M) to fill in the parameter 
-- values below.
--
-- This block of comments will not be included in
-- the definition of the procedure.
-- ================================================
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE InsetIntoTwoTable

(
@name nvarchar(50),
@Email nvarchar(50)
)

AS
BEGIN

    SET NOCOUNT ON;


    insert into dbo.info(name) values (@name)
    insert into dbo.login(Email) values (@Email)
END
GO

언급URL : https://stackoverflow.com/questions/175066/sql-server-is-it-possible-to-insert-into-two-tables-at-the-same-time

반응형