[转载]SQL Server如何保证可空字段中非空值唯一
原文地址:http://www.cnblogs.com/caspnet/archive/2011/02/23/1962638.html
解决问题是:在一个表里面,有一个允许为空的字段,空是可以重复的,但是不为空的值需要唯一。
表结构如下面代码创建
CREATE TABLE test_tb
(
TestId int not null identity(1,1) primary key,
Caption nvarchar(100) null
);
GO
解决方案1:
对于这个问题,大家的第一个想法可能是:在Caption这个字段上面加一个唯一键不就可以了吗?好,我们按着这个思路做下去,先创建唯一索引。
CREATE UNIQUE NONCLUSTERED INDEX un_test_tb
ON test_tb(Caption)
GO
索引创建好了,我们来测试下效果
INSERT INTO test_tb (Caption)
VALUES (null)
GO
INSERT INTO test_tb (Caption)
VALUES (null)
GO
运行之后我们会收到下面的错误信息:
消息 2601,级别 14,状态 1,第 1 行
不能在具有唯一索引 'un_test_tb' 的对象 'dbo.test_tb' 中插入重复键的行。
语句已终止。
所以该解决方案是不行的。
解决方案2:
添加约束,让SQL Server在插入数据的时候,先验证下已有数据中是否有现在要插入的这个值。由于这个约束不是简单的一个运算,因此我们先创建一个函数,然后再在约束中调用这个函数。
创建验证逻辑函数:
CREATE FUNCTION [dbo].[fn_CK_test_tb_Caption]()
RETURNS BIT
AS
BEGIN
IF(EXISTS(
SELECT 1
FROM test_tb AS a
WHERE (Caption IS NOT NULL) AND EXISTS
(SELECT 1 AS Expr1
FROM test_tb
WHERE (Caption IS NOT NULL) AND (Caption = a.Caption) AND (a.TestId <> TestId))
))
RETURN 0 RETURN 1
END
GO
在约束中引用函数:
ALTER TABLE test_tb
ADD CONSTRAINT CK_test_tb_Caption CHECK (dbo.fn_CK_test_tb_Caption() = 1)
GO
INSERT INTO test_tb (Caption)
VALUES (null)
GO
INSERT INTO test_tb (Caption)
VALUES (null)
GO
SELECT * FROM test_tb
GO
可以成功运行,而且也出了多行为NULL的情况。现在再来测试不为空的插入情况。
INSERT INTO test_tb (Caption)
VALUES (N'AAA')
GO
INSERT INTO test_tb (Caption)
VALUES (N'BBB')
GO
INSERT INTO test_tb (Caption)
VALUES (N'BBB')
GO
SELECT * FROM test_tb
GO
结果是在第三条语句的时候报错了,表中的Caption字段也有'AAA'和'BBB'了,这也正好是我们要的结果。
所以解决方案2是正确的。但是为了这么一个小小功能,就写这么长一段东西是不是太繁琐了呢?我们来看下面的解决方案。
解决方案3:(只适用于SQL Server 2008)
SQL Server 2008中有了一个优雅的解决方案,那就是筛选索引。筛选索引是一种经过优化的非聚集索引,尤其适用于涵盖从定义完善的数据子集中选择数据的查询。筛选索引使用筛选谓词对表中的部分行进行索引。有了筛选索引,我们只需要写一条语句就达到上面的效果。
CREATE UNIQUE NONCLUSTERED INDEX un_test_tb
ON test_tb(Caption)
WHERE Caption is not null
GO
再用上面的一些测试语句来测试的话,会发现完全是达到了我们的要求。
这个方案的唯一缺点就是该语句只有SQL Server 2008支持。。
[转载]SQL Server如何保证可空字段中非空值唯一的更多相关文章
- SQL SERVER将某一列字段中的某个值替换为其他的值 分类: MSSQL 2014-11-05 13:11 67人阅读 评论(0) 收藏
SQL SERVER将某一列字段中的某个值替换为其他的值 UPDATE 表名 SET 列名 = REPLACE(列名 ,'贷','袋') SQL SERVER"函数 replace 的参数 ...
- sql server中NULL导入decimal字段时报错
sql server中NULL导入decimal字段时报错 在导入CSV文件时,如果decimal字段为null值,导致文本文件入库时失败. 错误现象 构造例子 新建一张表,包含decimal字段. ...
- [转载]C#中使用ADO.NET连接SQL Server数据库,自动增长字段用作主键,处理事务时的基本方法
问题描述: 假设在数据库中存在以下两张数据表: User表,存放用户的基本信息,基本结构如下所示: 类型 说明 ID_User int 自动增长字段,用作该表的主键 UserName varcha ...
- 转载 SQL Server中索引管理之六大铁律
转载原地址 http://jingyan.baidu.com/article/48a42057c03bd7a924250429.html 索引是以表列为基础的数据库对象.索引中保存着表中排序的索引列, ...
- 转载——SQL Server数据库性能优化之SQL语句篇
转载自:http://www.blogjava.net/allen-zhe/archive/2010/07/23/326927.html 1. 按需索取字段,跟“SELECT *”说拜拜 字段的提取一 ...
- [转载]SQL Server中的事务与锁
了解事务和锁 事务:保持逻辑数据一致性与可恢复性,必不可少的利器. 锁:多用户访问同一数据库资源时,对访问的先后次序权限管理的一种机制,没有他事务或许将会一塌糊涂,不能保证数据的安全正确读写. 死锁: ...
- 转载--SQL Server 2005的XQuery介绍
原文地址: http://bbs.51cto.com/thread-458009-1-1.html 引用: 摘要 本文介绍了SQL Server 2005能够支持的XQuery的各方面特性如FLW ...
- SQL Server进阶(二)字段类型
概述 系统数据类型详情 SqlDbType namespace System.Data { // // 摘要: // 指定要用于 System.Data.SqlClient.SqlParameter ...
- 将文件导入到SQL server数据库表中的字段中
一.在要执行的sql server数据库a中执行如下脚本,创建存储过程sp_textcopy /* 将二进制文件导入.导出到数据库相应字段列中 */ CREATE PROCEDURE sp_textc ...
随机推荐
- C++内存泄露之野指针
写出本文仅仅是处于备忘的目的. 最近为现在做的软件添加了一个内存回收机制(以前处于某种内存只申请不释放,这并不等于内存泄露,因为我们知道这些内存块在内存中的位置)-- 在某一块内存不使用的时候将其释放 ...
- 【转】Eclipse下启动tomcat报错:/bin/bootstrap.jar which is referenced by the classpath, does not exist.
转载地址:http://blog.csdn.net/jnqqls/article/details/8946964 1.错误: 在Eclipse下启动tomcat的时候,报错为:Eclipse下启动to ...
- java比较版本号
java比较版本号,比如1.0.3和1.2.1相比较考虑到可以用String的compareTo()方法,代码如下: public class MainClass { public static vo ...
- Android 网络开发之WIFI
WIFI就是一种无线联网技术,常见的是使用无线路由器.那么在这个无线路由器的信号覆盖的范围内都可以采用WIFI连接的方式进行联网.如果无线路由器连接了一个ADSL线路或其他的联网线路,则又被称为&qu ...
- python 学习笔记二十 django项目bbs论坛
项目:开发一个简单的BBS论坛 需求: 整体参考“抽屉新热榜” + “虎嗅网” 实现不同论坛版块 帖子列表展示 帖子评论数.点赞数展示 在线用户展示 允许登录用户发贴.评论.点赞 允许上传文件 帖子可 ...
- 统计图表类型选择应用总结&表数据挖掘方法及应用
数据挖掘方法及应用: 图表注意事项 • 信息完整:图表标题.单位.图例.脚注.来源等 • 避免无意义的图表 • 一表反映一个观点 • 只选对的不选复杂的图表 • 标题一句话阐述清楚反映观点 确定对比关 ...
- 解决Unity3D导出apk失败:Failed to re-package resources
前几天把系统重装了一下,重新安装Unity3D和Android Studio之后发现过去的文件都不能导出了. 错误信息主要包括: CommandInvokationFailure: Failed to ...
- dir、help查询
#!/usr/bin/env python li = [] print(dir(li)) help(list)
- Canvas的API整理
canvas元素 可被用来通过脚本(通常是JavaScript)绘制图形.比如,它可以被用来绘制图形,制作图片集合,甚至用来实现动画效果.你可以(也应该)在元素标签内写入可提供替代的的代码内容,这些内 ...
- 3d游戏模型及地形提取及导航
支持所有DirectX的游戏模型提取 有需要的可以直接联系我!QQ290387340