문제

내 데이터베이스에는 호출 된 3 개의 테이블이 포함되어 있습니다 Object_Table, Data_Table 그리고 Link_Table. 링크 테이블에는 객체 레코드의 ID와 데이터 레코드의 ID 인 두 개의 열만 포함됩니다.

데이터를 복사하고 싶습니다 DATA_TABLE 주어진 객체 아이덴티티에 연결된 경우, 해당 레코드를 Data_Table 그리고 Link_Table 다른 주어진 객체 아이덴티티의 경우.

~할 수 있다 테이블 변수로 선택하고 각 반복에 대해 두 개의 삽입물을 수행하여 루핑을 선택하여이를 수행하십시오.

이것이 가장 좋은 방법입니까?

편집하다 : 두 가지 이유로 루프를 피하고 싶습니다. 첫 번째는 게으르고 루프/온도 테이블에 더 많은 코드가 필요하고 더 많은 코드는 실수를 할 수있는 더 많은 장소를 의미하며 두 번째 이유는 성능에 대한 우려입니다.

모든 데이터를 하나의 삽입물로 복사 할 수 있지만 각 레코드가 새 ID가있는 새 데이터 레코드에 링크 테이블을 가져 오는 방법은 무엇입니까?

도움이 되었습니까?

해결책 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

다른 덕분에 대답 출력 조항을 향해 지적했는데 솔루션을 시연 할 수 있습니다.

-- 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

그러나 다음 오류로 인해 실생활이 그렇게 간단하지 않다는 것이 밝혀졌습니다.

절에 대한 출력은 (1 차 키, 외국 키) 관계의 양쪽에있을 수 없습니다.

나는 여전히 할 수있다 OUTPUT INTO 임시 테이블을 다음 정상 삽입으로 마무리하십시오. 그래서 내 고리를 피할 수는 있지만 온도 테이블을 피할 수는 없습니다.

다른 팁

하나의 성명: 아니.

하나의 거래: 예

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

좋은 소식은 위의 코드도 원자, 단일 함수 호출에서 하나의 명령문 인 것처럼 하나의 SQL 문자열이있는 클라이언트 응용 프로그램에서 서버로 보낼 수 있습니다. 단일 삽입물의 효과를 얻으려면 하나의 테이블에 트리거를 적용 할 수도 있습니다. 그러나 궁극적으로 여전히 두 가지 진술이며 아마도 트리거를 실행하고 싶지 않을 것입니다. 모든 끼워 넣다.

여전히 두 개가 필요합니다 INSERT 진술이지만 당신이 얻고 싶은 것 같습니다. IDENTITY 첫 번째 삽입물에서 두 번째 삽입물에서 사용하십시오.이 경우 조사를 원할 수도 있습니다. OUTPUT 또는 OUTPUT INTO: http://msdn.microsoft.com/en-us/library/ms177564.aspx

링크 테이블이 객체 테이블과 데이터 테이블 사이의 많은 관계를 캡처하는 것처럼 들립니다.

내 제안은 저장된 절차를 사용하여 거래를 관리하는 것입니다. 객체 또는 데이터 테이블에 삽입하려면 인서트를 수행하려면 새 ID를 가져 와서 링크 테이블에 삽입하십시오.

이를 통해 모든 논리가 SPROC 호출하기 쉬운 하나의 캡슐화 상태를 유지할 수 있습니다.

당신이 행동이 다소 원자력이되기를 원한다면, 나는 거래에 그것을 마무리해야합니다. 그렇게하면 둘 다 발생하거나 필요에 따라 두 가지가 발생하지 않았을 것입니다.

삽입 문에 필요한 열 이름을 선택하는 뷰를 만들고 삽입 트리거 대신 A를 추가 하고이 뷰에 삽입하십시오.

사용에 강조하고 싶습니다

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

삽입은 한 번에 한 테이블에서만 작동 할 수 있습니다. 여러 인서트에는 여러 문장이 있어야합니다.

테이블 변수를 통해 루핑을 수행해야한다는 것을 모르겠습니다. 한 테이블에 질량 삽입물을 사용할 수는없고 질량 삽입물을 다른 테이블에 사용할 수 없습니까?

그건 그렇고 - 나는 당신이 Object_table에서 데이터를 복사한다는 것을 의미한다고 생각합니다. 그렇지 않으면 질문이 의미가 없습니다.

Oracle에서 멀티 레이트 인서트를 수행하기 전에 인서트를 수행하기 위해 트리거가 정의 된 뷰에 인서트와 관련된 트릭을 사용할 수 있습니다. SQL Server에서 수행 할 수 있습니까?

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

// 첫 번째 테이블과 동일하게 삽입하려면

$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 개의 테이블을 가지고 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top