2016-04-01 8 views
0

Это первый раз, когда я пишу хранимую процедуру на SQL. У меня есть несколько необязательных параметров поиска. Я делал это в PHP запроса, как показано ниже Примечание: Это не оригинальный код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 
"; 

, что я хочу, чтобы преобразовать это в процедуре SQL хранится. когда я пытаюсь сделать это, я получаю ошибку форматирования кода. Пожалуйста, проверьте

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] = ''[email protected] +'' 
     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 

проблемы является жгутами ниже частей

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] = ''[email protected] +'' 
      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 
    ' 
+0

В чем проблема? – FLICKER

+0

Правильно вопрос с незамкнутыми строковыми литералами в здании –

+0

да, это должно быть проблемой с незамкнутой строкой. как я могу отладить это. – Ja22

ответ

1

Правильного способом использования динамической 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. Просто назначьте @debug = 1, если вы хотите проверить значение @sql.

+0

спасибо за ответ. Я выполняю хранимую процедуру «EXEC arReports @ rep = Alex, @ market = ARIZONA» и получает ошибку как «Msg 214, уровень 16, состояние 3, процедура sp_executesql, строка 1 Процедура ожидает параметр« @params »типа« ntext/NCHAR/NVARCHAR '' – Ja22

+0

Моя ошибка. Я изменил @paramlist из varchar в Nvarchar. Это должно работать сейчас. – sam

+0

Не забудьте принять ответ, если найдете решение полезным. – sam

Смежные вопросы