从.Net的另一个存储过程中调用“无效列”

时间:2019-05-22 18:20:33

标签: .net sql-server stored-procedures

我在现有存储过程(“父”)的末尾添加了对SQL Server存储过程的调用(我们称其为“子”)。从SSMS在我的帐户下以及在生产环境中运行proc的服务帐户下运行时,子级和父级(又包括子级)都可以成功运行。

当我使用SqlClient.SqlCommand.ExecuteNonQuery()直接从.Net应用程序运行子级时,它成功运行。但是,当我使用相同的连接运行父级时,它将失败,并从子级中出现“无效列'X'”错误。

我确认的事情:

  • 子级中对X的每个引用都别名为相关视图或表,并且异常返回的“行号”实际上并不是包含X的查询的行。

  • 所有表/视图都包含此列

  • 在大多数情况下,子proc本身可以成功运行,甚至在父proc内也可以成功运行

  • 所有帐户都具有执行,选择和插入所需数据的适当权限

  • 父级已经从与子级相同的Database.schema中运行其他存储过程

为什么只有从.Net应用程序调用时,此proc才会引发错误?

1 个答案:

答案 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();