如何访问在TSQL中调用存储过程生成的当前作用域中的数据集?

Tri*_*nko 8 t-sql scope dynamic-data temp-tables

问题背景

生成和访问固定列布局的数据很容易.您可以预先创建本地临时表,并通过调用存储过程来填充它们.

另一方面,如果要生成具有动态列布局的数据,则通常必须动态构建SQL语句并使用"exec sp_executesql"执行它.由于数据布局在运行时是未知的,因此您无法在前面创建临时表,并且一旦在"exec sp_executesql"语句中,在那里创建的任何临时表都绑定到该范围并在调用返回时消失,因此访问数据要困难得多(即您的选择更加有限).

我的具体情况

我有一个查询需要访问动态生成的表中的数据.

由一个存储过程,其动态地构建的查询生成的表,它在一个变量"@sql为nvarchar(最大)"存储,并通过调用"EXEC sp_executesql的@statement = @sql"运行它.

@sql语句类似于"select*into #temptable from ...",但#temptable在"exec sp_executesql"返回时被销毁.对此的快速解决方法是仅使用"## temptable"(即全局临时表),因为它在存储过程返回时仍然存在并且我可以在调用范围中轻松访问它(因为它具有已知/静态名称) ).

我不喜欢这个解决方案,因为全局临时表不是线程安全的(名称冲突),我不想乱用动态生成的唯一名称,因为我最终不得不使用更多动态SQL来访问它们......这使我回到正方形,使数据在SP外部无法访问.

我不认为返回表变量(通过输出参数)是一个选项(对SQL Server 2008也是新的),除非可以在不必定义静态表类型的情况下完成.我的存储过程生成的表是动态的,并且取决于传递的输入参数.

内联表值函数是不是一种选择,因为我运行的代码循环来构建@sql查询和调用"EXEC sp_executesql的".

多语句表值函数(而不是存储过程)也不是一个选项,因为这样的函数必须有一个明确定义的表格式,而我正在运行dyanmic SQL来返回一个变量数量为列和列名称取决于输入参数值.

我真正想做的就是将动态查询的结果集选择到一个新表中,但我发现它很难,因为以上都没有; 特别令人恼火的是本地临时表不是会话本地的,而是存储过程的本地临时表,以便它们在返回时消失.我见过的唯一解决方案坚持认为使用OPENROWSET是唯一的方法,但我不想弄乱我的存储过程中的连接字符串,出于同样的原因我不想包含唯一名称管理代码. ..它应该比它应该的更复杂.

总之,我只想执行生成未知格式数据集的动态SQL,并能够从调用范围轻松访问它.

gbn*_*gbn 1

在 之前创建临时表sp_executesql:它仍然在“内部”范围内,例如sp_executesql

将 SQL 更改为执行 anINSERT而不是SELECT..INTO...

编辑:

让表格足够宽以涵盖所有选项。

坦率地说,SQL 设计用于处理固定表定义:可变输出签名(表)会导致您遇到的问题......

  • 正确的。这就是为什么我在这里发帖来寻找这些选项。我在这里找到了一个很好的选项细分... http://www.sommarskog.se/share_data.html 在一篇关于“在存储过程之间共享数据”的文章中,但我仍然希望/致力于更好的解决方案。OPENROWSET 选项仍然很好,因为它似乎完全支持我想要做的事情(直接从动态查询中选择到一个临时表中),但我讨厌性能影响和必须管理 SP 内部连接的语法。 (2认同)