Sql server 被困在创造一个触发器
执行一些MSSQL练习,我正在尝试创建一个触发器。然而,我的解决方案在理论上对我来说是正确的,但它不起作用 目的是为只有两列的表创建触发器。一列是主键,是标识,不允许空值。另一列是允许空值的列。但是,它只允许整个表中的一行使用空值。基本上,应该为此表上的insert/update操作触发一个触发器,当表中的列已经存在空值时,该触发器尝试将该列插入/更新为空值 我在触发器代码中捕获的条件如下:Sql server 被困在创造一个触发器,sql-server,sql-server-2005,Sql Server,Sql Server 2005,执行一些MSSQL练习,我正在尝试创建一个触发器。然而,我的解决方案在理论上对我来说是正确的,但它不起作用 目的是为只有两列的表创建触发器。一列是主键,是标识,不允许空值。另一列是允许空值的列。但是,它只允许整个表中的一行使用空值。基本上,应该为此表上的insert/update操作触发一个触发器,当表中的列已经存在空值时,该触发器尝试将该列插入/更新为空值 我在触发器代码中捕获的条件如下: After Insert, Update AS set ANSI_WARNINGS OFF If (
After Insert, Update
AS
set ANSI_WARNINGS OFF
If ( (select count(NoDupName) from TestUniqueNulls where NoDupName is null) > 1 )
BEGIN
Print 'There already is a row that contains a NULL value, transaction aborted';
ROLLBACK TRAN
END
然而,尽管如此,事务还是会自动执行。我不知道为什么会发生这种情况,而且触发器没有自动触发
有人能解释我的疑虑吗
我还使用了在触发器开始时关闭ANSI_警告。count(col)
只计算非空值,因此count(NoDupName)。。。其中NoDupName为null
将始终为零。您需要检查count(*)
我意识到这只是一个练习,但索引视图可能是一个更好的机制
CREATE VIEW dbo.NoMoreThanOneNull
WITH SCHEMABINDING
AS
SELECT NoDupName
FROM dbo.TestUniqueNulls
WHERE NoDupName IS NULL
GO
CREATE UNIQUE CLUSTERED INDEX ix ON dbo.NoMoreThanOneNull(NoDupName)
是的,我明白了。COUNT参数内的表达式的计算结果必须为NOTNULL,否则将不进行计数。因此,在表达式中使用
*
或1
或任何不可为空的列更安全。最常见的表达式是“*”
,尽管您也会遇到“1”。就性能而言,这些表达式之间没有区别。然而,若您使用的表达式可以计算为null(比如null列),那个么您的计数和其他聚合可能会完全关闭
create table nulltest(a int null)
go
insert nulltest(a) values (1), (null), (2)
go
select * from nulltest
select COUNT(*) from nulltest
select COUNT(1) from nulltest
select COUNT(a) from nulltest
go
drop table nulltest