SQL задает переменную как результат запроса в хранимой процедуре

77
8

Я создаю хранимую процедуру с помощью курсора, и мне нужно сохранить количество столбца в переменной. SQL говорит, что он не может преобразовать nvarchar в int. Я пытался использовать CONVERT, CAST и EXEC, но не смог заставить его работать. Как я могу это решить?

DECLARE @FieldName nvarchar(255);
DECLARE @RequestCode Nvarchar(50);
DECLARE @ReqSQLQuantity nvarchar(max);
DECLARE @Quantity int;

Select @ReqSQLQuantity = concat('select count(*) From (select distinct [', @FieldName , '] from [report_' , @RequestCode , ']) as number')
Set @Quantity = (@ReqSQLQuantity)
Select @Quantity

спросил(а) 2021-01-25T15:15:32+03:00 4 месяца, 4 недели назад
1
Решение
88

Еще одним более безопасным вариантом было бы использовать sp_executesql хранимую процедуру, что-то вроде этого....

DECLARE @FieldName nvarchar(255);
DECLARE @RequestCode Nvarchar(50);
DECLARE @ReqSQLQuantity nvarchar(max);
DECLARE @Quantity int, @tableName SYSNAME;

SET @tableName = N'report_' + @RequestCode

Select @ReqSQLQuantity = N' select @Quantity = count(*) '
+ N' From (select distinct ' + QUOTENAME(@FieldName)
+ N' from ' + QUOTENAME(@tableName) + N' ) as number'
Exec sp_executesql @ReqSQLQuantity
,N'@Quantity INT OUTPUT'
,@Quantity OUTPUT

Select @Quantity

ответил(а) 2021-01-25T15:15:32+03:00 4 месяца, 4 недели назад
77

Set @Quantite = (@ReqSQLQuantite)

Это не оценка, это неявное преобразование. От NVARCHAR до INT, и вы пытаетесь преобразовать текст запроса SQL в INT, следовательно, ошибку.

Кроме того, вы предполагаете, что результаты совпадают с возвращаемыми значениями и могут быть назначены переменным. Это неверно, результаты выполнения SQL отправляются клиенту. Чтобы SELECT @value =... результат, вы должны использовать назначение SELECT: SELECT @value =... Попытка запуска @variable = EXEC(...) - это не одно и то же. Подумайте о результатах SELECT так же, как печать в приложении: печать отправляет текст на консоль. Если вы запустите некоторый псевдокод, например x = print('foo') на консоль был отправлен "foo", а x содержит значение, возвращаемое печатью (что бы это ни было). То же самое с этим псевдо-SQL, @x = EXEC('SELECT foo') отправит foo клиенту, а @x будет некоторое числовое значение, которое является значением, возвращаемым EXEC (в правильном примере нужно было бы использовать явный RETURN чтобы установить его).


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

SET @sql = concat(N'SELECT count(*) FROM (SELECT ... FROM ...)');
exec sp_executesql @sql;

ответил(а) 2021-01-25T15:15:32+03:00 4 месяца, 4 недели назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема