首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场

TSQL级联
EN

Stack Overflow用户
提问于 2011-08-24 18:57:00
回答 4查看 27.4K关注 0票数 5

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

TSQL迫使您在使用“+”运算符时必须处理的两个问题是数据类型优先和NULL值。

对于数据类型优先,问题是转换错误。

代码语言:javascript
运行
复制
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())会工作。

当您处理表字段时,当您不知道数据类型时,转换就变成了工作密集型。这样做可能会奏效:

代码语言:javascript
运行
复制
SELECT 'Fall '  + ' (' + [Term] + ')' -- Output: Fall (2011)

但话又说回来,情况可能并非如此。这取决于什么是数据类型的术语。更复杂的是,dba可能会在某个时候不告诉任何人就更改数据包(因为一旦供应商最终意识到术语字段中只存储了数字或其他原因,它就作为一个大型升级包的一部分出现了)。

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

代码语言:javascript
运行
复制
SELECT 'Fall '  + ' (' + LTRIM([Term]) + ')'

所以现在我每次都运行这个LTRIM函数,尽管它可能不是必要的,因为我不知道术语的数据类型,而且我也不知道数据类型永远不会改变。

TSQL连接必须面对的第二个问题是如何处理空值。例如,这将失败:

代码语言:javascript
运行
复制
SELECT NULL + 'B'

所以你需要这样做:

代码语言:javascript
运行
复制
SELECT 'Fall '  + ' (' + LTRIM(ISNULL([Term],'')) + ')'

太痛苦了-我真希望我能这么做:

代码语言:javascript
运行
复制
SELECT 'Fall '  + ' (' + [Term] + ')'

因此,我想知道是否有任何(TSQL)方法可以避免对每个字段进行显式的数据类型转换和空检查,在这些字段中,我必须确保'+‘操作符按照我的需要运行。

谢谢!

编辑

@a1ex07为解决空问题(SET CONCAT_NULL_YEILDS_NULL OFF)提供了一个很好的解决方案,但在我研究它时,它似乎存在问题,以至于每次执行存储过程时都强制它们重新编译。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-08-25 01:20:54

对此,2005年或2008年没有答案。没有显式转换和空检查的级联是不可能的。

看起来下一个版本的Server将有一个CONCAT函数(谢谢@Martin),听起来就像我想要的一样。但缺点是,我的机构可能至少要过几年才会决定升级到那个版本,因为他们很不愿意成为早期的采用者,尤其是在微软。

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

票数 0
EN

Stack Overflow用户

发布于 2011-08-25 09:12:58

Server 2012确实具有CONCAT函数,它解决了您提出的所有问题。

这里SQL威胁提供了一个很好的功能总结。

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

票数 8
EN

Stack Overflow用户

发布于 2011-08-24 19:00:15

更新

可以使用指定NULL + 'txt'结果是否为NULL。Microsft说,CONCAT_NULL_YIELDS_NULL不会在Server的进一步版本中工作,但是仍然有一个通过dboption过程设置它的选项。但是,正如您在问题中提到的那样,最好使用ISNULL

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7180789

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档