检索存储过程的列名和类型?

可能重复:
检索存储过程结果集的列定义

我使用以下SQL来获取表或视图的列名和类型:

DECLARE @viewname varchar (250);

select a.name as colname,b.name as typename 
from syscolumns a, systypes b -- GAH!
where a.id = object_id(@viewname) 
and a.xtype=b.xtype 
and b.name <> 'sysname'

如何为存储过程的输出列做类似的事情?


[我刚刚意识到我已经回答了这个问题]

为存储过程做这件事情要比视图或表格复杂得多。 其中一个问题是存储过程可能会有多个不同的代码路径,具体取决于输入参数,甚至是您无法控制的事情,例如服务器状态,一天中的时间等。例如,您希望看到的输出为这个存储过程? 如果有多个结果集,而不考虑条件?

CREATE PROCEDURE dbo.foo
  @bar INT
AS
BEGIN
  SET NOCOUNT ON;

  IF @bar = 1
    SELECT a, b, c FROM dbo.blat;
  ELSE
    SELECT d, e, f, g, h FROM dbo.splunge;
END
GO

如果您的存储过程没有代码路径,并且您确信总是会看到相同的结果集(并且可以预先确定在存储过程具有非可选参数时应提供哪些值),我们举一个简单示例:

CREATE PROCEDURE dbo.bar
AS
BEGIN
  SET NOCOUNT ON;

  SELECT a = 'a', b = 1, c = GETDATE();
END
GO

FMTONLY

一种方法是做这样的事情:

SET FMTONLY ON;
GO
EXEC dbo.bar;

这会给你一个空的结果集,你的客户端应用程序可以查看结果集的属性来确定列名和数据类型。

现在, SET FMTONLY ON;有很多问题SET FMTONLY ON; 我不会进入这里,但至少应该指出,这个命令已被弃用 - 这是有原因的。 还要小心SET FMTONLY OFF; 当你完成时,或者你会想知道为什么你成功创建了一个存储过程,但是不能执行它。 不,我没有警告你,因为它发生在我身上。 诚实。 :-)

OPENQUERY

通过创建一个环回链接的服务器,你可以使用像OPENQUERY这样的工具来执行一个存储过程,但返回一个可组合的结果集(当然,请接受它作为一个非常松散的定义),你可以检查。 首先创建一个回送服务器(假设一个名为FOO的本地实例):

USE master;
GO
EXEC sp_addlinkedserver @server = N'.FOO', @srvproduct=N'SQL Server'
GO
EXEC sp_serveroption @server=N'.FOO', @optname=N'data access', 
  @optvalue=N'true';

现在我们可以执行上面的过程并将它提供给像这样的查询:

SELECT * INTO #t 
FROM OPENQUERY([.FOO], 'EXEC dbname.dbo.bar;')
WHERE 1 = 0;

SELECT c.name, t.name
FROM tempdb.sys.columns AS c
INNER JOIN sys.types AS t
ON c.system_type_id = t.system_type_id
WHERE c.[object_id] = OBJECT_ID('tempdb..#t');

这会忽略别名类型(以前称为用户定义的数据类型),并且可能会为列定义为两行,例如sysname 。 但从上面它产生:

name   name
----   --------
b      int
c      datetime
a      varchar

很明显,这里有更多的工作要做 - varchar不显示长度,并且必须为其他类型(如datetime2timedecimal获取精度/缩放比例。 但这是一个开始。

SQL Server 2012

SQL Server 2012中有一些新的功能使元数据发现更容易。 对于上述过程,我们可以执行以下操作:

SELECT name, system_type_name
FROM sys.dm_exec_describe_first_result_set_for_object
(
  OBJECT_ID('dbo.bar'), 
  NULL
);

除此之外,这实际上提供了精确度和规模,并为我们解决了别名类型。 对于上述过程,得出:

name   system_type_name
----   ----------------
a      varchar(1)
b      int
c      datetime

在视觉上差异不大,但当您开始使用各种精度和比例进入所有不同的数据类型时,您会欣赏此功能为您所做的额外工作。

缺点:在SQL Server 2012中,至少这些函数仅适用于第一个结果集(如函数名所示)。


您是否试图返回所有存储过程及其所有参数? 像这样的东西应该为此工作。

select * from information_schema.parameters

如果您需要获取从存储过程返回的列,请查看此处:

获取从存储过程返回的列名/类型

链接地址: http://www.djcxy.com/p/24739.html

上一篇: Retrieve column names and types of a stored procedure?

下一篇: How to access dataset in current scope generated by a call to a stored procedure in TSQL?