2011-11-11 2 views
0

CASE 절 안의 필드에 new_id를 할당해야합니다. 케이스 절 외부 사용시T-SQL : CASE 절의 INSERT INTO & OUTPUT 사용

INSERT INTO [table3] 
OUTPUT inserted.some_new_id 
DEFAULT VALUES 

잘 작동

INSERT INTO [table1] 
    (field1, field2, field3, field4, field5, field6) 
SELECT @someID1, field1_from_table2, @someID2, field2_from_table2, 
CASE 
    WHEN field3_from_table2 IS NULL 
    THEN INSERT INTO [table3] 
     OUTPUT inserted.some_new_id 
     DEFAULT VALUES 
    ELSE field3_from_table2 
END 
FROM [table2] 

코드 단편 여기

는 예이다.

주된 문제점은 field3_from_table2가 table1 IS NULL에 삽입하려고 할 때 table3에서 가져온 new_id를 할당해야한다는 것입니다.
table3은 ID 디스패처입니다.

이 문제에 대한 아이디어 나 해결책이 있습니까?

미리 감사드립니다.

+2

- 그것은 단지 설계에 ** 반환 값 ** ('여기 .... THEN (일부 값)') –

+0

@Chorinator, 만약'field3_from_table2' 당신의 예제에서 table1에'INSERT' 될 행은'NULL'입니까? – gonsalu

+0

@Gonsalu 아니요, 예제에 없지만 아주 간단한 테이블입니다. 그것은 단지 하나의 열을 포함하고 그것은 신원이다. 이 테이블은 ID 발송자로만 사용합니다. – Chorinator

답변

1

marc_s가 가리키는대로, 당신은 a 경우를 사용하여 그렇게 할 수 없습니다. 올바른 케이스 구문 here을 볼 수 있습니다.

문제를 해결하려면 cursor을 사용하는 것이 가장 좋습니다.

커서가있는 012에 대한 코드 예제를 볼 수 있습니다 here. 가정 table3

0

값 1 증가와 같은 속성 IDENTITY 순차 정수 값을 생성하면 table3에 생성 된 값을 보내고 그 다음 자신 ROW_NUMBER()를 사용하는 한 INSERT를 생성 할 수있다.

그러나 직접 값을 생성 중이므로 table3을 잠 가서 문이 실행되는 동안 변경되지 않도록해야합니다.

테스트 사례를 설정해 보겠습니다.

USE tempdb 
GO 

IF OBJECT_ID('table1', 'U') IS NOT NULL DROP TABLE table1; 
IF OBJECT_ID('table2', 'U') IS NOT NULL DROP TABLE table2; 
IF OBJECT_ID('table3', 'U') IS NOT NULL DROP TABLE table3; 

CREATE TABLE table1 (
    field1 int, 
    field2 int, 
    field3 int, 
    field4 int, 
    field5 int 
); 

CREATE TABLE table2 (
    field1_from_table2 int, 
    field2_from_table2 int 
); 

CREATE TABLE table3 (
    field1_from_table3 int IDENTITY(1,1) 
); 

INSERT INTO table2 
VALUES (1000, 2000) 
    , (1001, NULL); 
GO 

-- INSERT 20 records to generate some IDENTITY increments. 
INSERT INTO table3 DEFAULT VALUES 
GO 20 

다음은 순차 값을 생성하는 코드의 예입니다.

BEGIN TRANSACTION; 

SET IDENTITY_INSERT table3 ON; 
GO 

DECLARE @someID1 int = 100 
     , @someID2 int = 200; 
DECLARE @output table (field4 int, field5 int); 

-- Lock table3 exclusively to prevent INSERTs that spoil IDENTITY values. 
SELECT TOP(0) 1 FROM table3 WITH (HOLDLOCK, TABLOCKX); 

-- INSERT into table1, generating sequential integers 
-- and saving the output in @output. 
INSERT INTO table1 
OUTPUT inserted.field4 
    , inserted.field5 
    INTO @output(field4, field5) 
SELECT @someID1 
    , field1_from_table2 
    , @someID2 
    , field2_from_table2 
    , CASE 
     WHEN field2_from_table2 IS NOT NULL THEN field2_from_table2 
     ELSE (ROW_NUMBER() OVER (PARTITION BY field2_from_table2 
            ORDER BY field2_from_table2)) 
       + (SELECT MAX(field1_from_table3) FROM table3) 
     END 
    FROM table2; 

-- INSERT generated integer values. 
INSERT INTO table3 (field1_from_table3) 
SELECT field5 
    FROM @output 
WHERE field4 IS NULL; 

SET IDENTITY_INSERT table3 OFF; 
GO 

COMMIT; 

SELECT * FROM table1; 
SELECT * FROM table2; 
SELECT * FROM table3; 
당신은`CASE` 내부 문을 가질 수 없습니다