【问题标题】:Using SELECT statement to assign variable使用 SELECT 语句分配变量
【发布时间】:2013-05-07 08:35:14
【问题描述】:

你能解释一下这个奇怪的行为吗?

DECLARE @t VARCHAR(256) = ''

SELECT @t = @t + CAST(smb.symbol AS VARCHAR(256))
FROM (
    SELECT 1,'7'
    UNION ALL
    SELECT 2,'8'
    UNION all
    SELECT 3,'9'
) AS smb(n, symbol)
ORDER BY n

SELECT @t

输出:

789

对我来说没问题。

DECLARE @t VARCHAR(256) = ''

SELECT @t = @t + CAST(smb.symbol AS VARCHAR(256))
FROM (
    SELECT NUMS.N-1 AS N, CHAR(N-1) AS symbol
    FROM (
        SELECT 1 + n.n1 + nn.n2 * 10 + nnn.n3 * 100 as N
        FROM (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) AS n(n1)
            CROSS JOIN (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) AS nn(n2)
            CROSS JOIN (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) AS nnn(n3)
    ) AS NUMS
    WHERE NUMS.N BETWEEN 56 AND 58
) AS smb(N, symbol)
ORDER BY smb.N

SELECT @t

输出:

9

那么为什么第二个例子只输出最后一个符号呢?

【问题讨论】:

  • 您依赖于无证和无保证的行为。这种连接方法并不总是有效。 nvarchar concatenation / index / nvarchar(max) inexplicable behavior 的可能重复项
  • 想看一些有趣的东西吗?从您的第二个查询中删除 ORDER BY ,它也会返回 789 :)。 +1 可执行问题。
  • 你应该使用 FOR XML PATH('')
  • 感谢大家!对我来说,最好的做法是避免无证行为。

标签: sql-server tsql string-concatenation


【解决方案1】:

在使用多行变量赋值时不要依赖 order by。

例如试试这个:

DECLARE @c INT = 0

SELECT
 @c = @c + x
FROM (VALUES(1),(2),(3)) AS src(x)
WHERE x BETWEEN 1 AND 3 
ORDER BY 1 - x DESC

SELECT @c

SET @c = 0

SELECT
 @c = @c + x
FROM (VALUES(1),(2),(3)) AS src(x)
WHERE x BETWEEN 1 AND 3 
ORDER BY x DESC

SELECT @c

http://sqlmag.com/sql-server/multi-row-variable-assignment-and-order

【讨论】:

猜你喜欢
  • 2011-09-09
  • 2014-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多