从结束逗号中删除最后一个动态列?
Strip the last dynamic column from ending comma?
我正在编写以下动态 SQL,并在 FROM
关键字周围出现错误。
Incorrect syntax near the keyword 'FROM'.
' + @columnList + '
FROM [History]
我知道为什么,因为它前面不应该有逗号。但是,由于它前面的列 (@columnList
) 是动态 SQL 的结果,我该如何解决这个问题?
基本上,我需要一种方法来制作
SELECT @columnList =....
不在最后选择的 column/Account 末尾附加逗号。
这部分最后加逗号:
quotename(AccTbl.Account), ',',
完整查询:
DECLARE @sqlCommand NVARCHAR(MAX) = '',
@columnList NVARCHAR(MAX) = '',
@pivotColumns NVARCHAR(MAX) = '';
SELECT @columnList =
(SELECT DISTINCT concat(CHAR(9), 'COALESCE(', quotename(AccTbl.Account), ', 0)', quotename(AccTbl.Account), ',', CHAR(10)) --CHAR(9) & CHAR(10) for indentation/formatting
FROM [Accounts] AccTbl
WHERE AccTbl.Account NOT IN ('WS')
FOR XML Path(''), TYPE).value('(./text())[1]', 'NVARCHAR(MAX)');
SELECT @pivotColumns = STUFF(
(SELECT DISTINCT concat(CHAR(9), ',', quotename(AccTbl.Account), CHAR(10))
FROM [Accounts] AccTbl
WHERE AccTbl.Account NOT IN ('WS')
FOR XML Path(''), TYPE).value('(./text())[1]', 'NVARCHAR(MAX)'), 1, 1, '');
/*
EXEC the sqlCommand as separate batches to prevent this error: 'CREATE VIEW' must be the first statement in a query batch.
*/
SET @sqlCommand = '
USE [ABC_DB]
--GO
DROP VIEW IF EXISTS [dbo].[Piv];
--GO
SET ANSI_NULLS ON
--GO
SET QUOTED_IDENTIFIER ON
--GO
';
Execute sp_executesql @sqlCommand;
SET @sqlCommand = '
CREATE VIEW [dbo].[Piv]
AS
(SELECT
[Style Code],
' + @columnList + '
FROM [History]
PIVOT (SUM([Value]) FOR [Accounts] IN (
' + @pivotColumns + '
)
)
AS Piv);
';
PRINT @sqlCommand;
Execute sp_executesql @sqlCommand;
换句话说,现在发生的事情是这样的:
更新:
@columnList
固定为前导逗号而不是尾随逗号,但前导逗号和尾随逗号都适用于 @pivotColumns
,因为我们在 PIVOT 部分没有预先存在的列查询就像我们在 SELECT 语句中使用 Style Code
.
逗号不要放在末尾,放在开头,然后去掉第一个字符,使用STUFF
,在T-SQL.[=14中就容易多了=]
所以 {Expression} + ','
改为 ',' + {Expression}
。然后你可以简单地做 STUFF(@columnList,1,1,'')
来删除 leading 逗号。
部分问题是您的 'formatting' 代码。一般来说,我同意格式化动态代码有助于调试 - 在这里它会妨碍。
SELECT @columnList = STUFF(
(SELECT DISTINCT concat(', ', quotename(AccTbl.Account))
FROM [Accounts] AccTbl
WHERE AccTbl.Account NOT IN ('WS')
FOR XML Path(''), TYPE).value('(./text())[1]', 'NVARCHAR(MAX)'), 1, 1, '');
SELECT @pivotColumns = STUFF(
(SELECT DISTINCT concat(', ', quotename(AccTbl.Account))
FROM [Accounts] AccTbl
WHERE AccTbl.Account NOT IN ('WS')
FOR XML Path(''), TYPE).value('(./text())[1]', 'NVARCHAR(MAX)'), 1, 1, '');
删除那些 - 我们看到两个语句完全相同。假设来自帐户 table 的结果是:Acct1、Acct2
@columnList 和@pivotColumns 的结果都是“[Acct1], [Acct2]”。所以 - 如果您想扩展列列表部分,例如添加 table 别名(我会这样做):
SELECT @columnList = STUFF(
(SELECT DISTINCT concat(', ', 'h.', quotename(AccTbl.Account))
FROM [Accounts] AccTbl
WHERE AccTbl.Account NOT IN ('WS')
FOR XML Path(''), TYPE).value('(./text())[1]', 'NVARCHAR(MAX)'), 1, 1, '');
我不会费心在最终结果中格式化这些列,因为您将根据需要使用动态 SQL.
重新创建视图
SET @sqlCommand = '
CREATE VIEW [dbo].[Piv]
AS
(SELECT
h.[Style Code],
' + @columnList + '
FROM [History] h
PIVOT (SUM(h.[Value]) FOR [Accounts] IN (
' + @pivotColumns + '
)
)
AS Piv);
';
我正在编写以下动态 SQL,并在 FROM
关键字周围出现错误。
Incorrect syntax near the keyword 'FROM'.
' + @columnList + '
FROM [History]
我知道为什么,因为它前面不应该有逗号。但是,由于它前面的列 (@columnList
) 是动态 SQL 的结果,我该如何解决这个问题?
基本上,我需要一种方法来制作
SELECT @columnList =....
不在最后选择的 column/Account 末尾附加逗号。
这部分最后加逗号:
quotename(AccTbl.Account), ',',
完整查询:
DECLARE @sqlCommand NVARCHAR(MAX) = '',
@columnList NVARCHAR(MAX) = '',
@pivotColumns NVARCHAR(MAX) = '';
SELECT @columnList =
(SELECT DISTINCT concat(CHAR(9), 'COALESCE(', quotename(AccTbl.Account), ', 0)', quotename(AccTbl.Account), ',', CHAR(10)) --CHAR(9) & CHAR(10) for indentation/formatting
FROM [Accounts] AccTbl
WHERE AccTbl.Account NOT IN ('WS')
FOR XML Path(''), TYPE).value('(./text())[1]', 'NVARCHAR(MAX)');
SELECT @pivotColumns = STUFF(
(SELECT DISTINCT concat(CHAR(9), ',', quotename(AccTbl.Account), CHAR(10))
FROM [Accounts] AccTbl
WHERE AccTbl.Account NOT IN ('WS')
FOR XML Path(''), TYPE).value('(./text())[1]', 'NVARCHAR(MAX)'), 1, 1, '');
/*
EXEC the sqlCommand as separate batches to prevent this error: 'CREATE VIEW' must be the first statement in a query batch.
*/
SET @sqlCommand = '
USE [ABC_DB]
--GO
DROP VIEW IF EXISTS [dbo].[Piv];
--GO
SET ANSI_NULLS ON
--GO
SET QUOTED_IDENTIFIER ON
--GO
';
Execute sp_executesql @sqlCommand;
SET @sqlCommand = '
CREATE VIEW [dbo].[Piv]
AS
(SELECT
[Style Code],
' + @columnList + '
FROM [History]
PIVOT (SUM([Value]) FOR [Accounts] IN (
' + @pivotColumns + '
)
)
AS Piv);
';
PRINT @sqlCommand;
Execute sp_executesql @sqlCommand;
换句话说,现在发生的事情是这样的:
更新:
@columnList
固定为前导逗号而不是尾随逗号,但前导逗号和尾随逗号都适用于 @pivotColumns
,因为我们在 PIVOT 部分没有预先存在的列查询就像我们在 SELECT 语句中使用 Style Code
.
逗号不要放在末尾,放在开头,然后去掉第一个字符,使用STUFF
,在T-SQL.[=14中就容易多了=]
所以 {Expression} + ','
改为 ',' + {Expression}
。然后你可以简单地做 STUFF(@columnList,1,1,'')
来删除 leading 逗号。
部分问题是您的 'formatting' 代码。一般来说,我同意格式化动态代码有助于调试 - 在这里它会妨碍。
SELECT @columnList = STUFF(
(SELECT DISTINCT concat(', ', quotename(AccTbl.Account))
FROM [Accounts] AccTbl
WHERE AccTbl.Account NOT IN ('WS')
FOR XML Path(''), TYPE).value('(./text())[1]', 'NVARCHAR(MAX)'), 1, 1, '');
SELECT @pivotColumns = STUFF(
(SELECT DISTINCT concat(', ', quotename(AccTbl.Account))
FROM [Accounts] AccTbl
WHERE AccTbl.Account NOT IN ('WS')
FOR XML Path(''), TYPE).value('(./text())[1]', 'NVARCHAR(MAX)'), 1, 1, '');
删除那些 - 我们看到两个语句完全相同。假设来自帐户 table 的结果是:Acct1、Acct2
@columnList 和@pivotColumns 的结果都是“[Acct1], [Acct2]”。所以 - 如果您想扩展列列表部分,例如添加 table 别名(我会这样做):
SELECT @columnList = STUFF(
(SELECT DISTINCT concat(', ', 'h.', quotename(AccTbl.Account))
FROM [Accounts] AccTbl
WHERE AccTbl.Account NOT IN ('WS')
FOR XML Path(''), TYPE).value('(./text())[1]', 'NVARCHAR(MAX)'), 1, 1, '');
我不会费心在最终结果中格式化这些列,因为您将根据需要使用动态 SQL.
重新创建视图SET @sqlCommand = '
CREATE VIEW [dbo].[Piv]
AS
(SELECT
h.[Style Code],
' + @columnList + '
FROM [History] h
PIVOT (SUM(h.[Value]) FOR [Accounts] IN (
' + @pivotColumns + '
)
)
AS Piv);
';