TSQL - 解析执行计划,用于确定存储过程返回的列

时间:2009-08-10 19:02:48

标签: .net sql-server

有没有办法动态确定(从.NET代码或TSQL)存储过程将返回的列?我想在.NET中为我的存储过程动态生成包装器函数。很容易获得proc名称/参数/等。但我还想知道当一个过程返回数据时(不执行该SP)期望的列。这可能吗?

5 个答案:

答案 0 :(得分:4)

这实际上是出了名的狡猾。它适用于UDF,因为它们具有更强的元数据 - 但存储过程可以做很多令人讨厌的事情:

  • 分支(IF等),返回完全不同的形状
  • 执行另一个存储过程
  • 执行动态sql

非常非常棘手。有两种常见的方法:

  • 尝试解析TSQL;痛苦
  • 使用默认值(null等)执行它并检查结果

SET FMTONLY ON选项通常用于第二个选项(以避免更新等),但请注意系统存储过程仍在执行(可能是xp_sendmail?),因此您冒着做出不需要的事情的风险。

答案 1 :(得分:4)

我已经看到它已经完成了,然后我对客户开发人员大喊大叫,我们已经放弃了这个想法。

说真的,我们遇到了嵌套过程,添加列或参数(供以后使用等)以及其他东西的问题,因为反射第二次猜到了我们的意图。

但是,有关于它的MSDN文章:

编辑:基于其他答案,我们通常不会根据IF语句更改输出。我们将视图存储过程视为方法(当然是明智的),因此需要一个稳定的签名......

答案 2 :(得分:1)

这是一场你必须放松的艰难战斗。想象一下这样的程序:

create procedure usp_foo
     @p int
as
begin
if @p=1
  select col1 from table1;
if @p=2
  select col2 from table2;
if @p=3
  select col3 from table3;
end

答案 3 :(得分:0)

我不这么认为。

根据查询执行计划,您可以确定要在结果中获取哪些列。但是存储过程通常组合了许多查询,并且可以返回多个结果集。

但是,如果您知道您正在处理的每个程序只返回一个结果集,那么您可以“完成工作” - 所以这将是您的惯例。在这种情况下,您可以尝试解析其代码,查找SELECT并确定输出列的列表。

答案 4 :(得分:0)

从视图而不是sproc返回结果的好例子。 (两种方式都有参数,但视图具有很好的属性,如闭包和可预测的结构。)