Как мне это сделать SELECT * INTO [temp table] FROM [stored procedure]
? Не FROM [Table]
и без определения [temp table]
?
Select
все данные BusinessLine
в в tmpBusLine
работает нормально.
select *
into tmpBusLine
from BusinessLine
Я пытаюсь то же самое, но использование, stored procedure
которое возвращает данные, не совсем то же самое.
select *
into tmpBusLine
from
exec getBusinessLineHistory '16 Mar 2009'
Выходное сообщение:
Сообщение 156, уровень 15, состояние 1, строка 2 Неверный синтаксис рядом с ключевым словом "exec".
Я прочитал несколько примеров создания временной таблицы с той же структурой, что и для хранимой процедуры вывода, которая прекрасно работает, но было бы неплохо не указывать столбцы.
Ответы:
Вы можете использовать OPENROWSET для этого. Посмотри. Я также включил код sp_configure для включения специальных распределенных запросов, если он еще не включен.
источник
Если вы хотите сделать это без предварительного объявления временной таблицы, вы можете попытаться создать пользовательскую функцию, а не хранимую процедуру, и заставить эту пользовательскую функцию возвращать таблицу. В качестве альтернативы, если вы хотите использовать хранимую процедуру, попробуйте что-то вроде этого:
источник
В SQL Server 2005 вы можете использовать,
INSERT INTO ... EXEC
чтобы вставить результат хранимой процедуры в таблицу. Из документации MSDNINSERT
(фактически для SQL Server 2000):источник
Это ответ на слегка измененную версию вашего вопроса. Если вы можете отказаться от использования хранимой процедуры для пользовательской функции, вы можете использовать встроенную табличную пользовательскую функцию. По сути, это хранимая процедура (будет принимать параметры), которая возвращает таблицу как набор результатов; и, следовательно, будет хорошо с заявлением INTO.
Вот хорошая быстрая статья об этом и других пользовательских функциях. Если у вас все еще есть потребность в хранимой процедуре, вы можете заключить встроенную табличную пользовательскую функцию в хранимую процедуру. Хранимая процедура просто передает параметры, когда она вызывает select * из встроенной пользовательской функции с табличным значением.
Так, например, у вас есть встроенная пользовательская функция с табличным значением для получения списка клиентов для определенного региона:
Затем вы можете вызвать эту функцию, чтобы получить такие результаты:
Или сделать ВЫБОР В:
Если вам все еще нужна хранимая процедура, оберните эту функцию следующим образом:
Я думаю, что это самый «бездарный» метод для получения желаемых результатов. Он использует существующие функции, так как они были предназначены для использования без дополнительных сложностей. Вложив встроенную пользовательскую функцию с табличным значением в хранимую процедуру, вы получаете доступ к этой функции двумя способами. Плюс! У вас есть только одна точка обслуживания для реального кода SQL.
Было предложено использовать OPENROWSET, но это не то, для чего предназначалась функция OPENROWSET (из Books Online):
Использование OPENROWSET выполнит работу, но потребует некоторых дополнительных затрат для открытия локальных соединений и сортировки данных. Это также может быть не вариант во всех случаях, поскольку требует специального разрешения запроса, которое представляет угрозу безопасности и, следовательно, может быть нежелательным. Кроме того, подход OPENROWSET исключает использование хранимых процедур, возвращающих более одного набора результатов. Этого можно достичь, заключив в одну хранимую процедуру несколько встроенных пользовательских функций табличного значения.
источник
источник
Если вы не знаете схему, вы можете сделать следующее. Обратите внимание, что в этом методе существуют серьезные угрозы безопасности.
источник
Когда хранимая процедура возвращает много столбцов, и вы не хотите вручную «создавать» временную таблицу для хранения результата, я обнаружил, что самый простой способ - перейти в хранимую процедуру и добавить предложение «в» в последний оператор select и добавьте 1 = 0 к предложению where.
Запустите хранимую процедуру один раз, вернитесь и удалите только что добавленный код SQL. Теперь у вас будет пустая таблица, соответствующая результату хранимой процедуры. Вы можете либо «скрипт таблицы как создать» для временной таблицы, либо просто вставить непосредственно в эту таблицу.
источник
SELECT INTO
временную таблицу и создаете таблицу сценариев как создать из временной таблицы? Временные таблицы появляются,tempdb
но я не могу щелкнуть правой кнопкой мыши и создать скрипт. Любая помощь приветствуется.select ... into new_table
неявно создать фактическую таблицу.declare @s varchar(max)='';select @s=@s+','+COLUMN_NAME+' '+DATA_TYPE+isnull('('+case CHARACTER_MAXIMUM_LENGTH when -1 then 'max' else cast(CHARACTER_MAXIMUM_LENGTH as varchar(10))end+')','')from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='...';select @s
источник
Ваша хранимая процедура только получает данные или изменяет их тоже? Если он используется только для извлечения, вы можете преобразовать хранимую процедуру в функцию и использовать выражения общих таблиц (CTE), не объявляя ее следующим образом:
Однако все, что необходимо извлечь из CTE, следует использовать только в одном операторе. Вы не можете сделать это
with temp as ...
и попытаться использовать его после нескольких строк SQL. Вы можете иметь несколько CTE в одном операторе для более сложных запросов.Например,
источник
Если таблица результатов вашего сохраненного процесса слишком сложна, чтобы вручную ввести оператор «создать таблицу», и вы не можете использовать OPENQUERY OR OPENROWSET, вы можете использовать sp_help, чтобы сгенерировать список столбцов и типов данных для вас. Когда у вас есть список столбцов, вам нужно просто отформатировать его в соответствии с вашими потребностями.
Шаг 1: Добавьте «в #temp» к выходному запросу (например, «выберите [...] в #temp from [...]»).
Самый простой способ - это напрямую редактировать выходной запрос в proc. Если вы не можете изменить сохраненный процесс, вы можете скопировать содержимое в новое окно запроса и изменить его там.
Шаг 2: Запустите sp_help для временной таблицы. (например, "exec tempdb..sp_help #temp")
После создания временной таблицы выполните sp_help для временной таблицы, чтобы получить список столбцов и типов данных, включая размер полей varchar.
Шаг 3: Скопируйте столбцы и типы данных в оператор создания таблицы
У меня есть лист Excel, который я использую для форматирования вывода sp_help в оператор «создать таблицу». Вам не нужно ничего такого, что нужно, просто скопируйте и вставьте в свой редактор SQL. Используйте имена столбцов, размеры и типы для создания оператора «Create table #x [...]» или «Declare @x Table [...]», который можно использовать для ВСТАВКИ результатов хранимой процедуры.
Шаг 4: Вставить во вновь созданную таблицу
Теперь у вас будет запрос, аналогичный другим решениям, описанным в этой теме.
Этот метод также можно использовать для преобразования временной таблицы (
#temp
) в табличную переменную (@temp
). Хотя это может быть больше шагов, чем просто написаниеcreate table
оператора, это предотвращает ручные ошибки, такие как опечатки и несоответствия типов данных в больших процессах. Отладка опечатки может занять больше времени, чем написание запроса.источник
Если OPENROWSET вызывает у вас проблемы, есть другой путь, начиная с 2012 года; использовать sys.dm_exec_describe_first_result_set_for_object, как упомянуто здесь: Получить имена столбцов и типы хранимых процедур?
Сначала создайте эту хранимую процедуру, чтобы сгенерировать SQL для временной таблицы:
Чтобы использовать процедуру, вызовите ее следующим образом:
Обратите внимание, что я использую глобальную временную таблицу. Это связано с тем, что при использовании EXEC для запуска динамического SQL создается собственный сеанс, поэтому обычная временная таблица выходит за рамки любого последующего кода. Если глобальная временная таблица является проблемой, вы можете использовать обычную временную таблицу, но любой последующий SQL должен быть динамическим, то есть также выполняемым оператором EXEC.
источник
@SQL
.Quassnoi поставил меня большую часть пути туда, но одна вещь отсутствовала:
**** Мне нужно было использовать параметры в хранимой процедуре. ****
И OPENQUERY не позволяет этому случиться:
Таким образом, я нашел способ работать с системой, а также не нужно делать определение таблицы настолько жестким, и переопределить его внутри другой хранимой процедуры (и, конечно, воспользоваться шансом, что она может сломаться)!
Да, вы можете динамически создать определение таблицы, возвращенное из хранимой процедуры, с помощью оператора OPENQUERY с фиктивными переменными (пока параметр NO RESULT SET возвращает то же количество полей и в той же позиции, что и набор данных с хорошими данными).
После создания таблицы вы можете использовать хранимую процедуру exec во временной таблице в течение всего дня.
И чтобы отметить (как указано выше), вы должны включить доступ к данным,
Код:
Спасибо за информацию, которая была предоставлена первоначально ... Да, наконец, мне не нужно создавать все эти поддельные (строгие) определения таблиц при использовании данных из другой хранимой процедуры или базы данных, и да, вы также можете использовать параметры.
Поиск тегов ссылок:
Хранимая процедура SQL 2005 во временную таблицу
openquery с хранимой процедурой и переменными 2005
openquery с переменными
выполнить хранимую процедуру во временной таблице
Обновление: это не будет работать с временными таблицами, поэтому мне пришлось прибегнуть к созданию временной таблицы вручную.
Заметим, что это не будет работать с временными таблицами , http://www.sommarskog.se/share_data.html#OPENQUERY
Ссылка: Следующим шагом является определение LOCALSERVER. В примере это может выглядеть как ключевое слово, но на самом деле это только имя. Вот как вы это делаете:
Чтобы создать связанный сервер, вы должны иметь разрешение ALTER ANY SERVER или быть членом какой-либо из фиксированных ролей сервера sysadmin или setupadmin.
OPENQUERY открывает новое соединение с SQL Server. Это имеет некоторые последствия:
Процедура, которую вы вызываете с помощью OPENQUERY, не может ссылаться на временные таблицы, созданные в текущем соединении.
Новое соединение имеет собственную базу данных по умолчанию (определенную с помощью sp_addlinkedserver, по умолчанию - master), поэтому все спецификации объекта должны включать имя базы данных.
Если у вас есть открытая транзакция и вы удерживаете блокировки, когда вызываете OPENQUERY, вызываемая процедура не может получить доступ к тому, что вы заблокировали. То есть, если вы не будете осторожны, вы заблокируете себя.
Подключение не бесплатное, поэтому снижается производительность.
источник
SELECT @@SERVERNAME
. Вы можете также использоватьEXEC sp_serveroption @@SERVERNAME, 'DATA ACCESS', TRUE
Если вам повезло иметь SQL 2012 или выше, вы можете использовать
dm_exec_describe_first_result_set_for_object
Я только что отредактировал sql, предоставленный gotqn. Спасибо, получил.
Это создает глобальную временную таблицу с именем, совпадающим с именем процедуры. Временная таблица может позже использоваться по мере необходимости. Только не забудьте бросить его перед повторным выполнением.
источник
sys.all_objects
вместо,sys.procedures
если вы хотите сделать это для встроенных хранимых процедур.Этот сохраненный процесс выполняет работу:
Это небольшая переделка: вставьте результаты хранимой процедуры в таблицу, чтобы она действительно работала .
Если вы хотите, чтобы он работал с временной таблицей, вам нужно будет использовать
##GLOBAL
таблицу и затем удалить ее.источник
Чтобы вставить первый набор записей хранимой процедуры во временную таблицу, вам необходимо знать следующее:
sp_executesql
)Вышеупомянутое может выглядеть как ограничение, но ИМХО это вполне имеет смысл - если вы используете,
sp_executesql
вы можете один раз вернуть два столбца и один раз десять, а если у вас есть несколько наборов результатов, вы также не можете вставить их в несколько таблиц - вы можете вставить максимум в две таблицы в одном операторе T-SQL (используяOUTPUT
предложение и без триггеров).Таким образом, проблема заключается в том, как определить структуру временной таблицы перед выполнением
EXEC ... INTO ...
оператора.Первый работает, в
OBJECT_ID
то время как второй и третий работают также со специальными запросами. Я предпочитаю использовать DMV вместо sp, поскольку вы можете использоватьCROSS APPLY
и создавать временные определения таблиц для нескольких процедур одновременно.Также обратите внимание на
system_type_name
поле, так как оно может быть очень полезным. В нем хранится полное определение столбца. Например:и вы можете использовать его напрямую в большинстве случаев для создания определения таблицы.
Итак, я думаю, что в большинстве случаев (если хранимая процедура соответствует определенным критериям) вы можете легко построить динамические операторы для решения таких проблем (создать временную таблицу, вставить в нее результат хранимой процедуры, сделать то, что вам нужно с данными) ,
Обратите внимание, что вышеприведенные объекты не могут определить данные первого результирующего набора в некоторых случаях, например, когда выполняются динамические операторы T-SQL или временные таблицы используются в хранимой процедуре.
источник
Теперь я знаю, каков результат моей процедуры, поэтому я выполняю следующий запрос.
ЗНАЧЕНИЯ (10, 5, 1, NULL) SET IDENTITY_INSERT [dbo]. [TblTestingTree] Вкл.
источник
Если запрос не содержит параметра, используйте
OpenQuery
else useOpenRowset
.Основная вещь будет состоять в том, чтобы создать схему согласно хранимой процедуре и вставить в эту таблицу. например:
источник
Код
Надеюсь, это поможет. Пожалуйста, квалифицируйтесь соответствующим образом.
источник
Я обнаружил, что передача массивов / таблиц данных в хранимые процедуры может дать вам другое представление о том, как вы можете решить свою проблему.
Ссылка предлагает использовать параметр типа Image для перехода в хранимую процедуру. Затем в хранимой процедуре изображение преобразуется в табличную переменную, содержащую исходные данные.
Может быть, есть способ, которым это можно использовать с временной таблицей.
источник
Я столкнулся с той же проблемой, и вот что я сделал для этого по предложению Павла . Основная часть здесь заключается в использовании,
NEWID()
чтобы избежать одновременного запуска процедур / сценариев несколькими пользователями, что является проблемой для глобальной временной таблицы.источник
Другой метод заключается в создании типа и использовании PIPELINED для последующей передачи вашего объекта. Однако это ограничено знанием столбцов. Но у него есть преимущество:
источник
Это простой двухэтапный процесс: - создать временную таблицу - вставить во временную таблицу.
Код для выполнения такой же:
источник
После поиска я нашел способ динамически создать временную таблицу для любой хранимой процедуры, не используя
OPENROWSET
или неOPENQUERY
используя общую схему определения результата хранимой процедуры, особенно когда вы не являетесь администратором базы данных.Сервер Sql имеет встроенный
sp_describe_first_result_set
процесс, который может предоставить вам схему любого набора результатов процедур. Я создал таблицу схемы из результатов этой процедуры и вручную установил все поля в NULLABLE.Вы можете настроить схему для используемой версии сервера SQL (при необходимости).
источник
Если вам известны параметры, которые передаются, и если у вас нет доступа к программе sp_configure, то отредактируйте хранимую процедуру с этими параметрами, и ее можно сохранить в глобальной таблице ##.
источник
Это можно сделать в SQL Server 2014+, если хранимая процедура возвращает только одну таблицу. Если кто-нибудь найдет способ сделать это для нескольких столов, я бы хотел узнать об этом.
Это извлекает определение возвращаемой таблицы из системных таблиц и использует его для создания временной таблицы. Затем вы можете заполнить его из хранимой процедуры, как указано выше.
Есть также варианты этого, которые также работают с динамическим SQL.
источник
Несколько лет назад к вопросу, но мне нужно что-то подобное для быстрой и грязной генерации кода. Я полагаю, что, как уже говорили другие, просто определить временную таблицу проще, но этот метод должен работать для простых запросов хранимых процедур или SQL-отчетов.
Это будет немного запутанным, но оно заимствует из авторов здесь, а также решение Пола Уайта из DBA Stack Exchange Получить типы столбцов результата хранимой процедуры . Опять же, чтобы повторить этот подход и пример не предназначен для процессов в многопользовательской среде. В этом случае определение таблицы задается на короткое время в глобальной временной таблице для ссылки процессом шаблона генерации кода.
Я не полностью проверил это, поэтому могут быть предупреждения, поэтому вы можете перейти по ссылке MSDN в ответе Пола Уайта. Это относится к SQL 2012 и выше.
Сначала используйте хранимую процедуру sp_describe_first_result_set, которая напоминает описание Oracle.
Это позволит оценить первую строку первого набора результатов, поэтому, если ваша хранимая процедура или оператор возвращает несколько запросов, она будет описывать только первый результат.
Я создал сохраненный процесс, чтобы разбить задачи, которые возвращают одно поле для выбора, чтобы создать определение временной таблицы.
Загадка заключается в том, что вам нужно использовать глобальную таблицу, но вы должны сделать ее достаточно уникальной, чтобы вы могли часто создавать ее и создавать, не беспокоясь о столкновении.
В примере я использовал Guid (FE264BF5_9C32_438F_8462_8A5DC8DEE49E) для глобальной переменной, заменяя дефисы подчеркиванием
Опять же, я протестировал его только с простыми запросами хранимых процедур и простыми запросами, поэтому ваш пробег может отличаться. Надеюсь, это кому-нибудь поможет.
источник
Что ж, вам нужно создать временную таблицу, но у нее не должно быть правильной схемы .... Я создал хранимую процедуру, которая изменяет существующую временную таблицу, чтобы в ней были необходимые столбцы с правильными данными. тип и порядок (удаление всех существующих столбцов, добавление новых столбцов):
Обратите внимание, что это не будет работать, если sys.dm_exec_describe_first_result_set_for_object не может определить результаты хранимой процедуры (например, если она использует временную таблицу).
источник
Если вы позволите динамическому SQL создавать временную таблицу, эта таблица будет принадлежать соединению Dynamic SQL, а не соединению, из которого вызывается ваша хранимая процедура.
Сообщение 208, уровень 16, состояние 0 Неверное имя объекта "#Pivoted". Это потому, что #Pivoted принадлежит подключению Dynamic SQL. Итак, последняя инструкция
выходит из строя.
Один из способов избежать этой проблемы - убедиться, что все ссылки на #Pivoted сделаны внутри самого динамического запроса:
источник
Я бы сделал следующее
Создать (преобразовать SP в) UDF (табличное значение UDF).
select * into #tmpBusLine from dbo.UDF_getBusinessLineHistory '16 Mar 2009'
источник