Выполнить sp_executeSql для select ... в #table, но не могу выделить данные временной таблицы - PullRequest
33 голосов
/ 07 ноября 2011

Пытался выбрать ... во временную таблицу #TempTable в sp_Executedsql.Не успешно вставлено или нет, но там написано сообщений (359 строк затронуты), что означает успешное вставление?Сценарий ниже

DECLARE @Sql NVARCHAR(MAX);
SET @Sql = 'select distinct Coloum1,Coloum2 into #TempTable 
            from SPCTable with(nolock)
            where Convert(varchar(10), Date_Tm, 120) Between @Date_From And @Date_To';

SET @Sql = 'DECLARE @Date_From VARCHAR(10);
            DECLARE @Date_To VARCHAR(10);
            SET @Date_From = '''+CONVERT(VARCHAR(10),DATEADD(d,DATEDIFF(d,0,GETDATE()),0)-1,120)+''';
            SET @Date_To = '''+CONVERT(VARCHAR(10),DATEADD(d,DATEDIFF(d,0,GETDATE()),0)-1,120)+''';
            '+ @Sql;

EXECUTE sp_executesql @Sql;

После выполнения его возвращает мне сообщения (затронуто 359 строк).Далее при попытке выбрать данные из # TempTable.

Select * From #TempTable;

Их возвращает мне:

Msg 208, Level 16, State 0, Line 2
Invalid object name '#TempTable'.

Предполагается, что работает только раздел «select»Вставка не работает.как это исправить?

Ответы [ 8 ]

38 голосов
/ 10 августа 2012

Использование глобальной временной таблицы в этом сценарии может вызвать проблемы, поскольку таблица будет существовать между сеансами и может привести к некоторым проблемам с асинхронным использованием вызывающего кода.

Локальная временная таблица может использоваться, если она определена до вызова sp_executesql, например.

CREATE TABLE #tempTable(id int);

sp_executesql 'INSERT INTO #tempTable SELECT myId FROM myTable';

SELECT * FROM #tempTable;
28 голосов
/ 07 ноября 2011

Локальная временная таблица #table_name видна только в текущем сеансе, глобальные временные ##table_name таблицы видны во всех сеансах. Оба живут, пока их сессия не закрыта. sp_executesql - создает свой собственный сеанс (может быть, слово "scope" было бы лучше), поэтому оно и происходит.

11 голосов
/ 02 мая 2017

В вашей строке @sql не вставляйте into #TempTable. Вместо этого вызывайте свой оператор SELECT без оператора INSERT.

Наконец, вставьте результаты во временную таблицу следующим образом:

INSERT INTO @tmpTbl EXEC sp_executesql @sql

Кроме того, вам нужно объявить временную таблицу, если вы используете этот подход

DECLARE @tmpTbl TABLE (
    //define columns here...
)
7 голосов
/ 07 ноября 2011

ваша временная таблица в динамическом SQL выходит за рамки области нединамического SQL.

Посмотрите, как с этим справиться: Немного о локальных временных таблицах сервера sql

3 голосов
/ 07 ноября 2011

Временные таблицы живут только до тех пор, пока их создает соединение. Я ожидаю, что вы непреднамеренно выдаете select на отдельном соединении. Вы можете проверить это, на мгновение выполнив вставку во временную таблицу и проверив, есть ли там ваши данные. Если это так, вы можете вернуться к исходному решению и просто передать объект подключения на ваш выбор.

1 голос
/ 21 августа 2018

Это сработало для меня

declare @sql nvarchar(max)     
create table #temp ( listId int, Name nvarchar(200))     
set @sql = 'SELECT top 10 ListId, Name FROM [V12-ListSelector].[dbo].[List]'    
insert into #temp
exec sp_executesql  @sql    
select * from #temp    
drop table #temp
1 голос
/ 31 мая 2016
declare @sql varchar(1000)
set @sql="select * into #t from table;"
set @sql =@sql + "select * from #t;"

 execute  SP_EXECUTESQL  @sql
1 голос
/ 22 марта 2016

Чтобы обойти эту проблему, используйте команду CREATE TABLE #TEMPTABLE, чтобы сначала создать пустую временную таблицу перед запуском sp_executesql. Затем запустите INSERT INTO #TEMPTABLE с помощью sp_executesql. Это будет работать Вот как я преодолеваю эту проблему, так как у меня есть настройка, в которой все мои запросы обычно выполняются через sp_executesql.

...