如何获取存储过程以输出从 SQL*Plus 中的 select 语句返回的表?
Posted
技术标签:
【中文标题】如何获取存储过程以输出从 SQL*Plus 中的 select 语句返回的表?【英文标题】:How do I get a stored procedure to output the table that gets returned from a select statement in SQL*Plus? 【发布时间】:2017-02-27 20:21:43 【问题描述】:我想在我的数据库中获取有关用户的信息。
这就是我所拥有的:
表:
create table Users(
userID int CHECK (userID > 0),
email varchar2(30) NOT NULL,
age varchar2(30) NOT NULL,
numberBookedSoFar int,
primary key(userID)
);
程序:
CREATE or REPLACE PROCEDURE user_info() AS
BEGIN
SELECT age, COUNT(userid) AS numberofusers,
AVG(numberbookedsofar) AS avgbooked
FROM users
GROUP BY age;
END;
但是,什么都没有发生。
【问题讨论】:
那会得到一个编译错误,而不是什么都没有。您使用的是哪个版本的 Oracle? (为什么要使用子查询?) 请更清楚,你有什么来源,你需要实现什么 你的程序运行一个查询,但你没有要求它做更多的事情。 那么,我需要做什么才能输出结果表? 您可以在 Oracle 12c 中执行此操作(注意这需要 12c 客户端):***.com/a/40360471/230471 【参考方案1】:编辑
据我了解,您需要从存储函数返回表
CREATE TYPE users_obj IS OBJECT (age varchar2(30), numberofusers int, avgbooked numeric);
CREATE TYPE users_t IS TABLE OF users_obj;
CREATE or REPLACE FUNCTION user_info RETURN users_t
IS
users_table users_t := users_t();
n INT := 0;
BEGIN
FOR i IN (SELECT age, COUNT(userid) AS numberofusers, AVG(numberbookedsofar) AS avgbooked FROM users GROUP BY age) -- < here is your query
LOOP
users_table.EXTEND;
n := n + 1;
users_table(n) := users_obj(i.age, i.numberofusers, i.avgbooked);
END LOOP;
RETURN users_table;
END;
-- So, now you can call function which returns result as table
SELECT * FROM TABLE (user_info);
【讨论】:
是的,确实如此。我自己运行了查询,但是当我尝试运行时没有任何反应。【参考方案2】:我喜欢使用包中定义的类型。这允许我在一个紧凑的命名空间中将类型组合在一起。我不会比其他答案更好,只是不同。这是一个例子:
CREATE OR REPLACE PACKAGE deleteme_pkg
AS
TYPE example_t IS RECORD
(
text VARCHAR2 (10)
, textlength INTEGER
);
TYPE example_tt IS TABLE OF example_t;
FUNCTION sample
RETURN example_tt
PIPELINED;
END deleteme_pkg;
CREATE OR REPLACE PACKAGE BODY deleteme_pkg
AS
-- Very contrived, in practice, the rows will be from a select statement
FUNCTION sample
RETURN example_tt
PIPELINED
AS
l_rec example_t;
BEGIN
l_rec.text := 'This';
l_rec.textlength := LENGTH (l_rec.text);
PIPE ROW (l_rec);
l_rec.text := 'is';
l_rec.textlength := LENGTH (l_rec.text);
PIPE ROW (l_rec);
l_rec.text := 'a';
l_rec.textlength := LENGTH (l_rec.text);
PIPE ROW (l_rec);
l_rec.text := 'test';
l_rec.textlength := LENGTH (l_rec.text);
PIPE ROW (l_rec);
END sample;
END deleteme_pkg;
-- now select from the package function
select * from table(deleteme_pkg.sample);
【讨论】:
【参考方案3】:只是上述答案的变体。使用批量收集。希望这会有所帮助。
CREATE OR REPLACE type CUSTOM_OBJ
IS
object
(
AGE NUMBER,
USER_ID NUMBER,
AVG_BOOKED NUMBER
);
CREATE OR REPLACE TYPE custom_tab
IS
TABLE OF CUSTOM_OBJ;
CREATE OR REPLACE
FUNCTION USER_INFO
RETURN CUSTOM_TAB
AS
tab custom_tab;
BEGIN
SELECT custom_obj(age,numberofusers,AVGBOOKED) BULK COLLECT
INTO tab
FROM
(SELECT age,
COUNT(userid) AS numberofusers,
AVG(NUMBERBOOKEDSOFAR) AS AVGBOOKED
FROM users
);
RETURN TAB;
END;
【讨论】:
以上是关于如何获取存储过程以输出从 SQL*Plus 中的 select 语句返回的表?的主要内容,如果未能解决你的问题,请参考以下文章