请看代码:

DECLARE @max VARCHAR(max)
SET @max='aaa...' --这里有8000个a
+'bb' --连接一个varchar常量或变量 SELECT LEN(@max)

别想当然以为它会返回8002,而是8000,select @max也只会得到8000个a,后面两个b没了。我们知道,varchar(max)类型不受字符数限制,但为什么会这样?

这其实与@max的数据类型无关,而是与字符串拼接后得到的数据类型有关,或者说,与字符串常量的数据类型推断有关。在SQL 2005和SQL 2008(R2)中,敲一个'a',系统会把它作为varchar(1),'aa'则是varchar(2),N'a'则是nvarchar(1),而'a...'(超过8000个a)呢,05中会当它是text,08则当它是varchar(max),常量或变量的数据类型可以通过系统函数SQL_VARIANT_PROPERTY获取,使用示例:

SELECT SQL_VARIANT_PROPERTY('a','BaseType')

有关该函数的更多信息请参看SSMS帮助或http://technet.microsoft.com/zh-cn/library/ms178550(v=sql.105).aspx

那么问题来了,既然超过8000个字符的常量系统会自动识别为大数据类型,不会出现截断,为什么拼接一下就歇菜了,这是因为varchar(n)+varchar(n)还是=varchar(n),拼接时系统会自动拓展数据长度,但不会更改数据类型(varchar(n)与varchar(max)应视为不同数据类型),又因为varchar(n)中的n最大取值为8000,所以varchar(x)+varchar(y)最大只会得到varchar(8000),当x+y>8000时,便会出现截断。

回到文章开头的例子,就很明了了,'aaa...'和'bb'都是varchar(n),拼接后得到varchar(8000),也就是截断了的8000个'aaa...',所以即便把它赋值给varchar(max)也无济于事。如果'aaa...'再多个a,情况又不同了,这时就是text或varchar(max)+varchar(n),对于05,会报text与varchar不能拼接,对于08,会正确得到无截断的'aaa...bb',因为varchar(max)+varchar(n)=varchar(max)。

OK就到这里,希望猿友在拼接SQL字串时留意这个问题。

【SQL】小心字符串拼接导致长度爆表的更多相关文章

  1. SQL Server 字符串拼接、读取

    一.查询结果使用,字符串拼接 declare @names nvarchar(1000) declare @ParmDefinition nvarchar(1000) declare @sqltext ...

  2. SQL中字符串拼接

    1. 概述 在SQL语句中经常需要进行字符串拼接,以sqlserver,oracle,mysql三种数据库为例,因为这三种数据库具有代表性. sqlserver: select '123'+'456' ...

  3. python 防止sql注入字符串拼接的正确用法

    在使用pymysql模块时,在使用字符串拼接的注意事项错误用法1 sql='select * from where id="%d" and name="%s" ...

  4. sqlserver 字符串拼接及拆开联表查询的问题

    一.sql根据一个以逗号隔开的人员guid类型的ID字符串查出其对应的姓名同样拼接成逗号隔开的字符串: 1.需求:管理员发送通知(通知分为普通通知,奖品订单,调查问卷三种类型)给用户,并且可以查看统计 ...

  5. Delphi SQL语句字符串拼接

    单引号必须成对出现,最外层的单引号表示其内部符号为字符:除最外层以外的单引号,每两个单引号代表一个'字符.加号:+用于字符串之间的连接.字符串常量用四个单引号,例如 ' select * from T ...

  6. SQL Server 字符串拼接与拆分 string varchar Split and Join

    1.Split    SQL Server 2008 新语法: DECLARE @str VARCHAR(MAX) SET @str = REPLACE(@teeIDs, ',', '''),(''' ...

  7. SQL Where 字符串拼接

    ) set @s='1,2,3' --法一: --法二: exec('select * from tb where id in ('+@s+')')

  8. linux环境java程序cpu爆表问题查证

    1.top命令查找导致cup爆表的进程 2. top -H -p10832 (10832是Java进程的PID)命令找出了具体的线程 3.使用用命令 jstack 10832> jstack.t ...

  9. 解决存储过程中拼接的SQL字符串超长导致sql语句被截取的问题

    今天遇到了一个奇葩的问题:存储过程中的sql字符串拼接的太长,超出了分页存储过程执行sql参数的nvarchar(4000)的长度. 没办法,只能修改自己的存储过程,因为分页存储过程是不能动的. 开始 ...

随机推荐

  1. MVVM架构~knockoutjs系列之文本框数符长度动态统计功能

    返回目录 这个功能为什么要写呢,因为在之前做了一个前端的页面效果,使用JS写的,感觉很累,真的,对于一个文本框长度动态统计,你要写blur,press,down什么的事件,太麻烦了,这时,我想到了kn ...

  2. 谷歌大牛 Rob Pike 的 5 个编程原则

    谷歌大牛 Rob Pike 的 5 个编程原则 简介: Rob Pike,目前谷歌公司最著名的软件工程师之一,曾是贝尔实验室Unix开发团队成员,Plan9操作系统开发的主要领导人,Inferno操作 ...

  3. Atitit atiuse软件系列

    Atitit atiuse软件系列 1.1.  Atian inputmethod 输入法 方言与多语言多文字支持 (au)1 1.2. File searcher 文件搜索器,支持压缩文件与正则表达 ...

  4. angularjs学习曲线

    angularjs学习曲线 刚开始学Augular觉得开发应用需要有相当的编程基础. 不得不说这确实是一款了不起的开发框架,它要求开发人员设计低耦合和可维护的应用. 使用AngularJS 的复杂度就 ...

  5. vuejs学习网站推荐

    vuejs学习网站推荐 https://coligo.io/

  6. eclipse导入cordova创建的项目

    eclipse导入cordova创建的项目 看图不说话 run这个MainActivity就可以了,bin目录下会生成APK

  7. Android Studio下载及使用教程(转载)

    (一)下载及相关问题解决: Android Studio 下载地址,目前最新可下载地址,尽量使用下载工具. Android Studio正式发布,给Android开发者带来了不小的惊喜.但是下载地址却 ...

  8. 你的 mixin 兼容 ECMAScript 5 吗

    原文:Are your mixins ECMAScript 5 compatible? 作者:Nicholas C. Zakas 我最近在与客户合作的项目中,需要充分利用的 ECMAScript 5, ...

  9. How to select Multiple images from UIImagePickerController [duplicate]

    accepted You have to use custom imagepicker. And I think ELCImagePickerController is the best option ...

  10. 深入理解PHP内核(七)变量及数据类型-常量

    原文链接:http://www.orlion.ga/246/ 在PHP中,常量的名字是一个简单值的标识符,在脚本执行期间该值不能改变.和变量一样,常量默认为大小写敏感,但是通常是大写的. 常量是在变量 ...