文档章节

详解SQL Server 比较带有尾随空格的字符串

吖唛喋
 吖唛喋
发布于 2015/04/30 15:30
字数 1091
阅读 38
收藏 0

1、问题描述

declare @a varchar(10);set @a='maco '  
declare @b varchar(10);set @b='maco'  
if(@a=@b)  
    select '@a与@b相等'  
else  
    select '@a与@b不相等'  
--运行结果  
/*  
@a与@b相等  
*/  

@a后面有尾随空格,@b后面没有,但是为什么他们相等呢?

2、问题解析

2.1 有尾随空格的情况下,如何才能准确的比较两个字符串?

下面介绍几种常见的方式:

declare @a varchar(10);set @a='maco '  
declare @b varchar(10);set @b='maco'  
  
--第一种方式(两边都加上常量)  
if(@a+'a'=@b+'a')  
    select '@a与@b相等' as 方式一结果  
else   
    select '@a与@b不相等' as 方式一结果  


--第二种方式(替换空格未char(13))  
if(replace(@a,' ',char(13))=replace(@b,' ',char(13)))  
    select '@a与@b相等' as 方式二结果  
else  
    select '@a与@b不相等' as 方式二结果  


--第三种方式(都转成varbinary类型后再比较)  
if(cast(@a as varbinary) = cast(@b as varbinary))  
    select '@a与@b相等' as 方式三结果  
else  
    select '@a与@b不相等' as 方式三结果  


--第四种方式(判断datalength)  
if(@a=@b and datalength(@a)=datalength(@b))  
    select '@a与@b相等' as 方式四结果  
else   
    select '@a与@b不相等' as 方式四结果  


--第五种方式(用like)  
if(@a=@b and @a like @b and @b like @a)  
    select '@a与@b相等' as 方式五结果  
else   
    select '@a与@b不相等' as 方式五结果  
  
--运行结果  
/*  
方式一结果  
------------  
@a与@b不相等  
  
(1 row(s) affected)  
  
方式二结果  
------------  
@a与@b不相等  
  
(1 row(s) affected)  
  
方式三结果  
------------  
@a与@b不相等  
  
(1 row(s) affected)  
  
方式四结果  
------------  
@a与@b不相等  
  
(1 row(s) affected)  
  
方式五结果  
------------  
@a与@b不相等  
  
(1 row(s) affected)  
*/  

这里特别要说明的是用len判断是不行的。

declare @a varchar(10);set @a='maco '  
declare @b varchar(10);set @b='maco'  
if(@a=@b and len(@a)=len(@b))  
    select '@a与@b相等' as 方式六结果  
else   
    select '@a与@b不相等' as 方式六结果  
/*  
方式六结果  
----------  
@a与@b相等  
*/  

原因详见下图:

© 【叶子】http://blog.csdn.net/maco_wang 原创作品,转贴请注明作者和出处,留此信息。

2.2 为什么会出现这个问题,是尾随空格不参与比较吗?

个人认为不是这样的。

微软的帮助中曾经提到:ANSI 标准要求填充字符的字符串比较中使用,以使其长度匹配再进行比较。进行填充时,char 列用空格填充,binary 列用零填充。

LIKE 谓词表达式的右侧功能具有尾随空格的值时, SQL Server 不会填充到相同的长度在两个值比较发生之前。(上面的方式五,只是用like做个测试)

3、补充说明

说到尾随空格,不得不提到SET ANSI_PADDING

在 Microsoft SQL Server 的未来版本中,ANSI_PADDING 将始终为 ON,将该选项显式设置为 OFF 的任何应用程序都将产生错误。 请避免在新的开发工作中使用该功能,并着手修改当前还在使用该功能的应用程序。

SET ANSI_PADDING:对列存储长度小于列的定义大小的值以及在 char、varchar、binary 和 varbinary 数据中含有尾随空格的值的方式进行控制。

SET ANSI_PADDING虽然在比较的时候不起作用,但是它直接控制了入口,如果设置了off,则剪裁插入 varchar 列中的字符值的尾随空格。

详见:

设置

char(n) NOT NULL 或 binary(n) NOT NULL

char(n) NULL 或 binary(n) NULL

varchar(n) 或 varbinary(n)

ON

填充原始值(char 列具有尾随空格的值,binary 列具有尾随零的值),使达到列的长度。

如果 SET ANSI_PADDING 为 ON,则遵从与 char(n) 或 binary(n) NOT NULL 相同的规则。

不剪裁插入 varchar 列中的字符值的尾随空格。 不剪裁插入 varbinary 列中的二进制值的尾随零。 不将值填充到列的长度。

OFF

填充原始值(char 列具有尾随空格的值,binary 列具有尾随零的值),使达到列的长度。

如果 SET ANSI_PADDING 为 OFF,则遵从与 varchar 或 varbinary 相同的规则。

剪裁插入 varchar 列中的字符值的尾随空格。 剪裁插入 varbinary 列中的二进制值的尾随零。

注:建议始终将 ANSI_PADDING 设置为 ON。

本文转载自:http://blog.csdn.net/maco_wang/article/details/7016630

共有 人打赏支持
吖唛喋
粉丝 0
博文 2
码字总数 0
作品 0
襄阳
程序员
私信 提问
3.《SQLSERVER2012之T-SQL教程》T-SQL单表查询(三)

表结构与数据:https://github.com/XuePeng87/TSQLV4 使用字符数据 设计字符数据的查询操作,包括数据类型、排序规则、运算符和函数,以及模式匹配。 数据类型 SQL Server支持两种字符数据类...

巧乐兹
2016/10/25
10
0
《SQLSERVER2012之T-SQL教程》T-SQL单表查询(三)

表结构与数据:https://github.com/XuePeng87/TSQLV4 使用字符数据 设计字符数据的查询操作,包括数据类型、排序规则、运算符和函数,以及模式匹配。 数据类型 SQL Server支持两种字符数据类...

杰克鹏仔
2016/11/09
6
0
SQL Server 字符串处理函数

ASCII:返回字符表达式中最左侧的字符的 ASCII 代码值。 select ASCII(expression) CHAR:将 int ASCII 代码转换为字符。 CHAR 可用于将控制字符插入字符串中 制表符 char(9) 换行符 char(10)...

子曰疯
2014/01/13
0
0
EntityFramework之原始查询及性能优化(六)

前言 在EF中我们可以通过Linq来操作实体类,但是有些时候我们必须通过原始sql语句或者存储过程来进行查询数据库,所以我们可以通过EF Code First来实现,但是SQL语句和存储过程无法进行映射,...

SourceBird
2015/09/02
455
0
Adminer 4.7.0 正式发布,MySQL 管理客户端

Adminer 4.7.0 发布了,Adminer是一个类似于phpMyAdmin的MySQL管理客户端。整个程序只有一个PHP文件,易于使用和安装。Adminer支持多语言(已自 带11种翻译语言文件,可以按自己的需求翻译相...

达尔文
2018/11/25
1K
0

没有更多内容

加载失败,请刷新页面

加载更多

详解webpack-dev-server的简单使用

webpack-dev-server是一个小型的Node.js Express服务器,它使用webpack-dev-middleware来服务于webpack的包,除此自外,它还有一个通过Sock.js来连接到服务器的微型运行时. 我们来看一下下面的...

前端攻城老湿
25分钟前
0
0
深度解析JavaScript事件对象

这篇文章主要介绍了JavaScript事件对象,结合实例形式深入分析了javascript DOM、IE及其他浏览器相关事件对象操作技巧与注意事项,写的十分的全面细致,具有一定的参考价值,对此有需要的朋友可...

前端攻城小牛
26分钟前
1
0
Android下拉刷新开源框架

添加依赖 //下拉刷新 implementation 'com.jcodecraeer:xrecyclerview:1.5.9' xml引用 <com.jcodecraeer.xrecyclerview.XRecyclerView android:id="@+id/act_xrecycler......

lanyu96
33分钟前
1
0
Linux内核中ioremap映射的透彻理解

几乎每一种外设都是通过读写设备上的寄存器来进行的,通常包括控制寄存器、状态寄存器和数据寄存器三大类,外设的寄存器通常被连续地编址。根据CPU体系结构的不同,CPU对IO端口的编址方式有两...

天王盖地虎626
37分钟前
2
0
Collection中的之retainAll()方法的理解

//在jdkapi中的方法,说明返回值为boolean类型, boolean retainAll(Collection<?> c) ; //api中给的注释 //Retains only the elements in this list that are contained in the specified......

南桥北木
40分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部