T-SQL: использование INSERT INTO & OUTPUT внутри предложения CASE - PullRequest
1 голос
/ 11 ноября 2011

Мне нужно назначить 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.

Основная проблема заключается в том, что мне нужно присвоить new_id, полученный из table3, когда field3_from_table2, который я пытаюсь вставить в table1, является NULL.
table3 - просто диспетчер идентификаторов.

Любая идея или решение этой проблемы?

Заранее спасибо.

Ответы [ 2 ]

1 голос
/ 12 ноября 2011

Как указано marc_s, вы не можете сделать это, используя регистр. Вы можете увидеть правильный синтаксис регистра здесь .

Для решения вашей проблемы лучше всего использовать курсор .

Вы можете увидеть пример кода для sp с курсором здесь .

0 голосов
/ 12 ноября 2011

Предполагая, что 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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...