【发布时间】:2011-08-09 05:36:13
【问题描述】:
考虑一下这个简单的表格:
建表语句是:
CREATE TABLE [dbo].[Test_Serializable](
[Id] [int] NOT NULL,
[Name] [nvarchar](50) NOT NULL
)
所以没有任何主键或索引。
考虑它是空的并且没有任何行。我想插入这一行(1,'nima'),但我想检查是否存在Id=1 的行。如果是,则调用RAISERROR,如果没有插入行。我写了这个脚本:
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRY
BEGIN TRAN ins
IF EXISTS(SELECT * FROM Test_Serializable ts WITH(xlock,ROWLOCK) WHERE ts.Id=1)
RAISERROR(N'Row Exists',16,1);
INSERT INTO Test_Serializable
(
Id,
[Name]
)
VALUES
(
1,
'nima'
)
COMMIT TRAN ins
END TRY
BEGIN CATCH
DECLARE @a NVARCHAR(1000);
SET @a=ERROR_MESSAGE();
ROLLBACK TRAN ins
RAISERROR(@a,16,1);
END CATCH
这个脚本运行良好,但有一点很有趣。
我从 2 个 SSMS 运行此脚本并逐步运行这 2 个脚本(在调试模式下)。有趣的是,我的表没有行,但当到达 IF EXIST 语句锁定表时,其中一个脚本。
我的问题是(XLOCK,ROWLOCK) 是否会因为没有行而锁定整个表?还是会锁定幻像行:) !!???
编辑 1)
这是我的场景:
我有一个表格,例如 6 个字段
这是唯一性规则:
1)City_Code + F1_Code 是唯一的
2)City_Code + F2_Code 是唯一的
3)City_Code + F3_Code + F4_Code 是唯一的
问题是用户可能想要填写city_code 和F1_Code,当它想要将其插入其他字段时,我们必须具有Empty String 或0(对于数字字段)值。
如果用户想填写 City_Code + F3_Code + F4_Code 那么 F1_Code 和 F2_Code 必须有 Empty String 值
我怎样才能更好地检查这个?我不能为每个规则创建任何唯一索引
【问题讨论】:
-
这适用于 SQL Server 2005 还是 SQL Server 2008:这对解决方案很重要...
标签: sql sql-server sql-server-2005 sql-server-2008