Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/77.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 与触发器一起使用时,Inserted子句返回0_Sql_Sql Server - Fatal编程技术网

Sql 与触发器一起使用时,Inserted子句返回0

Sql 与触发器一起使用时,Inserted子句返回0,sql,sql-server,Sql,Sql Server,我试图使用SQL server 2012从下表的inserts语句中获取最后插入的行Id [dbo].[Table]( [TableId] [int] IDENTITY(1,1) NOT NULL, [Name] [nvarchar](50) NULL, [CreatedBy] [nvarchar](50) NULL, [CreatedDate] [datetime2](7) NOT NULL, [ModifiedBy] [nvarchar](50) NULL, [ModifiedDate] [

我试图使用SQL server 2012从下表的inserts语句中获取最后插入的行Id

[dbo].[Table](
[TableId] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](50) NULL,
[CreatedBy] [nvarchar](50) NULL,
[CreatedDate] [datetime2](7) NOT NULL,
[ModifiedBy] [nvarchar](50) NULL,
[ModifiedDate] [datetime2](7) NULL,
CONSTRAINT [pk_Table] PRIMARY KEY CLUSTERED 
(
[TableId] ASC
)
我还在该表上使用审计触发器,如下所示:

 trigger [dbo].[trigger_Table_auditColumnAutoInsert]
on [dbo].[Table]
instead of insert
/************************************************************** 
* INSTEAD OF trigger on table [dbo].[Table] responsible
    for automatically inserting audit column data
**************************************************************/ 
as
begin
    set nocount on
    declare @currentTime datetime2
    set @currentTime = GETUTCDATE()

    insert into [dbo].[Table]
    (
        Name,
        CreatedBy,
        CreatedDate,
        ModifiedBy,
        ModifiedDate
    )
    select
        Name,
        ISNULL(CreatedBy, system_user),
        @currentTime,
        NULL,
        NULL
    from inserted
    select SCOPE_IDENTITY() as [TableId]
    goto EOP -- end of procedure

ErrorHandler:
    if (@@trancount <> 0) rollback tran
EOP:
end
            declare @tmpTable table (id int)

            insert @tmpTable (id )
            exec sp_executesql N'insert into dbo.[Table](Name) Values(''foo'')'

            select id from @tmpTable
使用插入的输出总是为标识列返回0;尽管它返回其他插入的值:

 declare @tmpTable table
 (
 TableId int,
 Name nvarchar (50)
 )

INSERT INTO [dbo].[Table]([Name])
output inserted.TableId, inserted.Name into @tmpTable
VALUES('foo')


select * from @tmpTable

TableId Name
0       foo
我知道另一种从触发器本身获取插入Id的解决方案,方法是执行动态sql命令,如下所示:

 trigger [dbo].[trigger_Table_auditColumnAutoInsert]
on [dbo].[Table]
instead of insert
/************************************************************** 
* INSTEAD OF trigger on table [dbo].[Table] responsible
    for automatically inserting audit column data
**************************************************************/ 
as
begin
    set nocount on
    declare @currentTime datetime2
    set @currentTime = GETUTCDATE()

    insert into [dbo].[Table]
    (
        Name,
        CreatedBy,
        CreatedDate,
        ModifiedBy,
        ModifiedDate
    )
    select
        Name,
        ISNULL(CreatedBy, system_user),
        @currentTime,
        NULL,
        NULL
    from inserted
    select SCOPE_IDENTITY() as [TableId]
    goto EOP -- end of procedure

ErrorHandler:
    if (@@trancount <> 0) rollback tran
EOP:
end
            declare @tmpTable table (id int)

            insert @tmpTable (id )
            exec sp_executesql N'insert into dbo.[Table](Name) Values(''foo'')'

            select id from @tmpTable

我不明白为什么在前两个案例中它不起作用;为什么虽然触发器在同一事务中执行,但SCOPE_IDENTITY()不起作用?以及INSERTED子句为标识列返回0的原因。

以下要求似乎适用于审核列数据:

  • 默认情况下,使用为
    CreatedBy
    提供的插入值,或使用
    SYSTEM\u USER
  • 对于
    CreatedDate
    ,始终使用
    GETUTCDATE()
  • 如果INSTEAD OF触发器(而不是AFTER触发器)对您的需求不是必需的,那么您可以在审核列上使用默认约束和AFTER INSERT触发器来强制执行需求#2

    然后,使用
    SCOPE\u IDENTITY()
    和输出插入技术来获得新的
    TableId


    如果INSTEAD OF触发器对于您的实现是必不可少的,那么
    SELECT@@IDENTITY
    SCOPE\u IDENTITY

    的替代方法,如果您尝试的是小猪而不是跳跳虎?很抱歉我忍不住对你的问题中的拼写错误感兴趣。。。我希望温和的幽默不会在SO中受到反对……但是@@IDENTITY不是一个安全的选项。我没有一个现成的解释来解释为什么SCOPE_IDENTITY()不能与INSTEAD OF触发器一起工作。我尝试了您的示例,得到了与您相同的结果。@user908723-无论是
    @@IDENTITY
    还是
    SCOPE\u IDENTITY
    在触发器中都将是一个不正确的概念,因为触发器是针对语句而不是针对每一行触发的-对于多行
    插入
    ,已生成多个标识值,但
    @@identity
    SCOPE\u identity
    都只返回一个值。