我正在使用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
答案 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