如何获取存储过程以输出从 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;