惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Google DeepMind News
Google DeepMind News
Stack Overflow Blog
Stack Overflow Blog
Hugging Face - Blog
Hugging Face - Blog
博客园_首页
T
The Blog of Author Tim Ferriss
博客园 - 叶小钗
N
Netflix TechBlog - Medium
腾讯CDC
C
Check Point Blog
P
Proofpoint News Feed
Engineering at Meta
Engineering at Meta
GbyAI
GbyAI
S
SegmentFault 最新的问题
F
Fortinet All Blogs
美团技术团队
U
Unit 42
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
博客园 - 司徒正美
F
Full Disclosure
Recorded Future
Recorded Future
D
DataBreaches.Net
博客园 - 【当耐特】
Martin Fowler
Martin Fowler
J
Java Code Geeks
I
InfoQ
Y
Y Combinator Blog
A
About on SuperTechFans
AI
AI
爱范儿
爱范儿
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Forbes - Security
Forbes - Security
W
WeLiveSecurity
M
MIT News - Artificial intelligence
雷峰网
雷峰网
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Simon Willison's Weblog
Simon Willison's Weblog
Schneier on Security
Schneier on Security
The GitHub Blog
The GitHub Blog
Security Archives - TechRepublic
Security Archives - TechRepublic
aimingoo的专栏
aimingoo的专栏
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
G
GRAHAM CLULEY
Know Your Adversary
Know Your Adversary
Latest news
Latest news
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
D
Docker
Recent Commits to openclaw:main
Recent Commits to openclaw:main
量子位
V2EX - 技术
V2EX - 技术
Project Zero
Project Zero

博客园 - 山娃

Oracle ORA-01722: 无效数字 处理方法 PB程序系统错误处理记录 网上摘录(琐碎信息) 网上摘录 网上摘录 数据分组处理 Oracle 要点摘录 如何用Powerdesigner的PDM(物理数据模型)生成数据库及逆向工程(将现有的数据库生成PDM)(转) Oracle中返回结果集的存储过程(转帖 网摘) Oracle to_timestamp 函数测试(摘录,转帖) Oracle 查询历史数据(转帖) Oracle REF Cursor 用法(转帖) Oracle PL/SQL中如何使用%TYPE和%ROWTYPE(转帖) Oracle中的Instance实例和数据库的区别 . 转帖 建立与Oracle数据库服务器连接的两种连接模式(专用服务器与共享服务器) .转帖 Oracle10g数据库的4种存储形式 .转帖 PB “Row changed between retrieve and update” 经典错误处理。 转帖 PLSQLDEV 中修改主表和子表的主键,外键信息 oracle查询表信息(索引,外键,列等。。) 转帖 人生规划(网摘)
存储过程中如何使用另一个存储过程返回的结果集 网络转帖
山娃 · 2012-10-19 · via 博客园 - 山娃

与这个问题具有相同性质的其他描述还包括:
如何在存储过程中检索动态SQL语句的执行结果?
如何实现类似SELECT * FROM (EXEC procedure_name @parameters_var) AS datasource WHERE ... 的功能?
procedure_name是一个存储过程的名字,@parameters_var是过程参数
如何将一个存储过程的执行结果记录集传递给另一个存储过程?
存储过程中如何根据另一个存储过程的执行结果选择执行流程?
存储过程中如何根据动态SQL语句的查询结果更改执行流程?
一个存储过程A使用另一个存储过程B的名字(或一段SQL语句或一个不确定的表名,字段名)作为参数,如何在不改动存储过程B的情况下,对存储过程B的执行结果记录集进行过滤/更改,再将过滤/更改后的结果集返回给存储过程A的调用者?

上面这些问题都有一个共同点,那就是都希望对存储过程(或动态SQL语句)的执行结果进行再处理,但是标准的SQL语句只能处理数据表,而一个存储过程(或动态SQL语句)的执行结果虽然是记录集,但它们本身不能当做数据表来处理。这样就大大限制了存储过程(或动态SQL语句)的应用范围,它们只能作为将记录集返回给应用程序前的最后一个处理层。如果我们可以像使用普通的数据表那样使用存储过程(或动态SQL语句)该有多好。
这个问题我以前的解决方法是使用OPENQUERY()或OPENDATASOURCE(),但OPENQUERY()不仅要求建立一个链接服务器,而且执行性能也让人无法满意。OPENDATASOURCE()则要求提供连接字符串,这对系统后期的维护也是一个很大的麻烦。
今天使用SQL Server联机丛书时无意中发现了一条SQL语句,竟然非常方便的解决了这个问题。这个语句就是INSERT语句。
INSERT语句在帮助中的定义是这样的:

INSERT [ INTO]
{ table_name WITH ( < table_hint_limited > [ ...n ] )
| view_name
| rowset_function_limited
}

{ [ ( column_list ) ]
{ VALUES
( { DEFAULT | NULL | expression } [ ,...n] )
| derived_table
| execute_statement
}
}
| DEFAULT VALUES

其中execute_statement的解释是"任何有效的 EXECUTE 语句,它使用 SELECT 或 READTEXT 语句返回数据。"。通常我们放在这个位置的就是一段SELECT语句。但帮助既然说"任何有效的 EXECUTE 语句",那么"EXEC procedure_name"也应该可以罗?想到这一点,马上决定动手验证一下。验证结果证实没问题。即下面这样的语句

INSERT INTO table_name EXEC procedure_name @parameters_var

确实可以正常工作。有了这个基础,我们也就有了解决本文开头那些问题的方法。

基本思路是先创建一个临时表,通过INSERT ... EXEC ...语句将存储过程的返回结果保存到临时表中,接下来就可以像处理普通数据表那样对待这个临时表了。对于动态SQL语句,可以通过dbo.sp_executesql存储过程执行,或者直接作为EXEC的参数执行。具体的编写要求可以参考SQL Server联机丛书。这里只特别说明一下,临时表的表结构与存储过程(或动态SQL语句)返回的记录集的表结构兼容即可,不要求完全相同。如果直接通过EXEC执行动态SQL语句,SQL语句有4K的长度限制。

最后给出两种最常见的处理流程:
1。创建一个临时表#tmp,表结构与目标存储过程procedure_name的返回结果集兼容(兼容即可,不必相同)。
CREATE TABLE #tmp(
[columns_list]
)
2。执行存储过程并将存储过程的返回结果集插入临时表。
INSERT INTO #tmp EXEC procedure_name @parameters_var
3。现在可以使用(过滤,更改或检索)#tmp了。^_^
IF EXISTS(SELECT * FROM #tmp)
BEGIN
--执行分支1
END ELSE BEGIN
--执行分支2
END
4。别忘了最后清除临时表。
DROP TABLE #tmp

对于动态SQL语句,只要将第二步改为
INSERT INTO #tmp EXEC dbo.sp_executesql @querystring_var
即可。