How to retrieve multiple rows from a stored function with oracle

前端 未结 3 826
一个人的身影
一个人的身影 2021-01-06 07:43

I\'m trying to create a stored function in oracle that returns multiple rows.

My question is very similar to this one except that I want to fetch a select *

相关标签:
3条回答
  • 2021-01-06 08:24

    If you are using PHP and you want to access a oracle stored function. You can make use of something like this

    //Your connection details
    $conn = oci_connect($username, $password, '(DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = 127.0.0.1)(PORT = 1521))(CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = XE)))' );
    
    /* Your query string; you can use oci_bind_by_name to bind parameters or just pass the variable in it*/
    
    $query = "begin :cur := functionName('".$param1."','".$param2."','".$param3."'); end;";
    $stid = oci_parse($conn, $query); 
    $OUTPUT_CUR = oci_new_cursor($conn);
    oci_bind_by_name($stid, ':cur', $OUTPUT_CUR, -1, OCI_B_CURSOR);
    oci_execute($stid); 
    oci_execute($OUTPUT_CUR);
    oci_fetch_all($OUTPUT_CUR, $res);
    
    // To get your result  
    var_dump($res);
    
    

    I hope this helps.

    0 讨论(0)
  • 2021-01-06 08:27

    with SQL types you cant do %ROWTYPE, you'd have to type each column to match the table*.

    *sys.anydataset aside. but going down that route is a lot more complex coding.

    e.g. if your table was

    create table foo (id number, cola varchar2(1));
    

    then

    create type email_queue_type is object (id number, cola varchar2(1));
    /
    create type t_email_queue_type as table of email_queue_type;
    /
    

    and use that table email_queue_type_tab as the output from your function.

    but i'd recommend a pipelined function, as your current code isn't scalable.

    eg:

    SQL> create table foo (id number, cola varchar2(1));
    
    Table created.
    
    SQL>
    SQL> create type email_queue_type is object (id number, cola varchar2(1));
      2  /
    
    Type created.
    
    SQL> create type t_email_queue_type as table of email_queue_type;
      2  /
    
    Type created.
    
    SQL> insert into foo select rownum, 'a' from dual connect by level <= 10;
    
    10 rows created.
    
    SQL>
    SQL> create or replace PACKAGE email_queue AS
      2
      3
      4    FUNCTION lock_and_get return t_email_queue_type pipelined;
      5
      6  END email_queue;
      7  /
    
    Package created.
    
    SQL> create or replace PACKAGE BODY email_queue AS
      2
      3      FUNCTION lock_and_get RETURN t_email_queue_type pipelined AS
      4        queue_obj t_email_queue_type;
      5
      6      BEGIN
      7
      8       for r_row in (select * from foo)
      9              loop
     10                pipe row(email_queue_type(r_row.id, r_row.cola));
     11              end loop;
     12
     13      END lock_and_get;
     14
     15  END email_queue;
     16  /
    
    Package body created.
    
    SQL> select * from table(email_queue.lock_and_get());
    
            ID C
    ---------- -
             1 a
             2 a
             3 a
             4 a
             5 a
             6 a
             7 a
             8 a
             9 a
            10 a
    
    10 rows selected.
    
    SQL>
    
    0 讨论(0)
  • 2021-01-06 08:30

    If you aren't particularly keen on having the SQL type, you could do this with a sys_refcursor instead:

    create or replace package email_queue as 
        function lock_and_get return sys_refcursor;
    end email_queue;
    /
    
    create or replace package body email_queue as 
        function lock_and_get return sys_refcursor AS 
            c sys_refcursor;
            lockid varchar2(100) := 'alf';
        begin
            open c for
                select * from t_email_queue
                where lockedby = lockid;
    
             return c;
        end lock_and_get;
    end email_queue;
    /
    

    From SQL*Plus you could call it something like:

    var cur refcursor;
    exec :cur := email_queue.lock_and_get;
    print cur
    

    and as exec is shorthand for a simple anonymous block you can call if from other PL/SQL objects too. What you can't do, though, is:

    select * from table(email_queue.lock_and_get);
    

    I'm not familiar with calling functions from PHP, but from Java you can use this directly as the return from a callable statement, so you don't need the select * from table() construct at all. I have no idea if you can execute an anonymous block in a PHP call, something like begin $cur = email_queue.lock_and_get; end;, and have $cur as your result set that you can then iterate through?

    I realise this isn't a complete answer as the PHP side is way too vague, but might give you some ideas.

    0 讨论(0)
提交回复
热议问题