[英]SQL Server INSERT statement's OUTPUT clause not returning identity values
在SQL Server 2008 R2數據庫服務器上,我嘗試將數據插入表中,但是INSERT語句的OUTPUT子句僅為表的“標識”列返回零。 下面的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
選擇時看到的@NewCountryDivisions
:
這是表的定義:
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
看來我的觸發器是問題所在!
根據另一個堆棧溢出線程中某人的注釋,基礎表包含INSTEAD OF
觸發器的INSERT
語句上的OUTPUT
子句對於用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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.