设为首页 收藏本站
查看: 1163|回复: 0

[经验分享] 详解SQL Server 比较带有尾随空格的字符串--【叶子】

[复制链接]

尚未签到

发表于 2016-11-8 07:49:26 | 显示全部楼层 |阅读模式
  前记:CSDN论坛上多次出现相关问题,总结一下个人对这个问题的看法,欢迎大家共同讨论。
  1、问题描述
declare @a varchar(10);set @a='maco 'declare @b varchar(10);set @b='maco'if(@a=@b)select '@a与@b相等'elseselect '@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 方式二结果elseselect '@a与@b不相等' as 方式二结果--第三种方式(都转成varbinary类型后再比较)if(cast(@a as varbinary) = cast(@b as varbinary))select '@a与@b相等' as 方式三结果elseselect '@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相等*/  原因详见下图:
DSC0000.jpg

  © 【叶子】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。
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-297095-1-1.html 上篇帖子: SQL Server 数据挖掘系列(一) 下篇帖子: SQL Server 按某一字段分组取最大(小)值所在行的数据
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表