복붙노트

[SQL] SQL 서버 : 그것은 동시에 두 테이블에 삽입 할 수 있습니까?

SQL

SQL 서버 : 그것은 동시에 두 테이블에 삽입 할 수 있습니까?

내 데이터베이스 Object_Table, Data_Table 및 Link_Table라는 세 개의 테이블이 포함되어 있습니다. 링크 테이블은 두 개의 열, 개체 레코드의 정체성과 데이터 레코드의 정체성이 포함되어 있습니다.

나는 그것이 하나 개의 지정된 객체의 정체성과 다른 지정된 객체 ID에 대해 Data_Table 및 Link_Table에 기록을 해당 삽입 연결되어 DATA_TABLE에서 데이터를 복사 할.

나는 테이블 변수로 선택하고 각 반복 두 삽입하고 통해 반복하여이 작업을 수행 할 수 있습니다.

이 할 수있는 최선의 방법인가?

편집 : 내가 처음 내가 게으른 및 루프 / 임시 테이블이 더 많은 코드, 더 많은 코드 수단 실수와 두 번째 이유는 성능에 대한 우려입니다 수 있도록 더 많은 장소를 필요로한다는 것이다, 두 가지 이유로 루프를 피하려고.

나는 하나 개의 삽입에있는 모든 데이터를 복사 할 수 있습니다하지만 어떻게 각 레코드는 새로운 ID를 가진 새로운 데이터 레코드에 링크로 연결되는 링크 테이블을받을 수 있나요?

해결법

  1. ==============================

    1.하나 개의 문장에서 : 번호

    하나 개의 문장에서 : 번호

    하나의 트랜잭션에서 : 예

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

    좋은 소식은 위의 코드는 또한 원자 보장되고, 그것이 하나 개의 문장 인 것처럼 하나의 함수 호출에 하나의 SQL 문자열로 클라이언트 응용 프로그램에서 서버로 전송 될 수 있다는 것이다. 또한 단일 삽입의 효과를 얻기 위해 한 테이블에 트리거를 적용 할 수 있습니다. 그러나, 그것은 궁극적으로 여전히 두 문장 그리고 당신은 아마 모든 삽입에 대한 트리거를 실행하지 않습니다.

  2. ==============================

    2.당신은 여전히 ​​두 개의 INSERT 문이 필요하지만, 첫 번째 삽입에서 IDENTITY를 얻고 초에서 그것을 사용할처럼, 소리하는 경우에, 당신은 OUTPUT 또는 OUTPUT INTO를 조사 할 수 있습니다 : http://msdn.microsoft .COM / EN-US / 라이브러리 / ms177564.aspx

    당신은 여전히 ​​두 개의 INSERT 문이 필요하지만, 첫 번째 삽입에서 IDENTITY를 얻고 초에서 그것을 사용할처럼, 소리하는 경우에, 당신은 OUTPUT 또는 OUTPUT INTO를 조사 할 수 있습니다 : http://msdn.microsoft .COM / EN-US / 라이브러리 / ms177564.aspx

  3. ==============================

    3.상황까지 다음 세트는 내가 테이블 변수를 사용했다.

    상황까지 다음 세트는 내가 테이블 변수를 사용했다.

    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 및 정상 삽입으로 완료 할 수 있습니다. 그래서 난 내 루프를 피할 수 있지만 임시 테이블을 피할 수 없습니다.

  4. ==============================

    4.개체 테이블 및 데이터 테이블 사이의 많은 관계 : 링크 테이블이 많은 캡처 것 같은데.

    개체 테이블 및 데이터 테이블 사이의 많은 관계 : 링크 테이블이 많은 캡처 것 같은데.

    나의 제안은 트랜잭션을 관리하기 위해 저장 프로 시저를 사용하는 것입니다. 당신이 당신의 삽입을 수행하는 객체 또는 데이터 테이블에 삽입하는 새로운 ID를 얻고 링크 테이블을 삽입 할 때.

    이것은 당신의 논리를 모두 하나의 전화를 쉽게 sproc에 캡슐화 유지 할 수 있습니다.

  5. ==============================

    5.당신이 행동이 더 많거나 적은 원자 싶은 경우에, 나는 트랜잭션을 포장해야합니다 것입니다. 당신이 할 수있는 방법이 있는지 모두 일어 또는 필요에 따라 둘은 발생하지 않았다.

    당신이 행동이 더 많거나 적은 원자 싶은 경우에, 나는 트랜잭션을 포장해야합니다 것입니다. 당신이 할 수있는 방법이 있는지 모두 일어 또는 필요에 따라 둘은 발생하지 않았다.

  6. ==============================

    6.당신은 당신의 INSERT 문에 필요한 열 이름을 선택하는보기를 만들 수 있습니다,이 뷰 내로 INSTEAD OF INSERT 트리거 및 삽입을 추가합니다.

    당신은 당신의 INSERT 문에 필요한 열 이름을 선택하는보기를 만들 수 있습니다,이 뷰 내로 INSTEAD OF INSERT 트리거 및 삽입을 추가합니다.

  7. ==============================

    7.사용에 내가 스트레스를 원하는

    사용에 내가 스트레스를 원하는

    SET XACT_ABORT ON;
    

    여러 SQL 문을 가진 MSSQL 거래에 대한.

    참조 : 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
    
  8. ==============================

    8.삽입 한 번에 하나 개의 테이블에서 작동 할 수 있습니다. 다중 삽입 여러 개의 문을 가지고 있습니다.

    삽입 한 번에 하나 개의 테이블에서 작동 할 수 있습니다. 다중 삽입 여러 개의 문을 가지고 있습니다.

    난 당신이 테이블 변수를 통해 반복 할 필요가 있음을 알 수없는 - 당신은 단지 다른에 하나 개의 테이블, 다음 대량 삽입에 대량 삽입을 사용할 수 없습니다?

    그런데 - 당신이 Object_Table에서 데이터를 복사 의미 추측하고있다; 그렇지 않으면 문제는 이해가되지 않습니다.

  9. ==============================

    9.오라클의 다중 테이블 삽입을 할 수있는 전에, 당신은 INSTEAD OF 트리거가 삽입을 수행하는 데에 정의했다 뷰에 삽입을 포함하는 트릭을 사용할 수 있습니다. 이 SQL 서버에서 수행 할 수 있습니까?

    오라클의 다중 테이블 삽입을 할 수있는 전에, 당신은 INSTEAD OF 트리거가 삽입을 수행하는 데에 정의했다 뷰에 삽입을 포함하는 트릭을 사용할 수 있습니다. 이 SQL 서버에서 수행 할 수 있습니까?

  10. ==============================

    10.

    -- ================================================
    -- 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
    
  11. ==============================

    11.// 먼저 테이블과 동일한를 삽입 할 경우

    // 먼저 테이블과 동일한를 삽입 할 경우

    $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);
    

    // 또는 당신은 테이블 하나의 특정 부분을 삽입 할 경우

     $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 개) 테이블이있다.

  12. from https://stackoverflow.com/questions/175066/sql-server-is-it-possible-to-insert-into-two-tables-at-the-same-time by cc-by-sa and MIT license