Использование временной таблицы с exec @sql в хранимой процедуре
У меня есть хранимая процедура, и часть из них, как показано ниже: @DRange-входящее значение varchar
declare @sql varchar(max)
set @sql = 'select * into #tmpA from TableA where create_date >= getDate - ' + @DRange + '' and is_enabled = 1'
exec (@sql)
select * from #tmpA
проблема в том, что при выполнении хранимой процедуры возникает сообщение об ошибке: Не удается найти объект "#tmpA", поскольку он не существует или у вас нет разрешений.
невозможно ли использовать временную таблицу и выполнить ее или я сделал что-то неправильно?
2 ответов
#tmpA
создается в другой области, поэтому не отображается вне динамического SQL. Вы можете просто сделать окончательный SELECT
часть динамического SQL. Также несколько других вещей:
- всегда используйте префикс схемы при создании / ссылках на объекты
-
всегда использовать
sp_executesql
для динамического SQL; в этом случае он позволяет параметризовать@DRange
значение и избежать рисков SQL-инъекций. - всегда префикс строки Юникода с
N
- Unicode требуется дляsp_executesql
а если вы ленитесь об этом в других местах вашего кода, это также может привести к болезненным неявные преобразования.
DECLARE @sql NVARCHAR(MAX);
SET @sql = N'select * into #tmpA from dbo.TableA
where create_date >= DATEADD(DAY, -@DRange, GETDATE())
AND is_enabled = 1; SELECT * FROM #tmpA';
EXEC sp_executesql @sql, N'@DRange INT', @DRange;
конечно, если все, что вы делаете выбор, мне трудно понять, почему это динамический SQL в первую очередь. Я предполагаю, что ваш запрос (или то, что вы позже сделаете с временной таблицей) сложнее, чем это - если это так, не тупите его для нас. Расскажи нам о своей проблеме. предотвратит много назад и вперед, так как дополнительные детали могут изменить ответ.
вот что я сделаю.
declare @sql varchar(max)
set @sql = 'select * from TableA where create_date >= getDate - ' + @DRange + '' and is_enabled = 1'
Select * Into #tmpA from TableA where create_date = '01/01/1000' -- to create a blank table
insert into #tmpA
exec (@sql)
select * from #tmpA