18

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

15

Вопрос: Как выполнить SELECT * INTO [временная таблица] FROM [хранимая процедура]? Не FROM [таблица] и без определения [временной таблицы]?

Я использую следующий запрос, чтобы выбрать все данные из таблицы BusinessLine во временную таблицу tmpBusLine, и это работает нормально:

SELECT *
INTO tmpBusLine
FROM BusinessLine

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

SELECT *
INTO tmpBusLine
FROM
EXEC getBusinessLineHistory '16 Mar 2009'

Однако получаю сообщение об ошибке:

Msg 156, Level 15, State 1, Line 2
Incorrect syntax near the keyword 'exec'.

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

5 ответ(ов)

1

Привет! Если вы хотите выполнить код, который выбирает имя сервера и использует OPENQUERY для вызова хранимой процедуры, то вот переведенный фрагмент на русский:

-- Получаем имя сервера
SELECT @@ServerName

-- Включаем доступ к данным через сервер
EXEC sp_serveroption @@ServerName, 'DATA ACCESS', TRUE

-- Создаем временную таблицу и заполняем её результатами из удаленного вызова хранимой процедуры
SELECT *
INTO #tmpTable
FROM OPENQUERY(YOURSERVERNAME, 'EXEC db.schema.sproc 1')

Не забудьте заменить YOURSERVERNAME на имя вашего сервера и db.schema.sproc на полное имя вашей хранимой процедуры. Если у вас остались вопросы, не стесняйтесь спрашивать!

1

Когда хранимая процедура возвращает множество столбцов, и вы не хотите вручную создавать временную таблицу для хранения результата, я нашел самый простой способ сделать это — войти в хранимую процедуру и добавить оператор "into" к последнему оператору select, а в условие where добавить 1=0.

Запустите хранимую процедуру один раз, а затем вернитесь и удалите SQL-код, который вы только что добавили. Теперь у вас будет пустая таблица, соответствующая результату хранимой процедуры. Вы можете либо использовать "сценарий таблицы как создать" для временной таблицы, либо просто вставить данные напрямую в эту таблицу.

1

Самое простое решение:

CREATE TABLE #temp (...);

INSERT INTO #temp
EXEC [sproc];

Если вы не знаете схему, то можно сделать следующее. Обратите внимание, что этот метод имеет серьезные риски безопасности.

SELECT * 
INTO #temp
FROM OPENROWSET('SQLNCLI', 
                'Server=localhost;Trusted_Connection=yes;', 
                'EXEC [db].[schema].[sproc]')
0

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

  1. Объявление временной таблицы @temp с необходимыми полями:

    • name: имя файла.
    • field: дополнительное поле (может содержать информацию о типе файла).
    • filename: фактический путь к файлу.
    • filegroup: имя файла группы.
    • size: текущий размер файла.
    • maxsize: максимальный размер файла.
    • growth: размер, на который файл будет увеличиваться при необходимости.
    • usage: использование файла (например, для данных или журналов).
  2. Заполнение временной таблицы с помощью результата выполнения системной процедуры sp_helpfile, которая возвращает информацию о файлах в базе данных.

  3. Наконец, запрос для выбора всех данных из временной таблицы @temp.

Если у вас есть какие-либо вопросы по этой реализации или вы хотите внести изменения, не стесняйтесь задавать их!

0

Если результаты вашей хранимой процедуры слишком сложны для того, чтобы ручками написать оператор "create table", и вы не можете использовать OPENQUERY или OPENROWSET, вы можете использовать sp_help, чтобы сгенерировать список столбцов и типов данных для вас. Как только у вас есть список столбцов, остается только отформатировать его в соответствии с вашими нуждами.

Шаг 1: Добавьте "into #temp" к выходному запросу (например, "select [...] into #temp from [...]").

Самый простой способ — это отредактировать выходной запрос в самой процедуре. Если вы не можете изменить хранимую процедуру, скопируйте её содержимое в новое окно запроса и измените запрос там.

Шаг 2: Выполните sp_help для временной таблицы (например, "exec tempdb..sp_help #temp").

После создания временной таблицы выполните sp_help для получения списка столбцов и типов данных, включая размер полей varchar.

Шаг 3: Скопируйте столбцы данных и типы в оператор create table.

У меня есть Excel-таблица, которую я использую для форматирования вывода sp_help в оператор "create table". Вам не нужно ничего такого сложного, просто скопируйте и вставьте в ваш SQL-редактор. Используйте имена столбцов, размеры и типы для создания оператора "Create table #x [...]" или "declare @x table [...]", который вы сможете использовать для добавления результатов хранимой процедуры.

Шаг 4: Вставьте данные в только что созданную таблицу.

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

DECLARE @t TABLE 
(
   -- эти столбцы были скопированы из sp_help
   COL1 INT,
   COL2 INT   
)

INSERT INTO @t 
Exec spMyProc 

Эта техника также может быть использована для преобразования временной таблицы (#temp) в переменную таблицу (@temp). Хотя это может потребовать больше шагов, чем просто написать оператор "create table" самостоятельно, это помогает избежать ручных ошибок, таких как опечатки и несоответствия типов данных в больших процессах. Отладка опечатки может занять больше времени, чем написание запроса с самого начала.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь