我在现有存储过程(“父”)的末尾添加了对SQL Server存储过程的调用(我们称其为“子”)。从SSMS在我的帐户下以及在生产环境中运行proc的服务帐户下运行时,子级和父级(又包括子级)都可以成功运行。
当我使用SqlClient.SqlCommand.ExecuteNonQuery()直接从.Net应用程序运行子级时,它成功运行。但是,当我使用相同的连接运行父级时,它将失败,并从子级中出现“无效列'X'”错误。
我确认的事情:
子级中对X的每个引用都别名为相关视图或表,并且异常返回的“行号”实际上并不是包含X的查询的行。
所有表/视图都包含此列
在大多数情况下,子proc本身可以成功运行,甚至在父proc内也可以成功运行
所有帐户都具有执行,选择和插入所需数据的适当权限
父级已经从与子级相同的Database.schema中运行其他存储过程
为什么只有从.Net应用程序调用时,此proc才会引发错误?
答案 0 :(得分:0)
在浏览了探查器的跟踪之后,第一个错误是说其中一个临时表是无效的对象。我在proc中显式创建了该表,而不是使用“插入到”语句并对其进行了修复。
奇怪的是,在任何一个proc中,其他任何“插入”语句都没有发生这种情况。
编辑:
在进一步研究之后,这是因为父级和子级都有一个名为同一名称的临时表,而子级proc正在使用其父级临时表中不存在的任何列更新其临时表。
玩具代码:
CREATE PROCEDURE parent
AS
BEGIN
select top 100 *
into #tempTable
from sys.all_parameters
exec Financial.dbo.child
END
GO
CREATE PROCEDURE child
AS
BEGIN
select *
into #tempTable --changing this temp table name will solve the issue
from sys.all_columns
update #tempTable
set column_id = 1 --this will throw an error when called from .Net code below
where collation_name is null --and this will throw an error when called from .Net code below
END
GO
和.Net:
System.Data.SqlClient.SqlCommand cmd = new SqlCommand("parent", SqlClient.SqlConnection);
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandTimeout = 0;
cmd.ExecuteNonQuery();