T-SQL:使用INSERT INTO& CASE子句中的OUTPUT

时间:2011-11-11 19:13:07

标签: sql-server sql-server-2008 tsql

我需要将一个new_id分配给CASE子句中的字段。

以下是示例:

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子句之外使用时工作正常。

主要问题是当我尝试插入到table1中的field3_from_table2为IS NULL时,我必须分配从table3获取的new_id。
table3只是一个ID调度程序。

对此问题有任何想法或解决方法吗?

提前致谢。

2 个答案:

答案 0 :(得分:1)

正如marc_s指出的那样,使用案例你不能这样做。 您可以看到正确的大小写语法here

要解决您的问题,最佳解决方案是使用cursor

您可以看到带有光标here的sp的代码示例。

答案 1 :(得分:0)

假设table3生成顺序整数值,例如值为1的IDENTITY属性,您可以使用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;