2011-11-11 75 views
0

我需要爲CASE子句中的字段分配一個new_id。T-SQL:在CASE子句中使用INSERT INTO&OUTPUT

這裏是例如:

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] 

的代碼片段

INSERT INTO [table3] 
OUTPUT inserted.some_new_id 
DEFAULT VALUES 

的CASE子句之外使用時工作正常。

主要的問題是,我必須分配從table3獲得的new_id時field3_from_table2我試圖插入到table1 IS NULL。
table3只是一個ID調度器。

任何想法或解決此問題的解決方法?

在此先感謝。

+2

你不能讓你的發言'CASE'裏面 - 它只是設計用來**返回值**('WHEN .... THEN(這裏的一些值)') –

+0

@Chorinator,如果'field3_from_table2'是'NULL',是在你的例子中'INSERT'到table1的行嗎? – gonsalu

+0

@Gonsalu不,不在示例中,但它是一個非常簡單的表格。它只包含一列,它是一個身份。我僅將該表用作Id調度程序。 – Chorinator

回答

1

正如marc_s所指出的那樣,你不能這樣做。 您可以看到正確的大小寫語法here

要解決您的問題,最好的解決方案是使用cursor

你可以看到一個光標的代碼示例here

0

假設table3生成順序整數值,像IDENTITY屬性具有值1的增量,可以生成那些自己使用ROW_NUMBER(),然後INSERT荷蘭國際集團生成的值成table3

但是,由於您自己生成了值,因此您必須鎖定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;