如何获取存储过程以输出从 SQL*Plus 中的 select 语句返回的 table?
How do I get a stored procedure to output the table that gets returned from a select statement in SQL*Plus?
我想获取有关我数据库中用户的信息。
这是我的:
Table:
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;
但是,什么也没有发生。
编辑
据我了解,您需要 return table 来自存储函数
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);
我喜欢使用包中定义的类型。这允许我将类型组合在一个紧凑的命名空间中。我不会称这比其他答案更好,只是不同。这是一个例子:
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);
只是上述答案的变体。使用批量收集。希望这有帮助。
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;
我想获取有关我数据库中用户的信息。
这是我的:
Table:
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;
但是,什么也没有发生。
编辑
据我了解,您需要 return table 来自存储函数
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);
我喜欢使用包中定义的类型。这允许我将类型组合在一个紧凑的命名空间中。我不会称这比其他答案更好,只是不同。这是一个例子:
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);
只是上述答案的变体。使用批量收集。希望这有帮助。
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;