SQL Server触发器未按预期运行
我有两张桌子:SQL Server触发器未按预期运行,sql,sql-server,database,triggers,Sql,Sql Server,Database,Triggers,我有两张桌子: CREATE TABLE [dbo].[Test_Table1] ( [id] [int] IDENTITY(1,1) NOT NULL, [f_id] [int] NULL ) ON [PRIMARY] CREATE TABLE [dbo].[Test_Table2_Tbl] ( [f_id] [int] IDENTITY(1,1) NOT NULL, [text] [varchar](500) NULL ) ON [PRIMARY] 和一个
CREATE TABLE [dbo].[Test_Table1]
(
[id] [int] IDENTITY(1,1) NOT NULL,
[f_id] [int] NULL
) ON [PRIMARY]
CREATE TABLE [dbo].[Test_Table2_Tbl]
(
[f_id] [int] IDENTITY(1,1) NOT NULL,
[text] [varchar](500) NULL
) ON [PRIMARY]
和一个触发器:
CREATE TRIGGER [dbo].[trg_Test_Trigger_Delete]
ON [dbo].[Test_Table2_Tbl]
AFTER DELETE
AS
INSERT INTO Test_Table2_Tbl (text)
(SELECT id FROM deleted)
UPDATE Test_Table1_Tbl
SET f_id = NULL
WHERE f_id IN (SELECT id FROM deleted)
GO
敏锐的观察者会意识到“已删除”中不存在“id”
SQL在INSERT中捕获该错误,但如果没有INSERT,它将允许您添加触发器,而不会产生任何抱怨
为什么它没有捕捉到那个错误?(列名“id”无效。)
我的第二个问题是,为什么UPDATE
语句在deleted中找不到id时将EVERY
列更新为NULL
我只是非常困惑,需要弄清楚为什么每个记录都与
WHERE
子句匹配。您在更新中的错误是因为查询被视为相关子查询:
UPDATE Test_Table1_Tbl
SET f_id = NULL
WHERE Test_Table1_Tbl.f_id IN (SELECT Test_Table1_Tbl.id FROM deleted d);
id
在deleted
中无法解析,因此SQL将在下一个级别进行查看
这些是子查询的范围规则。这就是为什么在有子查询时应始终使用限定表名的原因:
UPDATE Test_Table1_Tbl
SET f_id = NULL
WHERE Test_Table1_Tbl.f_id IN (SELECT d.id FROM deleted d);
插入中唯一的错误是逻辑错误。id在该上下文中完全有效,因为id是Test_Table1_Tbl中的一列。使用create table和create trigger ddl,我无法创建触发器。可能在创建触发器时,Test_Table2_Tbl中有一个名为id的列?这就解释了为什么你可以使用触发器而不是列。