TSQL连接

Cha*_*ins 5 t-sql concatenation

我经常需要在TSQL中连接字段...

使用'+'运算符时,TSQL强制要求您处理的两个问题是数据类型优先级和NULL值.

使用数据类型优先级,问题是转换错误.

1) SELECT 1 + 'B' = Conversion ERROR
2) SELECT 1 + '1' = 2
3) SELECT '1' + '1' = '11'
Run Code Online (Sandbox Code Playgroud)

在2)中,varchar'1'被隐式转换为int,并且数学运算.但是,在1)中,int 1不会隐式转换为varchar.这就是DTP(IMO)阻碍的方向.从本质上讲,它有利于数学函数而不是字符串函数. 我希望 :-)在这种情况下DTP甚至不是一个考虑因素 - 为什么不配置'+'运算符以便操作可以优先于特定数据类型的成功?我不介意它是否仍然支持MATH而不是字符串函数 - 但为什么它不支持字符串函数而不是错误?(在1中取得成功的唯一方法)是将其视为一个字符串函数 - 所以它不像那里有任何歧义.)微软有人认为在1)中抛出错误对于程序员来说比对待更有价值'+'作为字符串函数.为什么?为什么他们没有提供覆盖它的方法呢?(或者他们......这真的是我问题的核心.) SET STRING_PREFERENCE ON本来不错!:-P

为了解决这个问题,你必须做更多的工作 - 你必须使用任意数量的不同字符串函数显式地将1转换为varchar - 通常是CAST/CONVERT,还有许多其他函数(如LTRIM())将工作.

当您不知道数据类型时处理表字段时,转换会变得工作密集.这可能有效:

SELECT 'Fall '  + ' (' + [Term] + ')' -- Output: Fall (2011)
Run Code Online (Sandbox Code Playgroud)

但话说回来,它可能不会.它只取决于[Term]的数据类型.更复杂的是,dba可能会在某个时刻更改dataype而不告诉任何人(因为一旦供应商最终意识到[Term]字段中只存储了数字,或者无论什么原因,它都会作为大型升级包的一部分出现) ).

所以,如果你想成为一个男生,你可以这样做:

SELECT 'Fall '  + ' (' + LTRIM([Term]) + ')'
Run Code Online (Sandbox Code Playgroud)

所以现在我每次都运行这个LTRIM函数,即使它可能没有必要,因为我不知道[Term]的数据类型(好的 - 我可以看一下,但这几乎就像工作,当我编码时,我不喜欢中断:-P*grump),而且,我不知道数据类型永远不会改变.

您必须面对TSQL连接的第二个问题是如何处理NULL值.例如,这会失败:

SELECT NULL + 'B'
Run Code Online (Sandbox Code Playgroud)

所以你需要这样做:

SELECT 'Fall '  + ' (' + LTRIM(ISNULL([Term],'')) + ')'
Run Code Online (Sandbox Code Playgroud)

多么痛苦 - 我希望我能做到这一点:

SELECT 'Fall '  + ' (' + [Term] + ')'
Run Code Online (Sandbox Code Playgroud)

所以我想知道是否有任何(TSQL)方法可以避免必须对每个字段进行显式数据类型转换和空检查,我必须确保'+'运算符在我需要的时候表现自己.

谢谢!

编辑
@ a1ex07为解决NULL问题(SET CONCAT_NULL_YEILDS_NULL OFF)提出了一个很好的答案,但是当我调查它时,就强制存储过程每次执行时重新编译而言似乎都有问题.

Mar*_*ith 8

SQL Server 2012确实具有CONCAT解决您提出的所有问题的功能.

的功能的一个很好的总结提供在这里通过SQL威胁

CONCAT采用可变数量的字符串参数并将它们连接成一个字符串.它至少需要两个输入值; 否则,会引发错误.所有参数都隐式转换为字符串类型,然后连接.空值隐式转换为空字符串.如果所有参数都为null,则返回varchar(1)类型的空字符串.隐式转换为字符串遵循现有的数据类型转换规则


Cha*_*ins 0

2005 年或 2008 年没有对此问题的答案。没有显式转换和空检查的串联根本不可能。

看起来 SQL-Server 的下一个版本将有一个 CONCAT 函数(感谢@Martin),这听起来正是我正在寻找的。但缺点是,我的机构可能至少要过几年才能决定升级到该版本,因为他们对于成为早期采用者非常害羞,尤其是在微软方面。

现在有一个 NULL 检查的快捷方式(CONCAT_NULL_YIELDS_NULL - 感谢@a1ex07),但是,使用它会带来相当大的惩罚(每次执行时都会重新编译该过程),更不用说微软不打算这样做在 SQL-Server 的未来版本中支持它。