2016-08-09 5 views
0

На сервере базы данных SQL Server 2008 R2 я пытаюсь вставить данные в таблицу, но предложение OUTPUT оператора INSERT возвращает только нули для столбца Identity таблицы. Инструкция INSERT, приведенная ниже, является частью более крупного скрипта со многими утверждениями, заключенными в одну транзакцию.Предложение OUTPUT оператора SQL Server INSERT не возвращает значения идентификатора

Вот заявление:

INSERT INTO CountryDivisions (
    [CountryID] 
    , [ParentDivisionID] 
    , [DivisionCodeISO] 
    , [DivisionCodeShort] 
    , [DivisionType] 
) 
    OUTPUT 
     inserted.[CountryDivisionID] -- Identity column, returning only zeros! 
     , inserted.[CountryID] 
     , inserted.[ParentDivisionID] 
     , inserted.[DivisionCodeISO] 
     , inserted.[DivisionCodeShort] 
     , inserted.[DivisionType] 
     INTO @NewCountryDivisions 
    SELECT 
     dc.[CountryID] 
     , null 
     , COALESCE(mcd.DependentDivisionCodeISO, mcd.ParentCountryAlpha2Code + '-' + mcd.DependentCountryAlpha2Code) 
     , mcd.DependentCountryAlpha2Code 
     , mcd.DependentDivisionType 
    FROM 
     @MoreCountryData AS mcd 
     JOIN Countries AS dc 
      ON dc.Alpha2Code = mcd.DependentCountryAlpha2Code 
    WHERE 
     NOT EXISTS (
      SELECT * 
      FROM CountryDivisions AS cd2 
      WHERE 
       cd2.[CountryID] = dc.[CountryID] 
       AND cd2.[DivisionCodeShort] = mcd.DependentCountryAlpha2Code 
     ) 

Это то, что я вижу при выборе из @NewCountryDivisions: enter image description here

Вот определение стола:

CREATE TABLE [dbo].[CountryDivisions](
    [CountryDivisionID] [int] IDENTITY(1,1) NOT NULL, -- identity column which is only returning zeros! 
    [CountryID] [int] NOT NULL, 
    [ParentDivisionID] [int] NULL, 
    [DivisionCodeISO] [nvarchar](10) NULL, 
    [DivisionCodeShort] [nvarchar](10) NULL, 
    [DivisionType] [nvarchar](150) NULL, 
    [LastUpdatedBy] [sysname] NOT NULL DEFAULT (user_name()), 
    [LastUpdatedDateTime] [datetime] NOT NULL DEFAULT (getutcdate()), 
CONSTRAINT [PK_CountryDivisions_CountryDivisionID] PRIMARY KEY NONCLUSTERED 
(
    [CountryDivisionID] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) 
) 

Я использую INSTEAD OF триггеры для обновления двух LastUpdated... колонны. Я новичок в написании триггеров, хотя я бы не стал ожидать их, чтобы вызвать эту проблему, но только в том случае, вот их определения:

CREATE TRIGGER [dbo].[CountryDivisions_InsertAudit] 
    ON [dbo].[CountryDivisions] 
    INSTEAD OF INSERT 
    AS 
    BEGIN 
     SET NoCount ON 

     INSERT INTO [dbo].[CountryDivisions] (
      -- I am assuming that SQL Server will apply the IDENTITY process to the [CountryDivisionID] column, so I am not inserting it myself. 
      [CountryID] 
      , [ParentDivisionID] 
      , [DivisionCodeISO] 
      , [DivisionCodeShort] 
      , [DivisionType] 
      , [LastUpdatedBy] 
      , [LastUpdatedDateTime] 
     ) 
      SELECT 
       i.CountryID 
       , i.ParentDivisionID 
       , i.DivisionCodeISO 
       , i.DivisionCodeShort 
       , i.DivisionType 
       , COALESCE(NULLIF(LTRIM(RTRIM(i.[LastUpdatedBy])), ''), USER_NAME()) 
       , COALESCE(i.[LastUpdatedDateTime], GETUTCDATE()) 
      FROM 
       inserted AS i 

    END 

CREATE TRIGGER [dbo].[CountryDivisions_UpdatAudit] 
    ON [dbo].[CountryDivisions] 
    INSTEAD OF UPDATE 
    AS 
    BEGIN 
     SET NoCount ON 

     UPDATE [dbo].[CountryDivisions] 
      SET 
       CountryID = i.CountryID 
       , ParentDivisionID = i.ParentDivisionID 
       , DivisionCodeISO = i.DivisionCodeISO 
       , DivisionCodeShort = i.DivisionCodeShort 
       , DivisionType = i.DivisionType 
       , LastUpdatedBy = COALESCE(NULLIF(LTRIM(RTRIM(i.[LastUpdatedBy])), ''), USER_NAME()) 
       , LastUpdatedDateTime = COALESCE(i.[LastUpdatedDateTime], GETUTCDATE()) 
      FROM 
       [dbo].[CountryDivisions] AS cd 
       JOIN inserted AS i 
        JOIN deleted AS d 
         ON d.CountryDivisionID = i.CountryDivisionID 
        ON cd.CountryDivisionID = i.CountryDivisionID 
      WHERE 
       -- only update records that have actually been updated. 
       i.CountryID <> d.CountryID 
       OR ISNULL(i.ParentDivisionID, -1) <> ISNULL(d.ParentDivisionID, -1) 
       OR ISNULL(i.DivisionCodeISO, '') <> ISNULL(d.DivisionCodeISO, '') 
       OR ISNULL(i.DivisionCodeShort, '') <> ISNULL(d.DivisionCodeShort, '') 
       OR (
        ISNULL(i.LastUpdatedBy, '') <> ISNULL(d.LastUpdatedBy, '') 
        AND UPDATE(LastUpdatedBy) 
       ) 
       OR (
        ISNULL(i.LastUpdatedDateTime, '1900-01-01') <> ISNULL(d.LastUpdatedDateTime, '1900-01-01') 
        AND UPDATE(LastUpdatedDateTime) 
       ) 
    END 

ответ

0

кажется, что мои спусковые были проблема!

Из комментария кто-то сделали в другом потоке переполнения стеки, OUTPUT положения о INSERT утверждениях, где базовая таблица содержит INSTEAD OF триггера будет возвращать только нули для любого столбца, определенного с помощью функции IDENTITY(seed, increment).

Чтобы обойти эту проблему, я переписал триггеры как AFTER триггер. Это также позволяет мне объединить два триггера в один триггер.

CREATE TRIGGER [dbo].[CountryDivisions_Audit] 
    ON [dbo].[CountryDivisions] 
    AFTER INSERT, UPDATE 
    AS 
    BEGIN 
     SET NoCount ON 

     -- prevent recursion 
     If TRIGGER_NESTLEVEL() > 1 RETURN 

     UPDATE cdan 
      SET 
       [LastUpdatedBy] = USER_NAME() 
       , [LastUpdatedDateTime] = GETUTCDATE() 
      FROM 
       [dbo].[CountryDivisions] AS cdan 
       JOIN inserted AS i 
        LEFT JOIN deleted AS d 
         ON d.[CountryDivisionID] = i.[CountryDivisionID] 
        ON i.[CountryDivisionID] = cdan.[CountryDivisionID] 
      WHERE 
       -- only update records that have actually been updated. 
       ISNULL(i.[CountryDivisionID], -1) <> ISNULL(d.[CountryDivisionID], -1) 
       OR ISNULL(i.[ParentDivisionID], -1) <> ISNULL(d.[ParentDivisionID], -1) 
       OR ISNULL(i.[DivisionCodeISO], '') <> ISNULL(d.[DivisionCodeISO], '') 
       OR ISNULL(i.[DivisionCodeShort], '') <> ISNULL(d.[DivisionCodeShort], '') 
       OR ISNULL(i.[DivisionType], '') <> ISNULL(d.[DivisionType], '') 
       OR (
        ISNULL(i.LastUpdatedBy, '') <> ISNULL(d.LastUpdatedBy, '') 
        AND UPDATE(LastUpdatedBy) 
       ) 
       OR (
        ISNULL(i.LastUpdatedDateTime, '1900-01-01') <> ISNULL(d.LastUpdatedDateTime, '1900-01-01') 
        AND UPDATE(LastUpdatedDateTime) 
       ) 
    END