这是我第一次在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
答案 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。