#sql #sql-server #sql-server-2016
Вопрос:
У меня есть пользовательский тип таблицы tyAnalysisNumbers
. Мне нужно заполнить свой определенный пользователем тип данных в хранимой процедуре SELECT
инструкцией, и я изо всех сил пытаюсь заставить ее работать в моей хранимой процедуре.
Следующие способы, которые я пробовал, не работают
DECLARE @MyTable tyAnalysisNumbers;
INSERT INTO @MyTable
EXEC ('SELECT * FROM ' @someTable);
Я получаю эту ошибку:
Инструкция INSERT EXEC не может быть вложенной
Я не уверен, как вставить в свою пользовательскую таблицу с помощью инструкции select.
Может ли кто-нибудь помочь мне в этом?
Комментарии:
1. В целом это должно сработать, так что в вашем сценарии будет больше событий, не включенных в ваш сценарий. Добавьте полный пример к вашему вопросу, который воспроизводит ошибку.
2. У меня есть две хранимые процедуры, родительская, которая вызывает дочернюю. Дочерний sp, над которым я работаю, использует пользовательскую таблицу, работает как есть, вы правы. Но он должен быть вызван из родительской хранимой процедуры в нашем приложении, в которой запускаются следующие строки: ` ВСТАВИТЬ В @resultsTable выполнить транзакцию фиксации дочернего хранилища ВЫБЕРИТЕ * ИЗ @resultsTable Конец Попробуйте начать Перехватывать, если XACT_STATE() <> 0 ` ` В этот момент ошибки регистрируются в отладочных событиях, и именно там я вижу ошибку
An INSERT EXEC statement cannot be nested
.3. Что такое
@someTable
? Название постоянной таблицы? Табличная переменная, объявленная ранее в коде? ТВП?4. @someTable-это имя схемы и таблицы, постоянное, а не временное.
5. Это все, что делает вложенная хранимая процедура? Вставьте выходные данные из какой-либо таблицы в тип таблицы, а затем выберите ее? Зачем беспокоиться о типе таблицы? Если есть другие вещи, которые происходят до окончательного выбора, пожалуйста, включите эту информацию и не скрывайте ее и не заглушайте. Возможно, решение состоит в том, чтобы просто выполнять все в динамической области SQL (или, если набор операций, выполняемых после заполнения типа, велик и/или список
@someTable
возможностей невелик, могут быть и другие решения).
Ответ №1:
Инструкция INSERT EXEC не может быть вложенной
Приведенная выше ошибка объясняется сама собой. Пожалуйста, посмотрите на приведенный ниже сценарий:
Например, у нас есть одна процедура, которая вставляет данные в тип таблицы и возвращает результат.
CREATE PROCEDURE uspInsertData1
AS
BEGIN
DECLARE @MyTable tyAnalysisNumbers;
INSERT INTO @MyTable
EXEC ('SELECT * FROM someTable');
select * from @MyTable
END
Теперь предположим, что у нас есть другая процедура, которая вызовет описанную выше процедуру и снова вставит данные в другую таблицу.
CREATE PROCEDURE uspInsertData2
AS
BEGIN
DECLARE @MyTable tyAnalysisNumbers;
INSERT INTO sometable
EXEC uspInsertData1
END
Теперь, если вы выполните 1-ю процедуру, она будет работать нормально, но если вы выполните вторую процедуру, вы получите эту ошибку.
Инструкция INSERT EXEC не может быть вложенной.
Потому что теперь у вас есть вложенные операторы EXEC.
Я предлагаю завершить вашу работу в одной хранимой процедуре, если это возможно.
Комментарии:
1. Это объясняет проблему операции, но не является решением.
2. @AaronBertrand Согласен.. Но у меня есть и такие сценарии, но я никогда не предпочитаю и не предлагаю называть такие вложенные процедуры. Я всегда избегаю таких вложенных вызовов, чтобы предотвратить такие побочные эффекты. Я предлагаю завершить вашу работу в одной хранимой процедуре.
Ответ №2:
Попробуй вот так:
DECLARE @MyTable tyAnalysisNumbers;
SELECT * INTO #Temp FROM @MyTable;
DECLARE @tblName AS SYSNAME = (SELECT name FROM sys.tables WHERE name = @someTable);
EXEC ('INSERT INTO #Temp SELECT * FROM ' @tblName);
Это также решает проблему внедрения SQL.