TSQL 连接

标签 tsql concatenation

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

使用“+”运算符时 TSQL 强制您处理的两个问题是 Data Type Precedence和 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 (IMO) 阻碍的地方。本质上,它更喜欢数学函数而不是字符串函数。我希望 :-) 在这种情况下 DTP 甚至不是一个考虑因素——为什么不配置“+”运算符以便操作可以有利于特定数据类型的成功?如果可能的话,我不介意它是否仍然偏爱 MATH 而不是字符串函数——但为什么它不偏爱字符串函数而不是错误? (在 1) 中取得成功的唯一方法是将其视为字符串函数——所以它不像那里有任何歧义。)微软有人认为在 1) 中抛出错误对程序员来说比处理更有值(value)'+' 作为字符串函数。为什么?为什么他们不提供覆盖它的方法? (或者他们......这真的是我问题的核心。)SET STRING_PREFERENCE ON本来不错! :-P

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

当您在不知道数据类型的情况下处理表字段时,转换会变得非常繁重。这可能有效:
SELECT 'Fall '  + ' (' + [Term] + ')' -- Output: Fall (2011)

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

所以如果你想成为一个男孩,你可以这样做:
SELECT 'Fall '  + ' (' + LTRIM([Term]) + ')'

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

处理 TSQL 连接时必须面对的第二个问题是如何处理 NULL 值。例如,这将失败:
SELECT NULL + 'B'

所以你需要这样做:
SELECT 'Fall '  + ' (' + LTRIM(ISNULL([Term],'')) + ')'

多么痛苦——我希望我能做到这一点:
SELECT 'Fall '  + ' (' + [Term] + ')'

所以我想知道是否有任何(TSQL)方法可以避免对每个字段进行显式数据类型转换和空检查,我必须确保“+”运算符按照我的需要运行。

谢谢!

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

最佳答案

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

提供了一个很好的功能总结 here来自 SQL Menace

CONCAT takes a variable number of string arguments and concatenates them into a single string. It requires a minimum of two input values; otherwise, an error is raised. All arguments are implicitly converted to string types and then concatenated. Null values are implicitly converted to an empty string. If all the arguments are null, then an empty string of type varchar(1) is returned. The implicit conversion to strings follows the existing rules for data type conversions

关于TSQL 连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7180789/

相关文章:

list - Scala 中列表串联(:::)的复杂性?

sql-server - Linq to SQL 性能与分组

r - 如何在R中连接两个数组

java - 如何在 Java 中连接两个数组?

python - 使用 pandas 创建多索引

javascript - 通过在 JavaScript 中连接 2 个字符串来设置 'calc()' 值不起作用

sql - 在 SQL 中创建不同长度的序列

sql - 如果 SQL 中的值重复,如何使 select 语句返回 "NULLs"

tsql - 将相邻、重叠和嵌入的范围合并为互斥范围

sql-server - Transact SQL 如何在毕业变化(促销)时标记 person_id