Я придумал немного клуджа (хорошо, это большой клудж), основанный на том факте, что вы не можете иметь вложенные операторы INSERT--EXECUTE
.... По сути, если ваша «проблемная» процедура является целью INSERT--EXECUTE
, а сама содержит INSERT--EXECUTE
, то возникнет ошибка. Чтобы это работало, вам нужно было бы (вполне возможно, бессмысленно) вызвать INSERT--EXECUTE
в процедуре и обернуть его в блок TRY--CATCH
с соответствующей обработкой. Неуклюжий и тупой, но если ничего не подойдет, стоит попробовать.
Используйте следующее, чтобы проверить это. Это создаст три процедуры:
IF objectproperty(object_id('dbo.Foo1'), 'isProcedure') = 1
DROP PROCEDURE dbo.Foo1
IF objectproperty(object_id('dbo.Foo2'), 'isProcedure') = 1
DROP PROCEDURE dbo.Foo2
IF objectproperty(object_id('dbo.Foo3'), 'isProcedure') = 1
DROP PROCEDURE dbo.Foo3
GO
-- Returns a simple data set
CREATE PROCEDURE Foo1
AS
SET NOCOUNT on
SELECT name
from sys.databases
GO
-- Calls Foo1, loads data into a local temp table, then returns those contents
CREATE PROCEDURE Foo2
AS
SET NOCOUNT on
CREATE TABLE #Temp (DBName sysname not null)
BEGIN TRY
INSERT #Temp (DBName)
EXECUTE Foo1
END TRY
BEGIN CATCH
IF ERROR_NUMBER() = 8164
PRINT 'Nested INSERT EXECUTE'
ELSE
PRINT 'Unanticipated err: ' + cast(ERROR_NUMBER() as varchar(10))
END CATCH
SELECT *
from #Temp
GO
-- Calls Foo2, loads data into a local temp table, then returns those contents
CREATE PROCEDURE Foo3
AS
SET NOCOUNT on
CREATE TABLE #Temp2 (DBName sysname not null)
INSERT #Temp2 (DBName)
EXECUTE Foo2
SELECT *
from #Temp2
GO
EXECUTE Foo1
вернет «базовый» набор данных.
EXECUTE Foo2
вызовет Foo1, загрузит данные во временную таблицу и затем вернет содержимое этой таблицы.
EXECUTE Foo3
пытается сделать то же самое, что и Foo2, но вызывает Foo2. Это приводит к вложенной ошибке INSERT--EXECUTE
, которая обнаруживается и обрабатывается TRY--CATCH
.
в Foo2.