我'm working with stored procedures in SQL Server 2008 and I'已经知道我必须 INSERT INTO
已经预定义的临时表以便处理数据 . 那个's fine, except how do I figure out how to define my temp table, if I' m不是编写存储过程而不是列出其定义并通过代码读取的那个?
例如,我的临时表对于'EXEC sp_stored_procedure'是什么样的?这是一个简单的存储过程,我可能猜测数据类型,但似乎必须有一种方法来只读取执行过程返回的列的类型和长度 .
5 回答
所以假设你在tempdb中有一个存储过程:
有一种非常复杂的方法可以确定存储过程将输出的元数据 . 有几个注意事项,包括该过程只能输出单个结果集,如果无法精确确定数据类型,则会对数据类型进行最佳猜测 . 它需要使用
OPENQUERY
和一个环回链接服务器,并将'DATA ACCESS'
属性设置为true . 您可以检查sys.servers以查看您是否已经拥有有效的服务器,但是我们只需创建一个名为loopback
的手动服务器:现在您可以将其作为链接服务器进行查询,您可以将任何查询的结果(包括存储过程调用)用作常规
SELECT
. 所以你可以这样做(注意数据库前缀很重要,否则你会得到错误11529和2812):如果我们可以执行
SELECT *
,我们也可以执行SELECT * INTO
:一旦#tmp表存在,我们可以通过说(假设SQL Server 2005或更高版本)来确定元数据:
(如果您使用的是SQL Server 2000,则可以使用syscolumns执行类似操作,但我没有2000实例来验证等效查询 . )
结果:
在Denali,这将更加容易得多 . 同样,第一个结果集仍然存在限制,但您不必设置链接服务器并跳过所有这些环节 . 你可以说:
结果:
直到Denali,我建议你可以更容易地卷起袖子并自己找出数据类型 . 这不仅仅是因为完成上述步骤很繁琐,而且还因为您更有可能做出比引擎更正确(或至少更准确)的猜测,因为数据类型猜测引擎所做的将基于运行时输出,没有任何可能值的域的外部知识 . 这个因素在Denali中也是如此,所以不要觉得新的元数据发现功能是最终的结果,它们只是让上面的内容变得不那么乏味了 .
哦,对于
OPENQUERY
的其他潜在问题,请参阅Erland Sommarskog的文章:http://www.sommarskog.se/share_data.html#OPENQUERY
一种不太复杂的方法(在某些情况下可能就足够了):在最终SELECT之后和FROM子句之前编辑原始SP,添加INSERT INTO tmpTable以将SP结果保存在tmpTable中 .
运行修改后的SP,最好使用有意义的参数,以获得实际数据 . 恢复该过程的原始代码 .
现在,您可以从SQL Server management studio获取tmpTable脚本或查询sys.columns以获取字段描述 .
这是我写的一些代码 . 这个想法(正如其他人所说的)是获取SP代码,修改它并执行它 . 但是,我的代码不会更改原始SP .
第一步,获取SP的定义,剥离“创建”部分,并在声明参数后删除“AS”(如果存在) .
(注意基于唯一标识符创建新表名)现在找到代码中的最后一个'From'字,假设这是执行返回结果集的select的代码 .
更改代码以将结果集选择到表中(基于uniqueidentifier的表)
结果集现在在一个表中,表是否为空无关紧要!
让我们得到表的结构
你现在可以用这个做你的魔术
别忘了丢掉那张独特的 table
希望这可以帮助!
看起来在SQL 2012中有一个新的SP来帮助解决这个问题 .
https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-describe-first-result-set-transact-sql
如果你在一个受限制权限的环境中工作,其中回环链接服务器之类的东西似乎是黑魔法并且肯定是“没办法!”,但你对模式有一些权利,只有几个存储过程要处理,这是非常简单的解 .
您可以使用非常有用的 SELECT INTO 语法,该语法将创建一个包含查询结果集的新表 .
假设您的过程包含以下选择查询:
而是将其替换为:
当您执行它时,它将创建一个新表MyOutputTable,其中包含查询返回的结果 .
您只需右键单击其名称即可获得表定义 .
就这样 !
SELECT INTO只需要能够创建新表和也适用于临时表(SELECT ... INTO #MyTempTable),但检索定义可能更难 .
但是当然如果你需要检索数千SP的输出定义,那不是最快的方法:)