表结构,如以下代码
创建 复制代码代码如下所示:
创建表test_tb
(
testid int不是空的身份(1,1)主键,
字幕nvarchar(100)空
);
去
解决方案1:
对于这个问题,第一个想法可能是:可以在标题字段中添加一个单键吗我们这样做,首先创建一个唯一索引。
复制代码代码如下所示:
创建唯一的非聚集索引un_test_tb
在test_tb(字幕)
去
创建索引,我们将测试效果。
复制代码代码如下所示:
插入test_tb(字幕)
值(NULL)
去
插入test_tb(字幕)
值(NULL)
去
运行之后,我们将收到以下
错误信息:
下面提到:
消息2601,第14级,状态1,第一行
一排重复键不能插入一个object'dbo test_tb'with独特的index'un_test_tb。
语句已终止。
所以这个解决方案是不可能的。
解决方案2:
添加约束,允许SQL Server在插入数据时验证是否存在当前数据中插入的值。由于此约束不是一个简单
操作,我们首先创建一个
函数,然后在约束中调用函数。
创建验证逻辑函数:
复制代码代码如下所示:
创建函数{ DBO }。{ fn_ck_test_tb_caption }()
返回点
作为
开始
如果(存在)
选择1
从test_tb作为
其中(标题不为空且存在)
(选择1作为表达式
从test_tb
在(标题不为空)和(标题a.caption)和(a.testid)<> testid)
))
返回0
返回1
结束
去
约束中的引用函数:
复制代码代码如下所示:
修改表test_tb
添加约束ck_test_tb_caption
检查(dbo.fn_ck_test_tb_caption()= 1)
去
现在测试这个效果。首先测试null值。
复制代码代码如下所示:
插入test_tb(字幕)
值(NULL)
去
插入test_tb(字幕)
值(NULL)
去
SELECT * FROM test_tb
去
它可以成功运行,而且它具有多行为null
情况。现在再次测试非空插入。
复制代码代码如下所示:
插入test_tb(字幕)
值(n'aaa)
去
插入test_tb(字幕)
VALUES (N'BBB')
去
插入test_tb(字幕)
值(n'bbb)
去
SELECT * FROM test_tb
去
结果是,第三的说法是错误的,并在表格标题字段也有aaa'andBBB,这正是我们想要的结果。
那么解决方案2是
正确的,但是对于这么小的函数来说,写这么长的一段东西是否太麻烦了呢让我们看看下面的解决方案。
解决方案3:(仅适用于SQL Server 2008)
在SQL Server 2008中的一个完美的解决方案,这是进行指标筛选。筛选指标是一个
优化的非聚集索引,特别是
查询,覆盖从定义的数据子集选择数据。过滤指标采用过滤谓词的索引表中的表的一部分。一个筛选指标,我们只需要写一个语句实现上述效果。
复制代码代码如下所示:
创建唯一的非聚集索引un_test_tb
在test_tb(字幕)
标题不为空
去
使用上面的一些测试语句来测试,它将被
发现完全是我们的要求。这个方案的唯一缺点是,这个语句只有SQL Server 2008
支持。不知道您还没有优雅的解决方案,适合于所有版本的SQL Server,希望与我们合作。