Выберите таблицу INTO Temp из строковой переменной динамического SQL - PullRequest
1 голос
/ 29 октября 2019

У меня есть процедура, которая создает динамический запрос SQL, упрощенный как

@mySQLQuery = 'SELECT ' + @myCol + 'FROM' + @myTable

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

SELECT * INTO #myTempTable FROM ( @mySQLQuery) x

в основном то, что я хочу сделать.

Я попытался sp_executeSQL 'SELECT * INTO #myTempTable FROM (' + @mySQLQuery + ') x' в моей процедуре, и этотоже не сработало.

Спасибо за любые предложения`

Ответы [ 3 ]

2 голосов
/ 29 октября 2019

Единственный способ, которым я могу думать о вас, - это сохранить объект в tempdb. Временные таблицы сохраняются только для сеанса , в котором они созданы, что означает, что если вы создаете временную таблицу с использованием динамического SQL, она не сохраняется только для этого сеанса в sp_executesql.

EXEC sp_executesql N'SELECT 1 AS one INTO #test;';

--This'll fail
SELECT * FROM #test;

Поэтому вам нужно будет использовать постоянную таблицу в tempdb:

DECLARE @NyCol sysname,
        @MyTable sysname,
        @MySchema sysname;
--Assume these are set somewhere

DECLARE @SQL nvarchar(MAX),
        @CRLF nchar(2) = NCHAR(13) + NCHAR(10);

SET @SQL = N'SELECT ' + QUOTENAME(@MyCol) + @CRLF +
           N'INTO tempdb.dbo.MyTempTable'  + @CRLF +
           N'FROM ' + QUOTENAME(@MySchema) + N'.' + QUOTENAME(@MyTable) + N';';

EXEC sp_executesql @SQL;

--Do Stuff

--Clean up

DROP TABLE tempdb.dbo.MyTempTable;
1 голос
/ 29 октября 2019

Я использовал два способа.

Если структура вашей временной таблицы известна заранее, вы можете сделать это:

CREATE TABLE #temp (<column list>);

SET @my_sql = <your query syntax, without the INTO clause>;

INSERT #temp (<column list>)
EXECUTE sp_executesql @my_sql;

Если, с другой стороныИтак, ваша структура таблицы заранее неизвестна, вы можете использовать глобальную временную таблицу (##temp) вместо локальной временной таблицы (#temp):

EXECUTE sp_executesql <your query with INTO ##temp etc>

Глобальная таблица (## temp) будет доступен из процедуры вне оператора EXECUTE.

0 голосов
/ 29 октября 2019

Область действия временных таблиц ограничена только до тех пор, пока сеанс не будет активным.

В вашем случае, когда вы используете sp_executesql, локальная временная таблица выходит из области действия после завершения вызова sp_executesql.

Вам необходимо создать глобальные временные таблицы.

См. Ниже небольшой пример:

create table dbo.test_mytable( col1 int );
GO

insert into dbo.test_mytable
select 1 union
select 2;
go

create or alter procedure dbo.test_myproc( @mytable varchar(255), @mycol varchar(255) )
as
begin
  declare @mysql varchar(4000);

  drop table if exists ##mytemptable;
  set @mysql = 'select ' + @mycol + ' from ' + @mytable;
  set @mysql = 'select * into ##mytemptable from (' + @mysql + ')  X';

  exec (@mysql);
  select * from ##mytemptable;
end;
GO

exec dbo.test_myproc 'dbo.test_mytable', 'col1';

Когда вы запустите приведенный выше фрагмент кода, вы увидите результат, как показано ниже:

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