【问题标题】:SQL Server trigger does not recognize inserted rowSQL Server 触发器无法识别插入的行
【发布时间】:2019-11-06 03:15:58
【问题描述】:

我有一个简单的 SQL Server 触发器,但由于某种原因它无法识别 INSERTED 行。

代码如下:

-- code
DROP TABLE a;
GO

CREATE TABLE a 
(
    id INT IDENTITY(1,1) PRIMARY KEY,
    v INT
)
GO

DROP TABLE a_audit;

CREATE TABLE a_audit 
(
    id INT,
    v INT,
    [updated_at] [DATETIME] NOT NULL DEFAULT GETDATE()
)
GO

CREATE TRIGGER [dbo].[trg_a]
ON [dbo].[a]
AFTER INSERT, UPDATE, DELETE
NOT FOR REPLICATION
AS
BEGIN
    SET NOCOUNT ON;
    PRINT 'start';

    DECLARE @xmltmp xml = (SELECT * FROM inserted FOR XML AUTO);
    PRINT CONVERT(NVARCHAR(MAX), @xmltmp);

    -- INSERT INTO a_audit (id, v) VALUES (inserted.id, inserted.v);
END;
GO

INSERT INTO a (v) 
VALUES (1);

WAITFOR DELAY '00:00:01.11';

INSERT INTO a (v) 
VALUES (2);
GO

SELECT * FROM a;

PRINT 'done'

它产生这个输出

start
<inserted id="1" v="1"/>

(1 row affected)
start
<inserted id="2" v="2"/>

(1 row affected)

(2 rows affected)
done

所以我看到 INSERTED 行确实存在。

但是,如果我删除对 insert 语句的评论,输出是这样的:

消息 4104,级别 16,状态 1,过程 trg_a,第 14 行 [批处理开始第 16 行]
无法绑定多部分标识符“inserted.id”。

消息 4104,级别 16,状态 1,过程 trg_a,第 14 行 [批处理开始第 16 行]
无法绑定多部分标识符“inserted.v”。

怎么了?

【问题讨论】:

  • 当它只引用对象inserted时,为什么TRIGGERDELETE上?

标签: sql-server triggers


【解决方案1】:

inserted 是一个表,而不是一个函数。要从另一个表中INSERT,您需要使用INSERT INTO... SELECT ... FROM 语句:

INSERT INTO a_audit (id,v)
SELECT id,
       v
FROM inserted;

除非您使用FROM,否则您无法引用表的列。例如,仅运行以下代码会出现以下错误:

SELECT a_audit.id, a.audit.v;

无法绑定多部分标识符“a_audit.id”。

你必须SELECT...FROM:

SELECT id, v
FROM a_audit;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-09
    • 1970-01-01
    • 2016-12-22
    相关资源
    最近更新 更多