sql – 为什么从存储过程中选择不支持关系数据库?
众所周知,您无法从Oracle或SQL Server(以及大部分其他主流的RDBMS产品)中的存储过程执行SELECT.
一般来说,从存储过程中选择几个明显的“问题”,只需要考虑两个: a)存储过程产生的列是不确定的(直到运行时才知道) b)由于存储过程的不确定性,建立数据库统计和制定高效的查询计划将会出现问题 由于用户经常希望使用此功能,因此随着时间的推移,已经开发了许多解决方法: http://www.club-oracle.com/threads/select-from-stored-procedure-results.3147/ http://www.sommarskog.se/share_data.html SQL Server特别具有OPENROWSET功能,允许您加入或从几乎任何内容中进行选择:https://msdn.microsoft.com/en-us/library/ms190312.aspx 但是,DBA的安全原因往往很不情愿. 所以对我的问题:虽然有一些明显的问题或性能考虑涉及允许联接或选择存储过程,是否有一些基本的技术原因为什么这种能力不支持RDBMS平台? 编辑: 编辑2: 解决方法TL; DR:您可以从(表值)函数中选择,或从PostgreSQL中的任何类型的函数中进行选择.但不是存储过程.这是一个“直观的”,有点数据库不可知的解释,因为我相信SQL及其许多方言是一个有机成长的语言/概念,因为这是一个基本的“科学”解释. 程序与功能,历史上 我没有真正看到从存储过程中选择的点,但是我受到多年的经验和接受现状的偏见,我当然看到程序和功能之间的区别如何混淆,以及他们希望如何更加多才多艺.特别在SQL Server,Sybase或MySQL中,过程可以返回任意数量的结果集/更新计数,尽管这与返回定义良好的类型的函数不同. 将程序视为必要的例程(具有副作用)和函数作为纯粹的例程而没有副作用. SELECT语句本身也是“纯”而没有副作用(除了潜在的锁定效果之外),所以将函数看作可以在SELECT语句中使用的唯一的例程类型是有意义的. 实际上,将函数看作是对行为有很强限制的例程,而允许程序执行任意程序. 4GL与3GL语言 另一种看待这种情况的方法是从SQL的角度来看是一个4th generation programming language (4GL).如果4GL在很大程度上受到限制,它只能合理地工作. Common Table Expressions made SQL turing-complete,但SQL的声明性仍然阻碍了它从实用的每一天的角度来看是一种通用语言. 存储的程序是规避此限制的一种方式.有时,你想要完整和实用.因此,存储过程需要重视,具有副作用,事务性等. 存储的功能是将一些3GL /程序语言特性引入到更纯粹的4GL世界中的一种聪明的方法,其价格在于禁止其中的副作用(除非您想要打开潘多拉的盒子并具有完全不可预测的SELECT语句). 某些数据库允许其存储过程返回任意数量的结果集/游标的事实是它们允许任意行为(包括副作用)的特征.原则上说,我所说的都不会在存储的函数中阻止这种特定的行为,但如果允许在SQL 4GL语言的上下文中这样做,这将是非常不实际和难以管理的. 从而: 程序可以调用程序,任何函数和SQL 但: >“纯”函数调用过程变成“不纯”函数(如过程) 和: > SQL无法调用过程 “纯”表值函数的示例: 以下是使用表值的“纯”函数的一些示例: 神谕 CREATE TYPE numbers AS TABLE OF number(10); / CREATE OR REPLACE FUNCTION my_function (a number,b number) RETURN numbers IS BEGIN return numbers(a,b); END my_function; / 接着: SELECT * FROM TABLE (my_function(1,2)) SQL Server CREATE FUNCTION my_function(@v1 INTEGER,@v2 INTEGER) RETURNS @out_table TABLE ( column_value INTEGER ) AS BEGIN INSERT @out_table VALUES (@v1),(@v2) RETURN END 接着 SELECT * FROM my_function(1,2) PostgreSQL的 让我在PostgreSQL上有一个字. PostgreSQL是非常棒的,因此是一个例外.这也很奇怪,大概50%的功能不应该在生产中使用.它只支持“功能”而不是“程序”,但这些功能可以作为任何事情.查看以下内容: CREATE OR REPLACE FUNCTION wow () RETURNS SETOF INT AS $$ BEGIN CREATE TABLE boom (i INT); RETURN QUERY INSERT INTO boom VALUES (1) RETURNING *; END; $$LANGUAGE plpgsql; 副作用: >创建表 然而: SELECT * FROM wow(); 产量 wow --- 1 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |