"Вставка результатов хранимой процедуры в временную таблицу"
Вопрос: Как выполнить 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 ответ(ов)
Привет! Если вы хотите выполнить код, который выбирает имя сервера и использует 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
на полное имя вашей хранимой процедуры. Если у вас остались вопросы, не стесняйтесь спрашивать!
Когда хранимая процедура возвращает множество столбцов, и вы не хотите вручную создавать временную таблицу для хранения результата, я нашел самый простой способ сделать это — войти в хранимую процедуру и добавить оператор "into" к последнему оператору select, а в условие where добавить 1=0.
Запустите хранимую процедуру один раз, а затем вернитесь и удалите SQL-код, который вы только что добавили. Теперь у вас будет пустая таблица, соответствующая результату хранимой процедуры. Вы можете либо использовать "сценарий таблицы как создать" для временной таблицы, либо просто вставить данные напрямую в эту таблицу.
Самое простое решение:
CREATE TABLE #temp (...);
INSERT INTO #temp
EXEC [sproc];
Если вы не знаете схему, то можно сделать следующее. Обратите внимание, что этот метод имеет серьезные риски безопасности.
SELECT *
INTO #temp
FROM OPENROWSET('SQLNCLI',
'Server=localhost;Trusted_Connection=yes;',
'EXEC [db].[schema].[sproc]')
В вашем запросе создаётся временная таблица @temp
, которая используется для хранения информации о файлах базы данных. Вот шаги, которые выполняет ваш код:
Объявление временной таблицы
@temp
с необходимыми полями:name
: имя файла.field
: дополнительное поле (может содержать информацию о типе файла).filename
: фактический путь к файлу.filegroup
: имя файла группы.size
: текущий размер файла.maxsize
: максимальный размер файла.growth
: размер, на который файл будет увеличиваться при необходимости.usage
: использование файла (например, для данных или журналов).
Заполнение временной таблицы с помощью результата выполнения системной процедуры
sp_helpfile
, которая возвращает информацию о файлах в базе данных.Наконец, запрос для выбора всех данных из временной таблицы
@temp
.
Если у вас есть какие-либо вопросы по этой реализации или вы хотите внести изменения, не стесняйтесь задавать их!
Если результаты вашей хранимой процедуры слишком сложны для того, чтобы ручками написать оператор "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" самостоятельно, это помогает избежать ручных ошибок, таких как опечатки и несоответствия типов данных в больших процессах. Отладка опечатки может занять больше времени, чем написание запроса с самого начала.
Как выполнить оператор UPDATE с JOIN в SQL Server?
Функция против Хранимой процедуры в SQL Server
Найти все таблицы, содержащие столбец с указанным именем
Как экранировать одинарную кавычку в SQL Server?
Следует ли мне использовать != или <> для обозначения "не равно" в T-SQL?