exec sp_executesql ошибка «Неверный синтаксис около 1» при использовании параметра datetime - PullRequest
0 голосов
/ 30 апреля 2010

У меня есть SSRSreport, который отправляет в базу данных следующий текст:

EXEC ( 'DECLARE @TeamIds as TeamIdTableType ' + @Teams +
       ' EXEC rpt.DWTypeOfSicknessByCategoryReport @TeamIds , ' + 
       @DateFrom + ', ' + @DateTo + ', ' + @InputRankGroups + ', ' + 
       @SubCategories )

Когда я просматриваю это в профилировщике, оно интерпретирует это как:

exec sp_executesql N'EXEC ( ''DECLARE @TeamIds as TeamIdTableType '' + @Teams +
 '' EXEC rpt.DWTypeOfSicknessByCategoryAndEmployeeDetailsReport @TeamIds, '' + 
@DateFrom + '', '' + @DateTo + '', '' + @InputRankGroups + '', '' + 
@SubCategories )',
N'@Teams nvarchar(34),@DateFrom datetime,@DateTo datetime,
@InputRankGroups varchar(1),@SubCategories bit',
@Teams=N'INSERT INTO @TeamIds VALUES (5);',
@DateFrom='2010-02-01 00:00:00',@DateTo='2010-04-30 00:00:00',
@InputRankGroups=N'1',@SubCategories=1

Когда этот sql запускает ошибки на даты.

Я пытался изменить формат даты, но это не помогает. Если я уберу даты, все будет хорошо.

Ответы [ 2 ]

1 голос
/ 30 апреля 2010

Мне кажется, я знаю, что здесь происходит. Если выполняемый SQL -

EXEC ( 'DECLARE @TeamIds as TeamIdTableType ' + @Teams
    + ' EXEC rpt.DWTypeOfSicknessByCategoryReport @TeamIds , '
    + @DateFrom + ', '
    + @DateTo + ', '
    + @InputRankGroups + ', '
    + @SubCategories )

... SQL Server сначала выполнит объединение строк, а затем вызовет EXEC для объединенной строки. При заданных значениях параметров это означает, что объединенная строка будет выглядеть примерно так (с пробелами, откорректированными для удобства чтения):

DECLARE @TeamIds as TeamIdTableType
INSERT INTO @TeamIds VALUES (5);
EXEC rpt.DWTypeOfSicknessByCategoryReport @TeamIds ,
    2010-02-01 00:00:00, 2010-04-30 00:00:00, 1, 1

Проблема в том, что EXEC не является параметризованным запросом, поэтому он должен интерпретировать параметры datetime как необработанные строки, но как необработанные строки без кавычек они не имеют правильного синтаксиса. Вы можете исправить это одним из двух способов.

Во-первых, простой способ : процитировать строки даты и времени.

EXEC ( 'DECLARE @TeamIds as TeamIdTableType ' + @Teams
    + ' EXEC rpt.DWTypeOfSicknessByCategoryReport @TeamIds , '
    + '''' + @DateFrom + ''', '
    + '''' + @DateTo + ''', '
    + @InputRankGroups + ', '
    + @SubCategories )

Это дает вам что-то с правильным синтаксисом:

DECLARE @TeamIds as TeamIdTableType
INSERT INTO @TeamIds VALUES (5);
EXEC rpt.DWTypeOfSicknessByCategoryReport @TeamIds ,
    '2010-02-01 00:00:00', '2010-04-30 00:00:00', 1, 1

Второй, почти простой, но более правильный способ : используйте параметризованный запрос.

DECLARE @sql varchar(max)
SET @sql = 'DECLARE @TeamIds AS TeamIdTableType ' + @Teams
    + ' EXEC rpt.DWTypeOfSicknessByCategoryReport @TeamIds , @DateFrom, @DateTo, @InputRankGroups, @SubCategories'
EXEC sp_executesql @sql, N'@DateFrom datetime,@DateTo datetime,@InputRankGroups varchar(1),@SubCategories bit',
    @DateFrom, @DateTo, @InputRankGroups, @SubCategories

Таким образом, вам не нужно беспокоиться о том, как избежать определенных типов значений, хотя это немного более многословно. Обратите внимание, что вы не можете полностью его параметризировать из-за передачи необработанного SQL в качестве параметра в @Teams. Это может быть не то, что вы можете контролировать - я не очень знаком с SSRS.

0 голосов
/ 12 ноября 2014

Спасибо, что поделились своим решением. Я пытался реализовать 2-й, но я получал ошибку, вызывая хранимую процедуру. Мне пришлось немного изменить синтаксис, и это сработало для меня:

DECLARE @vSQL nvarchar(max) = N'
DECLARE @customerIdList Report.IntegerListTableType; 
'+@customerIdInserts+';
EXEC rpt_CustomerTransactionSummary
@startDate=@startDate,
@endDate=@endDate,
@accountType=@accountType,
@customerIds = @customerIdList';
exec sp_executesql 
  @vSQL,
  N'@startDate datetime, @endDate datetime, @accountType int',
  @startDate,
  @endDate',
  @accountType;

Этот синтаксис также допускает значения NULL (например, @ accountType = NULL)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...