从另一个存储过程调用具有交叉应用的存储过程会产生错误 SQL 服务器

Posted

技术标签:

【中文标题】从另一个存储过程调用具有交叉应用的存储过程会产生错误 SQL 服务器【英文标题】:Calling Stored procedure with cross apply from another stored procedure gives error SQL server 【发布时间】:2018-04-12 09:43:12 【问题描述】:

我一直在尝试从另一个存储过程调用存储过程。现在的问题是,底层嵌套存储过程包含带有临时表的 CROSS APPLY,当我直接执行它时它运行良好。

但是当我尝试从其他 SP 调用此 SP 时,它会给出错误,即其中一列无效。在这种情况下,“列名 'levels' 无效”。

另外,当我通过传递参数调用SP SQL窗口执行这个SP时,它运行良好,整个主程序开始顺利运行。

我无法理解为什么会出现此问题。以下是一种供参考的实现。 1.) 主SP

CREATE STORED PROCEDURE ....

INSERT INTO #TempTable
EXEC [Child_SP] @Param1 = 1, @Param2 = 1
...

给出错误。 2.)一旦我从主 PS 执行下面给出的单个语句一次。它开始正常工作。

EXEC [Child_SP] @Param1 = 1, @Param2 = 1

3.) 子 SP 与临时表之一交叉 APLLY。如下所示。

SELECT ID, '1,2,3,4,5' AS levels
INTO #Temp1
FROM ABC

SELECT ID
FROM #Temp1 x0
CROSS APPLY (SELECT * FROM dbo.iter_charlist_to_table(x0.levels, ',') AS x) x1 
WHERE x1.listPos > 1

“iter_charlist_to_table”是表值函数,它从逗号分隔列表中获取值作为表。

它是否与 SQL 线程有关或有什么问题?谢谢。

【问题讨论】:

(在您的第一个 SQL 之后)“出现错误”...?什么错误?我也看不到您在 INSERT 之前创建了一个表,所以这可能就是原因。 错误与帖子中提到的相同。 "无效的列名'levels'" 您需要发布完整的 SQL。我们看不到Child_SP 正在做什么,并且之后您有... 在线,这意味着在EXEC 之后还有进一步的SQL。不要给我们你的代码的 sn-ps,发布整个的东西。 另外,你没有回答这个问题;您的无名程序中有CREATE TABLE #Temptable 语句吗?同样,如果不是,那么就有一个问题。如果不先创建表,您将无法执行INSERT INTO [Table] EXEC [SP]INSERT INTO 不像 INTO 子句那样工作(即SELECT * INTO #TempTable FROM [Table]; Larnu,是的,我已经提到了 CREATE TABLE。我将提供代码的精确副本,因为我无法在此处发布实际代码。谢谢。 【参考方案1】:

我建议使用此代码将您的 tmp 表放在 SP 的开头,因为您的 insert INTO 将始终尝试创建该表,如果该表已经存在则无关紧要。

IF OBJECT_ID('tempdb..#Temp1') IS NOT NULL DROP TABLE #Temp1

如果你分享更多的代码会更有利于理解。

为了以防万一不要忘记将别名放在表上,有时可能不需要此更正,但这是避免查询连接表上的数据时出现问题的好习惯

SELECT x0.ID
FROM #Temp1 x0
CROSS APPLY (SELECT fnAlias.* FROM dbo.iter_charlist_to_table(x0.levels, ',')  fnAlias) x1 
WHERE x1.listPos > 1

【讨论】:

以上是关于从另一个存储过程调用具有交叉应用的存储过程会产生错误 SQL 服务器的主要内容,如果未能解决你的问题,请参考以下文章

MySQL 从另一个存储过程调用存储过程

在 Oracle 中从另一个存储过程调用一个存储过程

从另一个存储过程调用的存储过程中获取第一个结果集

如何传递逗号分隔的输入参数以从另一个存储过程调用存储过程

如何在没有临时表的情况下从另一个存储过程调用存储过程(带参数)

从另一个不工作的线程调用存储过程 c#, EntityFramework