【问题标题】:Oracle SQL Stored Procedure Returning SetOracle SQL 存储过程返回集
【发布时间】:2014-06-23 10:48:51
【问题描述】:

我认为这很简单。

我有一张表 People,其中包含 NameSurnameAge 列。

我想要一个存储过程GetPersonsBySurname

  • 输入 -> 一组姓氏
  • 输出 -> 该组姓氏中的人的姓名、姓氏和年龄。

提前谢谢你。

现在我有了这个...我可以编写一个只有一个姓氏的存储过程... 我想要一组姓氏...

这是我的代码

表格

CREATE TABLE "PEOPLE" 
(
    "NAME" VARCHAR2(255 BYTE), 
    "SURNAME" VARCHAR2(255 BYTE), 
    "AGE" NUMBER(*,0)
)

标题

create or replace PACKAGE "MYPACK" IS 

TYPE r_output IS RECORD 
(     

    name varchar2(255), 
    surname  varchar2(255), 
    age varchar2(255)

);

TYPE CURS_R_OUTPUT IS REF CURSOR
  RETURN r_output;

PROCEDURE GetPersonsBySurname ( mysurname in varchar2,
                                    OUT_P_CUR                       OUT CURS_R_OUTPUT,
                                    OUT_ESITO                       OUT VARCHAR2,
                                    OUT_MESSAGGIO                   OUT VARCHAR2
);

END MYPACK;

身体

create or replace PACKAGE BODY "MYPACK" 
IS
PROCEDURE GetPersonsBySurname  ( mysurname in varchar2,
                                    OUT_P_CUR                       OUT CURS_R_OUTPUT,
                                    OUT_ESITO                       OUT VARCHAR2,
                                    OUT_MESSAGGIO                   OUT VARCHAR2
                                    )
AS     
BEGIN

  OPEN OUT_P_CUR FOR
      select p.name, p.surname, p.age
      from people p
      where p.surname = mysurname ;


 EXCEPTION
 WHEN NO_DATA_FOUND 
 THEN
     OUT_ESITO := 'OK';
     OUT_MESSAGGIO := 'No data found';

 WHEN OTHERS
 THEN
     OUT_ESITO := 'KO';
     OUT_MESSAGGIO := 'ERROR';

 END GetPersonsBySurname;

 END MYPACK;

【问题讨论】:

  • 欢迎来到 StackOverflow。请提出具体问题,展示您已经编写的代码并解释您的具体问题所在。这不是一个将软件需求和规范从简单的英语变成可运行代码的网站。
  • 嗨,谢谢。我已经更新了我的问题

标签: sql stored-procedures oracle11g


【解决方案1】:

声明自己是架构级别的集合类型:

create or replace type surnames_coll
as
table of varchar2(255 byte)
;

然后在你的包中实现这个存储过程:

procedure GetPersonsByMultipleSurnames
    ( mysurnames                    in surnames_coll
    , out_p_cur                     out curs_r_output
    , out_esito                     out varchar2
    , out_messaggio                 out varchar2 )
as
begin
    open out_p_cur for
      select p.name, p.surname, p.age
      from table(mysurnames) x
          join people p
              on p.surname = X.column_value
    ;
exception
    when others then
        out_esito := 'KO';
        out_messaggio := 'ERROR';
end GetPersonsByMultipleSurnames;

来自 PL/SQL 的,而不是

mypack.GetPersonsBySurname(
    mysurname => 'Esposito',
    out_p_cur => my_p_cur,
    out_esito => my_esito,
    out_messaggio => my_out_messaggio
);

你要打电话

mypack.GetPersonsByMultipleSurnames(
    mysurnames => surnames_coll('Esposito','Grande','con Carne','...'),
    out_p_cur => my_p_cur,
    out_esito => my_esito,
    out_messaggio => my_out_messaggio
);

当然,输出引用游标表明您不会从 PL/SQL 调用它,而是从 Java 或 .NET 或类似的东西调用它。在这种情况下,存储过程可能会有所不同。

测试:

假设您在people 表中插入了以下数据:

insert into people (name, surname, age) values ('Juan', 'Esposito', 1);
insert into people (name, surname, age) values ('Pablo', 'Esposito', 2);
insert into people (name, surname, age) values ('Maria', 'con Carne', 3);
insert into people (name, surname, age) values ('Chili', 'con Carne', 4);
insert into people (name, surname, age) values ('Ernesto', 'Grande', 5);
insert into people (name, surname, age) values ('Pedro', 'Grande', 6);
insert into people (name, surname, age) values ('Che', 'del Puerto', 5);
insert into people (name, surname, age) values ('Rita', 'del Puerto', 6);

然后在 SQL*Plus 中运行姓氏为Espositocon CarneGrande 的简单测试将产生

SQL> var l_people_cursor refcursor;
SQL> var l_esito varchar2(32);
SQL> var l_messagio varchar2(4000);
SQL> 
SQL> begin
  2          mypack.GetPersonsByMultipleSurnames(
  3          mysurnames => surnames_coll('Esposito','Grande','con Carne', '...'),
  4          out_p_cur => :l_people_cursor,
  5          out_esito => :l_esito,
  6          out_messaggio => :l_messagio
  7          );
  8  end;
  9  /

PL/SQL procedure successfully completed.

SQL> 
SQL> print l_esito;

L_ESITO                                                                         
--------------------------------                                                


SQL> print l_messagio;

L_MESSAGIO                                                                      
--------------------------------------------------------------------------------


SQL> 
SQL> col name format a10
SQL> col surname format a20
SQL> 
SQL> print l_people_cursor;

NAME       SURNAME                     AGE                                      
---------- -------------------- ----------                                      
Pablo      Esposito                      2                                      
Juan       Esposito                      1                                      
Pedro      Grande                        6                                      
Ernesto    Grande                        5                                      
Chili      con Carne                     4                                      
Maria      con Carne                     3                                      

6 rows selected.

SQL> 

PS: 你原来函数中的exception when no_data_found then 异常处理程序完全没用。打开游标永远不会引发此异常。

PS#2:在您的out_messagio 中返回'ERROR' 是一种非常糟糕的做法。相反,请转至out_messagio := sqlerrm;

【讨论】:

    猜你喜欢
    • 2023-04-06
    • 1970-01-01
    • 2016-08-19
    • 2016-04-09
    • 1970-01-01
    • 2011-01-31
    • 2019-06-03
    • 2014-08-31
    • 1970-01-01
    相关资源
    最近更新 更多