【发布时间】:2019-09-20 05:19:53
【问题描述】:
我正在尝试在数据库中的一个表上创建触发器,如下所示
CREATE TRIGGER tr_JTIA_ForInsert
ON MyTable
FOR INSERT
AS
BEGIN
DECLARE @JTIItemID INT,
@UserWWID INT
IF EXISTS (SELECT *
FROM [MyTable] JTIA
INNER JOIN inserted NewItem ON NewItem.ItemID = JTIA.ItemID
AND NewItem.UserWWID = JTIA.UserWWID
AND NewItem.Status = JTIA.Status)
BEGIN
SELECT
@JTIItemID = inserted.ItemID,
@UserWWID = inserted.UserWWID
FROM
inserted
EXEC msdb.dbo.sp_send_dbmail
@recipients = 'edwin@gmail.com',
@profile_name = 'App Administrator',
@body = SELECT CONCAT('User : ',(SELECT CONVERT(varchar(20),12345)), ' was assigned a duplicate JTIItemID: ', (SELECT CONVERT(varchar(20),1234567)), ' at timestamp: ', (select convert(varchar, getdate(), 22))),
@subject = 'Duplicate record Was Assigned to user:';
END
END
当我执行上述触发器时,我在创建时收到以下错误消息。
消息 156,级别 15,状态 1,过程 tr_JTIA_ForInsert,第 16 行 [批处理开始第 0 行]
关键字“SELECT”附近的语法不正确。消息 137,级别 15,状态 1,过程 tr_JTIA_ForInsert,第 17 行 [批处理开始第 0 行]
必须声明标量变量“@subject”。
不知道我错过了什么
【问题讨论】:
-
您需要在调用
EXEC msdb.dbo.sp_send_dbmail之前构建您的电子邮件消息的@body。在调用这个系统存储过程时,你应该只使用字符串文字和字符串变量——没有复杂的SELECT和其他逻辑来创建结果stirng -
另外:您的触发器有 MAJOR 缺陷,您似乎认为它会被调用 每行一次 - 事实并非如此。触发器将每条语句触发一次,因此如果您的
INSERT导致此触发器触发插入 25 行,您将触发触发器一次和@987654326 @ 伪表将包含 25 行。您的代码将从Inserted中选择这 25 行中的哪一行?它是不确定的,您将获得任意行,而您将忽略所有其他行。您需要重写触发器以考虑到这一点!
标签: sql-server tsql database-trigger