可能重复:
检索存储过程结果集的列定义
我使用以下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'
Run Code Online (Sandbox Code Playgroud)
如何为存储过程的输出列执行类似的操作?
Aar*_*and 91
[我刚才意识到我之前已回答过这个问题 ]
对存储过程执行此操作比查看视图或表格要复杂得多.其中一个问题是存储过程可能有多个不同的代码路径,具体取决于输入参数,甚至是你无法控制的东西,如服务器状态,时间等等.例如,你期望看到的输出是什么这个存储过程?如果有多个结果集而不管条件限制怎么办?
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
Run Code Online (Sandbox Code Playgroud)
如果您的存储过程没有代码路径,并且您确信您将始终看到相同的结果集(并且如果存储过程具有非可选参数,则可以提前确定应提供哪些值),让我们举一个简单的示例:
CREATE PROCEDURE dbo.bar
AS
BEGIN
SET NOCOUNT ON;
SELECT a = 'a', b = 1, c = GETDATE();
END
GO
Run Code Online (Sandbox Code Playgroud)
一种方法是做这样的事情:
SET FMTONLY ON;
GO
EXEC dbo.bar;
Run Code Online (Sandbox Code Playgroud)
这将为您提供一个空结果集,您的客户端应用程序可以查看该结果集的属性以确定列名称和数据类型.
现在,有很多问题SET FMTONLY ON;我不会在这里讨论,但至少应该注意这个命令已被弃用 - 这是有充分理由的.完成后也要小心SET FMTONLY OFF;,否则你会想知道为什么你成功创建了一个存储过程但是却无法执行它.不,我没有警告你,因为它刚好发生在我身上.诚实.:-)
通过创建一个环回链接服务器,您可以使用类似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';
Run Code Online (Sandbox Code Playgroud)
现在我们可以采用上面的过程并将其提供给这样的查询:
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');
Run Code Online (Sandbox Code Playgroud)
这会忽略别名类型(以前称为用户定义的数据类型),也可能会为列定义为两行,例如,sysname.但从上面它产生:
name name
---- --------
b int
c datetime
a varchar
Run Code Online (Sandbox Code Playgroud)
显然还有更多的工作在这里做- varchar不显示长度,你必须得精度/规模为其他类型,比如datetime2,time和decimal.但这是一个开始.
SQL Server 2012中有一些新功能可以使元数据发现更加容易.对于上述过程,我们可以执行以下操作:
SELECT name, system_type_name
FROM sys.dm_exec_describe_first_result_set_for_object
(
OBJECT_ID('dbo.bar'),
NULL
);
Run Code Online (Sandbox Code Playgroud)
除此之外,这实际上提供了精度和规模,并为我们解析了别名类型.对于上述过程,这会产生:
name system_type_name
---- ----------------
a varchar(1)
b int
c datetime
Run Code Online (Sandbox Code Playgroud)
视觉上差别不大,但当您开始进入具有各种精度和规模的所有不同数据类型时,您将会欣赏此功能为您提供的额外工作.
缺点:在SQL Server 2012中,至少这些函数仅适用于第一个结果集(如函数名称所示).
| 归档时间: |
|
| 查看次数: |
73695 次 |
| 最近记录: |