在另一个具有动态查询的存储过程中使用具有动态查询的存储过程的结果
Using result of Stored Procedure with dynamic query in another Stored Procedure with dynamic query
我在创建使用用户定义类型的存储过程并构建要在存储过程结束时执行的动态查询时遇到问题。
我以前这样做过,但这次不同。我正在构建一个动态聚合 SELECT 语句,该语句必须(动态地)调用另一个存储过程并使用内联结果。
由于其他存储过程也使用动态SQL,因此不能在用户自定义函数中定义。
我现在将在 SQL 代码中展示问题示例,希望对您有所帮助。
第一个存储过程:
CREATE PROCEDURE [dbo].[SP1]
...--(some uder defined types)
AS
DECLARE @SQLQuery AS NVARCHAR(MAX);
...--(some cursors used in assembling the dynamic query)
...--(at some point I have a check whether there are additional filter criteria)
SET @SQLQuery = @SQLQuery + '(SELECT COUNT([Column]) FROM [TableX]';
IF(EXISTS(SELECT TOP (1) FilterCriteria FROM @additionalCriteriaTable))
BEGIN
SET @SQLQuery = @SQLQuery = 'AND [IdOfTableX] IN (EXEC [dbo].[SP2] @param1, @param2 ...)';
END
SET @SQLQuery = @SQLQuery + ')';
存储过程 2 用于确定 [TableX] 的哪些行符合任何给定条件,还使用一些游标和动态查询。 SP2 returns 这些行的 IDS。
很清楚,我正在以错误的方式解决这个问题,因为您不能从存储过程内联 select。但是,您可以从用户定义的函数中进行,但是您不能在那里使用我需要的动态 SQL 。
有没有一种方法可以内联使用存储过程的结果,也许是通过使用一种注释形式来定义存储过程仅 returns 一个特定的结果集?
希望大家能帮帮我,
杰伦干杯
您可以将存储过程的结果插入临时 table 并稍后在查询中使用 table。
像这样:
IF EXISTS (SELECT * FROM @additionalCriteriaTable)
BEGIN
SET @SQLQuery = '
CREATE TABLE #temp ...
INSERT INTO #temp EXEC [dbo].[SP2] @param1, @param2 ...'
+ @SQLQuery + ' AND [IdOfTableX] IN (SELECT Something FROM #temp)';
END
您只需要小心创建与存储过程的结果具有完全相同结构的临时 table(您不能省略任何列或更改列的顺序)。
你确定这是你想要的吗:
In your code:
SET @SQLQuery = @SQLQuery = 'AND [IdOfTableX] IN (EXEC [dbo].[SP2] @param1, @param2 ...)';
@sqlquery 将无法正确构建。
您可能会发现最好让调用存储过程创建一个临时 table,然后将其填充到嵌套调用中。它不一定是全局的 table 才能可见,但您不能在 SP2 中创建它,否则它会在 SP1 有机会引用它之前消失。
我在创建使用用户定义类型的存储过程并构建要在存储过程结束时执行的动态查询时遇到问题。 我以前这样做过,但这次不同。我正在构建一个动态聚合 SELECT 语句,该语句必须(动态地)调用另一个存储过程并使用内联结果。
由于其他存储过程也使用动态SQL,因此不能在用户自定义函数中定义。
我现在将在 SQL 代码中展示问题示例,希望对您有所帮助。
第一个存储过程:
CREATE PROCEDURE [dbo].[SP1]
...--(some uder defined types)
AS
DECLARE @SQLQuery AS NVARCHAR(MAX);
...--(some cursors used in assembling the dynamic query)
...--(at some point I have a check whether there are additional filter criteria)
SET @SQLQuery = @SQLQuery + '(SELECT COUNT([Column]) FROM [TableX]';
IF(EXISTS(SELECT TOP (1) FilterCriteria FROM @additionalCriteriaTable))
BEGIN
SET @SQLQuery = @SQLQuery = 'AND [IdOfTableX] IN (EXEC [dbo].[SP2] @param1, @param2 ...)';
END
SET @SQLQuery = @SQLQuery + ')';
存储过程 2 用于确定 [TableX] 的哪些行符合任何给定条件,还使用一些游标和动态查询。 SP2 returns 这些行的 IDS。
很清楚,我正在以错误的方式解决这个问题,因为您不能从存储过程内联 select。但是,您可以从用户定义的函数中进行,但是您不能在那里使用我需要的动态 SQL 。 有没有一种方法可以内联使用存储过程的结果,也许是通过使用一种注释形式来定义存储过程仅 returns 一个特定的结果集?
希望大家能帮帮我,
杰伦干杯
您可以将存储过程的结果插入临时 table 并稍后在查询中使用 table。
像这样:
IF EXISTS (SELECT * FROM @additionalCriteriaTable)
BEGIN
SET @SQLQuery = '
CREATE TABLE #temp ...
INSERT INTO #temp EXEC [dbo].[SP2] @param1, @param2 ...'
+ @SQLQuery + ' AND [IdOfTableX] IN (SELECT Something FROM #temp)';
END
您只需要小心创建与存储过程的结果具有完全相同结构的临时 table(您不能省略任何列或更改列的顺序)。
你确定这是你想要的吗:
In your code:
SET @SQLQuery = @SQLQuery = 'AND [IdOfTableX] IN (EXEC [dbo].[SP2] @param1, @param2 ...)';
@sqlquery 将无法正确构建。
您可能会发现最好让调用存储过程创建一个临时 table,然后将其填充到嵌套调用中。它不一定是全局的 table 才能可见,但您不能在 SP2 中创建它,否则它会在 SP1 有机会引用它之前消失。