tempn表上的isnull与原始表上的isnull有什么区别?

时间:2011-03-07 11:55:15

标签: sql tsql sql-server-2008

我正在使用SQL将字符串连接在一起。

此声明有效:

DECLARE @FirstNamesString nvarchar(256)
SELECT
    @FirstNamesString = COALESCE(@FirstNamesString + ', ', '') + p.FirstName 
FROM 
    Person p
ORDER BY
    p.SortOrder

我得到的名字列表如下:

Name1, Name2, Name3

现在我想为每个人添加一个可能为空的姓氏字段。我尝试了下面的sql,但我只得到列表中的最后一项(Name3):

DECLARE @FirstNamesString nvarchar(256)
SELECT @FirstNamesString = COALESCE(@FirstNamesString + ', ', '') + p.FirstName + ISNULL(' ' + p.LastName, '') 
FROM 
    Person p
ORDER BY
    p.SortOrder

但是,如果我首先将所有这些名称插入到临时表中,那么一切都按预期工作:

CREATE TABLE #Person2
(
     FirstName nvarchar(128) NOT NULL
    ,LastName nvarchar(256) NULL
    ,SortOrder int NOT NULL
)

INSERT INTO #Person2 (FirstName, LastName, SortOrder) (
    SELECT p.FirstName, p.LastName, p.SortOrder FROM Person p)

DECLARE @FirstNamesString nvarchar(256)

SELECT @FirstNamesString = COALESCE(@FirstNamesString + ', ', '') + p.FirstName + ISNULL(' ' + p.LastName, '') 
FROM 
    #Person2 p
ORDER BY
    p.SortOrder

DROP TABLE #Person2

那么上面的语句与原始表和temp表之间的区别是什么?临时表路线工作,我将使用它,但我很好奇...我在这里缺少什么?

以可能的解决方案更新

请参阅@Martin's answer,但不保证字符串的串联起作用。因此,解决方案是在选择名字列表之前首先将姓氏插入临时表:

CREATE TABLE #Person2
(
     FirstName nvarchar(256) NOT NULL
    ,SortOrder int NOT NULL
)

INSERT INTO #Person2 (FirstName, SortOrder) (
    SELECT p.FirstName + ISNULL(' ' + p.LastName, ''), p.SortOrder
    FROM Person p

)

DECLARE @FirstNamesString nvarchar(256)

SELECT
    @FirstNamesString = COALESCE(@FirstNamesString + ', ', '') + p.FirstName  
FROM 
    #Person2 p
ORDER BY
    p.SortOrder ASC

2 个答案:

答案 0 :(得分:3)

这种连接字符串的方法并不能保证工作。微软称"The correct behavior for an aggregate concatenation query is undefined."。如果计算标量最终出现在计划中的错误位置,它将失败。你能同时展示这两个计划吗?

您当然可以/应该使用XML PATH来连接字符串,就像在SQL Server 2008上一样,这是记录的工作。在当前版本中可靠。

示例:

DECLARE @FirstNamesString nvarchar(256) 

SELECT @FirstNamesString = (
SELECT CASE
         WHEN ROW_NUMBER() OVER (ORDER BY (p.SortOrder)) = 1 THEN ''
         ELSE ','
       END + p.FirstName + ISNULL(' ' + p.LastName, '')
FROM   Person p
ORDER  BY p.SortOrder
FOR XML PATH(''), TYPE  

).value('.[1]','nvarchar(256)')


PRINT @FirstNamesString 

答案 1 :(得分:0)

我试过这个并且它运行正常。但是变量引擎确实无法保证工作。 (并且没有记录)

create table Person(FirstName nvarchar(10), LastName nvarchar(20), SortOrder int)

insert into Person 
VALUES ('Pers1', 'Last1', 1),
       ('Pers2', 'Last2', 2),
       ('Pers3', 'Last3', 3),
       ('Pers4', 'Last4', 4),
       ('Pers5', NULL, 5)

DECLARE @FirstNamesString nvarchar(256)
SELECT @FirstNamesString = COALESCE(@FirstNamesString + ', ', '') + p.FirstName + ISNULL(' ' + p.LastName, '') 
FROM 
    Person p
ORDER BY
    p.SortOrder

print @FirstNamesString