我经常需要连接TSQL中的字段.
TSQL迫使您在使用“+”运算符时必须处理的两个问题是数据类型优先和NULL值。
对于数据类型优先,问题是转换错误。
1) SELECT 1 + 'B' = Conversion ERROR
2) SELECT 1 + '1' = 2
3) SELECT '1' + '1' = '11'在2)中,varchar '1‘被隐式转换为int,并且数学工作。但是,在1中,int 1不是隐式转换为varchar的。这就是DTP (国际海事组织)所遇到的阻碍。本质上,它更倾向于数学函数而不是字符串函数。我希望:-)在这种情况下,DTP甚至不是一个考虑因素--为什么'+‘运算符不被配置成比特定的数据类型更有利于成功的操作?如果可能的话,我不介意它仍然偏爱数学而不是字符串函数--但是为什么它不喜欢字符串函数而不是错误呢?(要想在1中取得成功,唯一的方法就是把它当作一个字符串函数来处理--因此,这里不存在任何歧义。)微软的一些人认为,在1中抛出一个错误对程序员来说比把'+‘当作一个字符串函数更有价值。为什么?为什么他们不提供一种方法来推翻它呢?(或者他们.这才是我问题的核心) SET STRING_PREFERENCE ON会很好的!
为了解决这个问题,您必须做更多的工作--您必须使用任意数量的不同字符串函数显式地将1转换为varchar --通常是强制转换/转换,但也有许多其他函数(如LTRIM())会工作。
当您处理表字段时,当您不知道数据类型时,转换就变成了工作密集型。这样做可能会奏效:
SELECT 'Fall ' + ' (' + [Term] + ')' -- Output: Fall (2011)但话又说回来,情况可能并非如此。这取决于什么是数据类型的术语。更复杂的是,dba可能会在某个时候不告诉任何人就更改数据包(因为一旦供应商最终意识到术语字段中只存储了数字或其他原因,它就作为一个大型升级包的一部分出现了)。
所以,如果你想成为一个男孩伯爵,你可以这样做:
SELECT 'Fall ' + ' (' + LTRIM([Term]) + ')'所以现在我每次都运行这个LTRIM函数,尽管它可能不是必要的,因为我不知道术语的数据类型,而且我也不知道数据类型永远不会改变。
TSQL连接必须面对的第二个问题是如何处理空值。例如,这将失败:
SELECT NULL + 'B'所以你需要这样做:
SELECT 'Fall ' + ' (' + LTRIM(ISNULL([Term],'')) + ')'太痛苦了-我真希望我能这么做:
SELECT 'Fall ' + ' (' + [Term] + ')'因此,我想知道是否有任何(TSQL)方法可以避免对每个字段进行显式的数据类型转换和空检查,在这些字段中,我必须确保'+‘操作符按照我的需要运行。
谢谢!
编辑
@a1ex07为解决空问题(SET CONCAT_NULL_YEILDS_NULL OFF)提供了一个很好的解决方案,但在我研究它时,它似乎存在问题,以至于每次执行存储过程时都强制它们重新编译。
发布于 2011-08-25 01:20:54
对此,2005年或2008年没有答案。没有显式转换和空检查的级联是不可能的。
看起来下一个版本的Server将有一个CONCAT函数(谢谢@Martin),听起来就像我想要的一样。但缺点是,我的机构可能至少要过几年才会决定升级到那个版本,因为他们很不愿意成为早期的采用者,尤其是在微软。
现在有一个空检查的快捷方式(CONCAT_NULL_YIELDS_NULL --谢谢@a1ex07),但是使用它会带来相当大的损失(每次执行过程都会重新编译),更不用说微软不打算在Server的未来版本中支持它了。
发布于 2011-08-25 09:12:58
Server 2012确实具有CONCAT函数,它解决了您提出的所有问题。
这里由SQL威胁提供了一个很好的功能总结。
CONCAT接受可变数目的字符串参数,并将它们连接到一个字符串中。它至少需要两个输入值,否则会引发错误。所有参数都隐式转换为字符串类型,然后连接。空值隐式转换为空字符串。如果所有参数都为null,则返回一个类型为varchar(1)的空字符串。隐式字符串转换遵循数据类型转换的现有规则。
发布于 2011-08-24 19:00:15
更新
可以使用空指定NULL + 'txt'结果是否为NULL。Microsft说,CONCAT_NULL_YIELDS_NULL不会在Server的进一步版本中工作,但是仍然有一个通过dboption过程设置它的选项。但是,正如您在问题中提到的那样,最好使用ISNULL。
https://stackoverflow.com/questions/7180789
复制相似问题