SQL存储过程格式化错误

时间:2016-04-01 06:16:45

标签: sql-server tsql stored-procedures

这是我第一次在SQL上编写存储过程。我有多个可选的搜索参数。我已经在php查询中完成了这个,如下所示 注意:这不是原始代码

X-Requested-With: XMLHttpRequest

我想要的是将其转换为SQL存储过程。当我尝试这样做时,我得到一个代码格式错误。请检查

     $query = " 

SELECT  CASE WHEN GROUPING(trntypename) = 1 THEN 'Total' ELSE trntypename END AS trntypename,
        SUM(CASE WHEN FORMAT(datecreated,'yyyyMM') = '201510' THEN AmountDue END) AS [201510],
        SUM(CASE WHEN FORMAT(datecreated,'yyyyMM') = '201511' THEN AmountDue END) AS [201511],
        SUM(CASE WHEN FORMAT(datecreated,'yyyyMM') = '201512' THEN AmountDue END) AS [201512],
        SUM(CASE WHEN FORMAT(datecreated,'yyyyMM') = '201601' THEN AmountDue END) AS [201601],
        SUM(CASE WHEN FORMAT(datecreated,'yyyyMM') = '201602' THEN AmountDue END) AS [201602],
        SUM(CASE WHEN FORMAT(datecreated,'yyyyMM') = '201603' THEN AmountDue END) AS [201603],
        SUM(AmountDue) Total FROM RAccounts_Receivable WHERE ";

        if ($rep != "") {
            $query .= "(SalesmanGroupName=:rep)";
            if (($market != "") || ($agent != "") || ($warehouse != "") || ($customername != "") || ($regionalname != "")) {
                $query.=" and ";
            }
        }

        if ($market != "") {
            $query .= "(bptypename=:market)";
            if (($warehouse != "") || ($customername != "") || ($regionalname != "")) {
                $query.=" and ";
            }
        }

        if ($warehouse != "") {
            $query .= "(warehousename=:warehouse)";
            if (($customername != "") || ($regionalname != "")) {
                $query.=" and ";
            }
        }

        if ($customername != "") {
            $query .= "(SupplierName=:supplier)";
            if ($regionalname != "") {
                $query.=" and ";
            }
        }

        if ($regionalname != "") {
            $query.= "(territoryname=:territory) ";
        }

       if (($rep != "") || ($market != "") || ($agent != "") || ($warehouse != "") || ($customername != "") || ($regionalname != "")) {
            $query.=" AND ";
        }

        $query .=" datecreated >= DATEADD(month,DATEDIFF(month,0,GETDATE()) - 7,0)
GROUP BY ROLLUP([trntypename])
ORDER BY CASE WHEN GROUPING(trntypename) = 1 THEN '1' ELSE 0 END
";

问题在于以下部分

USE  CustomReports

GO 
ALTER PROCEDURE arReports(@rep AS NVARCHAR(MAX),@market AS NVARCHAR(MAX))
AS
DECLARE @CaseQuery NVARCHAR(MAX) = 'SUM(CASE WHEN FORMAT(datecreated,''yyyy/MM'') = ''<<dateval>>'' THEN AmountDue END) AS [<<dateval>>]',
        @SelectQuery NVARCHAR(MAX),
        @Sql NVARCHAR(MAX)


SELECT  @SelectQuery = COALESCE(@SelectQuery + ',', '') + REPLACE(@CaseQuery, '<<dateval>>', FORMAT(datecreated,'yyyy/MM'))
FROM    [dbo].[RAccounts_Receivable]
WHERE   datecreated >= DATEADD(month,DATEDIFF(month,0,GETDATE()) - 7,0)
GROUP BY FORMAT(datecreated,'yyyy/MM')
ORDER BY FORMAT(datecreated,'yyyy/MM')

SET @Sql = '
        SELECT  CASE WHEN GROUPING(trntypename) = 1 THEN ''Total'' ELSE trntypename END AS trntypename,
         ' + @SelectQuery + ',
          SUM(AmountDue) Total
        FROM RAccounts_Receivable
        WHERE'

   BEGIN
    IF (@rep <>'''') 
        SET @sql = @sql + '([SalesmanGroupName] = ''+@rep +''
        IF (@market <> '') 
             SET @sql = @sql + ' AND'
   END    

   BEGIN
    IF (@market <>'')  
        SET @sql = @sql + ''([bptypename] = ''+ @market +''

   END

    AND datecreated >= DATEADD(month,DATEDIFF(month,0,GETDATE()) - 7,0)
    GROUP BY ROLLUP([trntypename])
    ORDER BY CASE WHEN GROUPING(trntypename) = 1 THEN 1 ELSE 0 END
'
EXEC (@Sql)

RETURN

1 个答案:

答案 0 :(得分:1)

使用Dynamic sql的正确方法是使用参数化,可以使用sp_executesql完成,如下所述:

ALTER PROCEDURE arReports
@rep AS NVARCHAR(MAX)  = null,
@market AS NVARCHAR(MAX) = null
as
begin
declare @sql nvarchar(max)
declare @paramlist nvarchar(max)
declare @nl char(3) = char(13) + char(10)
Declare @SelectQuery NVARCHAR(MAX)
declare @debug bit = 0
SELECT  @SelectQuery = COALESCE(@SelectQuery + ',', '') + REPLACE(@CaseQuery, '<<dateval>>', FORMAT(datecreated,'yyyy/MM'))
FROM    [dbo].[RAccounts_Receivable]
WHERE   datecreated >= DATEADD(month,DATEDIFF(month,0,GETDATE()) - 7,0)
GROUP BY FORMAT(datecreated,'yyyy/MM')
ORDER BY FORMAT(datecreated,'yyyy/MM')

set @sql = '
SELECT  CASE WHEN GROUPING(trntypename) = 1 THEN ''Total'' ELSE trntypename END AS trntypename,
         ' + @SelectQuery + ',
          SUM(AmountDue) Total
        FROM RAccounts_Receivable
        WHERE 1=1' + @nl

if @rep is not null 
begin
set @sql = @sql + ' and [SalesmanGroupName]  = @rep' + @nl
end

if @market is not null 
begin
set @sql = @sql + ' and [bptypename] =  @market' + @nl
end

set @sql = @sql +  ' AND datecreated >= DATEADD(month,DATEDIFF(month,0,GETDATE()) - 7,0)
    GROUP BY ROLLUP([trntypename])
    ORDER BY CASE WHEN GROUPING(trntypename) = 1 THEN 1 ELSE 0 END'

set @paramlist = '@rep NVARCHAR(MAX),
@market NVARCHAR(MAX)'

if @debug = 1 
Begin
Print @sql
end

exec sp_executesql @sql,@Paramlist,@rep,@market
end

如果这有帮助,请告诉我。

我使用参数@debug来检查@sql措辞。如果要检查@sql的值,只需指定@debug = 1。