动态TSQL中带引号的错误

时间:2018-10-16 22:51:53

标签: tsql dynamic

我尝试了许多帖子来解决下面的错误,但是我被困住了。如果有人可以在这里指导我正确的方向,将不胜感激。

-- Without EXEC -- this works fine
DECLARE @BPPA AS nvarchar(5)
SET @BPPA = 'BPP2'
DECLARE @BPPB AS nvarchar(5)
SET @BPPB = 'BPP4'

SELECT T0.CustCode AS 'CustCode', MAX(T0.CustName) AS 'CustName', T0.ItemCode AS 'ItemCode', MAX(T0.ItemName) AS 'ItemName', MAX(T0.BPP) AS 'BPP',
SUM(T0.Qty) AS 'QtyP1', SUM(T0.SalesAmt) AS 'SalesAmtP1', 0 AS 'QtyP2', 0 AS 'SalesAmtP2'
FROM [dbo].[VWAJ_SALANALYSIS] T0
WHERE T0.DocDate BETWEEN '2016-01-01' AND '2016-03-31'
AND (
((',' + RTRIM(T0.BPP) + ',') LIKE '%,' + @BPPA + ',%') OR ((',' + RTRIM(T0.BPP) + ',') LIKE '%,' + @BPPB + ',%')
)
GROUP BY T0.CustCode, T0.ItemCode

    -- With EXEC -- Error 'Must declare the scalar variable "@BPPA"
DECLARE @BPPA AS nvarchar(5)
SET @BPPA = 'BPP2'
DECLARE @BPPB AS nvarchar(5)
SET @BPPB = 'BPP4'

EXEC('
SELECT T0.CustCode AS ''CustCode'', MAX(T0.CustName) AS ''CustName'', T0.ItemCode AS ''ItemCode'', MAX(T0.ItemName) AS ''ItemName'', MAX(T0.BPP) AS ''BPP'',
SUM(T0.Qty) AS ''QtyP1'', SUM(T0.SalesAmt) AS ''SalesAmtP1'', 0 AS ''QtyP2'', 0 AS ''SalesAmtP2''
FROM [dbo].[VWAJ_SALANALYSIS] T0
WHERE T0.DocDate BETWEEN ''2016-01-01'' AND ''2016-03-31''
AND (
(('','' + RTRIM(T0.BPP) + '','') LIKE ''%,'' + @BPPA + '',%'') OR (('','' + RTRIM(T0.BPP) + '','') LIKE ''%,'' + @BPPB + '',%'')
)
GROUP BY T0.CustCode, T0.ItemCode
')

我在做什么错?我相信我遗漏了一些引号,但是不确定多少以及为什么。 提前致谢! AJ

2 个答案:

答案 0 :(得分:0)

首先,您可能已经阅读了错误消息,应该会给您提示。

引号看起来还不错,主要问题是变量的作用域是声明它们的批处理。EXEC语句在单独的批处理中执行sql字符串,因此您的变量@BPPA@BPPB在该批次中找不到。您必须拆分字符串以从调用批处理中获取值:

DECLARE @BPPA AS varchar(5) = 'BPP2'
DECLARE @BPPB AS varchar(5) = 'BPP4'

EXEC('
SELECT T0.CustCode AS ''CustCode'', MAX(T0.CustName) AS ''CustName'', T0.ItemCode AS ''ItemCode'', MAX(T0.ItemName) AS ''ItemName'', MAX(T0.BPP) AS ''BPP'',
SUM(T0.Qty) AS ''QtyP1'', SUM(T0.SalesAmt) AS ''SalesAmtP1'', 0 AS ''QtyP2'', 0 AS ''SalesAmtP2''
FROM [dbo].[VWAJ_SALANALYSIS] T0
WHERE T0.DocDate BETWEEN ''2016-01-01'' AND ''2016-03-31''
AND (
(('','' + RTRIM(T0.BPP) + '','') LIKE ''%,''' + @BPPA + ''',%'') OR (('','' + RTRIM(T0.BPP) + '','') LIKE ''%,''' + @BPPB + ''',%'')
)
GROUP BY T0.CustCode, T0.ItemCode
')

要传递参数,您应该看看系统存储过程sp_executesql

添加了示例: 使用sp_executesql,您的EXEC语句应如下所示:

EXEC sp_executesql N'
SELECT T0.CustCode AS ''CustCode'', MAX(T0.CustName) AS ''CustName'', T0.ItemCode AS ''ItemCode'', MAX(T0.ItemName) AS ''ItemName'', MAX(T0.BPP) AS ''BPP'',
SUM(T0.Qty) AS ''QtyP1'', SUM(T0.SalesAmt) AS ''SalesAmtP1'', 0 AS ''QtyP2'', 0 AS ''SalesAmtP2''
FROM [dbo].[VWAJ_SALANALYSIS] T0
WHERE T0.DocDate BETWEEN ''2016-01-01'' AND ''2016-03-31''
AND (
(('','' + RTRIM(T0.BPP) + '','') LIKE ''%,'' + @BPPA + '',%'') OR (('','' + RTRIM(T0.BPP) + '','') LIKE ''%,'' + @BPPB + '',%'')
)
GROUP BY T0.CustCode, T0.ItemCode
'
, N'@BPPA nvarchar(5), @BPPB nvarchar(5)'
, @BPPA = N'BPP2', @BPPB = N'BPP4'

除了常量之外,您还可以像这样传递变量中的值(替换示例脚本的最后一行):

, @BPPA = @BPPA, @BPPB = @BPPB

答案 1 :(得分:0)

我认为您可以在下面尝试此代码。我暂时没有对SQL Server的任何访问权限:)

DECLARE @BPPA AS nvarchar(5)

SET @BPPA = '''%,BPP2,%'''

DECLARE @BPPB AS nvarchar(5) 

SET @BPPB = '''%,BPP4,%'''

DECLARE @sSQL  AS varchar(750)

SET @sSQL = 'SELECT T0.CustCode AS ''CustCode'', MAX(T0.CustName) AS ''CustName'', T0.ItemCode AS ''ItemCode'', MAX(T0.ItemName) AS ''ItemName'', MAX(T0.BPP) AS ''BPP'', SUM(T0.Qty) AS ''QtyP1'', SUM(T0.SalesAmt) AS ''SalesAmtP1'', 0 AS ''QtyP2'', 0 AS ''SalesAmtP2'' FROM [dbo].[VWAJ_SALANALYSIS] T0 WHERE T0.DocDate BETWEEN ''2016-01-01'' AND ''2016-03-31'' AND ( (('',''' + RTRIM(T0.BPP) + ''','') LIKE  N' + @BPPA + ') OR (('',''' + RTRIM(T0.BPP) + ''','') LIKE N' + @BPPB + ') ) GROUP BY T0.CustCode, T0.ItemCode ')

EXEC (@sSQL)

希望这可以为您提供帮助