详解SQL Server 比较带有尾随空格的字符串--【叶子】_mssql中declare中的字符串带有空格-程序员宅基地

前记:CSDN论坛上多次出现相关问题,总结一下个人对这个问题的看法,欢迎大家共同讨论。

1、问题描述

  1. declare @a varchar(10);set @a='maco '  
  2. declare @b varchar(10);set @b='maco'  
  3. if(@a=@b)  
  4.     select '@a与@b相等'  
  5. else  
  6.     select '@a与@b不相等'  
  7. --运行结果  
  8. /*  
  9. @a与@b相等  
  10. */  

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

 

2、问题解析

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

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

  1. declare @a varchar(10);set @a='maco '  
  2. declare @b varchar(10);set @b='maco'  
  3.   
  4. --第一种方式(两边都加上常量)  
  5. if(@a+'a'=@b+'a')  
  6.     select '@a与@b相等' as 方式一结果  
  7. else   
  8.     select '@a与@b不相等' as 方式一结果  
  1. --第二种方式(替换空格未char(13))  
  2. if(replace(@a,' ',char(13))=replace(@b,' ',char(13)))  
  3.     select '@a与@b相等' as 方式二结果  
  4. else  
  5.     select '@a与@b不相等' as 方式二结果  
  1. --第三种方式(都转成varbinary类型后再比较)  
  2. if(cast(@a as varbinary) = cast(@b as varbinary))  
  3.     select '@a与@b相等' as 方式三结果  
  4. else  
  5.     select '@a与@b不相等' as 方式三结果  
  1. --第四种方式(判断datalength)  
  2. if(@a=@b and datalength(@a)=datalength(@b))  
  3.     select '@a与@b相等' as 方式四结果  
  4. else   
  5.     select '@a与@b不相等' as 方式四结果  
  1. --第五种方式(用like)  
  2. if(@a=@b and @a like @b and @b like @a)  
  3.     select '@a与@b相等' as 方式五结果  
  4. else   
  5.     select '@a与@b不相等' as 方式五结果  
  6.   
  7. --运行结果  
  8. /*  
  9. 方式一结果  
  10. ------------  
  11. @a与@b不相等  
  12.   
  13. (1 row(s) affected)  
  14.   
  15. 方式二结果  
  16. ------------  
  17. @a与@b不相等  
  18.   
  19. (1 row(s) affected)  
  20.   
  21. 方式三结果  
  22. ------------  
  23. @a与@b不相等  
  24.   
  25. (1 row(s) affected)  
  26.   
  27. 方式四结果  
  28. ------------  
  29. @a与@b不相等  
  30.   
  31. (1 row(s) affected)  
  32.   
  33. 方式五结果  
  34. ------------  
  35. @a与@b不相等  
  36.   
  37. (1 row(s) affected)  
  38. */  

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

  1. declare @a varchar(10);set @a='maco '  
  2. declare @b varchar(10);set @b='maco'  
  3. if(@a=@b and len(@a)=len(@b))  
  4.     select '@a与@b相等' as 方式六结果  
  5. else   
  6.     select '@a与@b不相等' as 方式六结果  
  7. /*  
  8. 方式六结果  
  9. ----------  
  10. @a与@b相等  
  11. */  

原因详见下图:

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

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/youfang86402/article/details/41074613

智能推荐

学习Rust的第29天: cat in Rust

否则,假设提供了文件名,并且它将继续读取和打印这些文件的内容,当前将其作为注释保留。函数将命令行参数收集到字符串向量中,删除第一个参数(程序名称本身),然后。方法当前留空,可能会被实现来读取和打印指定文件的内容。方法读取由名称指定的文件的内容并将其作为 a 返回。它首先检查是否没有提供文件名,在这种情况下它调用。它检查是否没有提供文件名,在这种情况下它调用。文件名中是否存在该标志,如果存在,则调用该。文件名中是否存在该标志,如果存在,则调用该。否则,它会迭代每个文件名,使用 读取其内容。

GitHub Copilot Workspace:欢迎进入原生Copilot开发环境

一旦你对计划感到满意,你可以直接在Copilot Workspace中运行你的代码,跳入底层的GitHub Codespace,并调整所有代码更改直到你对最终结果感到满意。在去年GitHub Universe的早期展示后,今天,我们正重新想象开发者体验的本质,推出了GitHub Copilot Workspace的技术预览版:一个原生支持Copilot的开发环境。然后剩下的就是提交你的拉取请求,运行你的GitHub Actions,进行安全代码扫描,并请求你的团队成员进行人工代码审查。而且完全可以编辑……

【微机原理复试面试简答题汇总】_微机原理复试常见问题-程序员宅基地

文章浏览阅读1.2k次,点赞6次,收藏29次。提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档。_微机原理复试常见问题

vue快速入门(五十五)插槽基本用法

注释很详细,直接上代码……

Hbase 的架构详解_hbase架构-程序员宅基地

文章浏览阅读5.6k次,点赞10次,收藏19次。Hbase 作为 NoSQL 数据库的代表,属于三驾马车之一 BigTable 的对应实现,HBase 的出现很好地弥补了大数据快速查询能力的空缺。在前面咱们也有介绍过 HBase 的数据模型,感兴趣的小伙伴可以翻看下。谈谈你对HBase数据模型的认识?HBase 的核心架构由五部分组成,分别是 HBase Client、HMaster、Region Server、ZooKeeper 以及 HDFS。它的架构组成如下图所示。下面我们对 HBase 架构组成的每一部分详细介绍一下。1.HBas_hbase架构

Windows下Java环境配置教程_windows java环境配置-程序员宅基地

文章浏览阅读3.7w次,点赞171次,收藏430次。这篇博客介绍Java环境的配置,主要是安装JDK,以及path、JAVA_hOME、CLASSPAT的配置,还会介绍配置这些的原因。_windows java环境配置

随便推点

WML(Wireless Markup Language - 无线标记语言)_无线标记语言的特点-程序员宅基地

文章浏览阅读583次。WML  WML(Wireless Markup Language - 无线标记语言)。它是一种从 HTML 继承而来的标记语言,但是 WML 基于 XML,因此它较 HTML 更严格。  WML 被用来创建可显示在 WAP 浏览器中的页面。用WML编写的页面被称为 DECKS。DECKS 是作为一套 CARDS 被构造的。  这种描述语言同我们常听说的HTML语言同出一家,都属于XML语言这一大_无线标记语言的特点

23种设计模式(第三章结构型模式7种)_设计模式符合-程序员宅基地

文章浏览阅读307次。结构型模式结构型模式描述如何将类或对象按某种布局组成更大的结构。它分为类结构型模式和对象结构型模式,前者采用继承机制来组织接口和类,后者釆用组合或聚合来组合对象。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象结构型模式比类结构型模式具有更大的灵活性。结构型模式分为以下 7 种:代理模式适配器模式装饰者模式桥接模式外观模式组合模式享元模式5.1 代理模式5.1.1 概述由于某些原因需要给某对象提供一个代理以控制对该对象的访问。这时,访问对象不适合或者不能_设计模式符合

链表中为何使用二级指针_链表初始化为什么要二级指针-程序员宅基地

文章浏览阅读3.6k次,点赞30次,收藏128次。本篇目录前言参数的调用方式传值调用传址调用传引用调用示例说明使用二级指针/一级指针创建链表时的对比主函数中作此调用使用二级指针创建链表使用一级指针创建链表会成功吗销毁链表时二级指针和一级指针的对比使用二级指针销毁链表使用一级指针销毁链表会成功吗总结完整代码参考来源前言在学习数据结构时,在链表初始化或者销毁链表的时候,经常使用二级指针或者一级指针的引用,这是为什么呢?同样是指向内存单元的地址,为什么就不能使用一级指针呢?使用一级指针去初始化或者是销毁链表的时候,究竟会发生什么呢?到底什么时候该用二级指针,_链表初始化为什么要二级指针

win10通过pycharm远程登录到Linux服务器,并通过matplotlib作图_pycharm连接服务绘图-程序员宅基地

文章浏览阅读3.6k次,点赞9次,收藏24次。准备工作:1.下载专业版本的Pycharm。这里为大家提供18版本的链接: https://pan.baidu.com/s/1-GYSJvUx9JoUujPfu3EPwA密码: p283 或者直接去官网下载: https://www.jetbrains.com/pycharm/download/download-thanks.html?platform=windows2.安装并..._pycharm连接服务绘图

更改 MATLAB 当前文件夹 或 将其文件夹添加到 MATLAB 路径。出错_manually add this path to the matlab path-程序员宅基地

文章浏览阅读8.7k次。更改 MATLAB 当前文件夹 或 将其文件夹添加到 MATLAB 路径。出错_manually add this path to the matlab path

iOS之UIView动画_oc uiview animate 关键帧-程序员宅基地

文章浏览阅读5.5k次。在AppStore中的应用越来越重视动画效果的使用,一个良好动画效果可以让两个状态之间平滑地过度,也可以利用动画吸引住用户的眼球_oc uiview animate 关键帧