1. 程式人生 > >oracle返回表型別

oracle返回表型別

一.用自定義型別實現

1、建立表物件型別。

   在Oracle中想要返回表物件,必須自定義一個表型別,如下所示:

Sql程式碼  

create or replace type type_table is table of number;   

上面的型別定義好後,在function使用可用返回一列的表,稍後介紹返回多列的

2、 建立函式

在函式的定義中,可以使用管道化表函式和普通的方式,下面提供兩種使用方式的程式碼:

1)、管道化表函式方式:

Sql程式碼  

create or replace function f_pipe  

(s number)  

return type_table pipelined  

as    

begin      

    for i in 1..s loop   

    pipe row(i);   

end loop;  

return;  

end f_pipe;  

注意:管道的方式必須使用空的return表示結束.

呼叫函式的方式如下:

2)、 普通的方式:

Sql程式碼  

create or replace function f_normal  

(s number)  

return type_table  

as  

    rs type_table:= type_table();  

begin  

    for i in 1..s loop  

        rs.extend;  

        rs(rs.count) := i;  

    end loop;  

return rs;  

end f_normal;  

呼叫方式如下:

Sql程式碼  

select * from table(f_normal(5));  

如果需要多列的話,需要先定義一個物件型別。可以把物件型別替換上面語句中的number;

定義物件型別:

Sql程式碼  

create or replace type type_row as object  

(  

  id int,  

  name varchar2(50)  

)  

修改表物件型別的定義語句如下:

Sql程式碼  

create or replace type type_table is table of type_row;  

1)、管道化表函式方式:

Sql程式碼  

create or replace function f_pipe(s number)  

return type_table pipelined  

as  

    v_type_row type_row;     

begin      

for i in 1..s loop   

    v_type_row :=  type_row(i,to_char(i*i));  

    pipe   row(v_type_row);     

end loop;  

return;  

end f_pipe;  

 測試:select * from table(f_pipe(5));

2)、 普通的方式:

Sql程式碼  

create or replace function f_normal(s number)  

return type_table  

as  

    rs type_table:= type_table();  

begin  

    for i in 1..s loop  

        rs.extend;  

        rs(rs.count) := type_row(rs.count,'name'||to_char(rs.count));  

    --Result(Result.count) := type_row(NULL,NULL);  

        --rs(rs.count).name := rs(rs.count).name || 'xxxx';  

    end loop;  

return rs;  

end f_normal;  

  測試:select * from table(f_normal(5));

其他程式碼段

把許可權(和)值拆分成多條記錄

Sql程式碼  

create or replace type type_table_number is table of number;   

create or replace function f_right_table(  

    rights number  

)  

    --自定義table型別 --pipelined 管道關鍵字  

    return type_table_number pipelined     

as     

begin  

    --呼叫方法:select column_value as right from table(f_right_table(power(2,15)*2-2));     

    for i in 1..15 loop    

      IF bitand(rights,power(2,i))=power(2,i) THEN  

         pipe row(power(2,i)); --pipe row 特定寫法,輸出記錄  

      END IF;    

    end loop;  

return;  

end f_right_table;  

一種遍歷資料的方法,

只是演示myrow,myrow 就相當於一個臨時變數

Java程式碼  

for myrow in (  

      select 2 as right from dual where bitand(rights,2)=2  

      union  

      select 4 as right from dual where bitand(rights,4)=4  

) loop  

      rs.extend;  

      rs(rs.count) := myrow.right;  

end loop;  

二.其他實現

包裡面用一個儲存過程,返回遊標,就可以了

>包的定義

1) 包頭

Sql程式碼  

create or replace package mypk    

as    

type t_cursor is ref cursor;    

procedure proc(name varchar2,c out t_cursor,a number);    

end;  

2) 包體

Sql程式碼  

create or replace package body mypk    

as    

procedure proc(name varchar2,c out t_cursor,a number)    

as     

begin    

open c for select * from test where id=a and name=name;    

end proc;    

end;  

這個方案的侷限性太大,無法實現select * from function()的要求

呼叫:

Sql程式碼  

declare  

    cur_out_arg mypk.t_cursor;  

    rec_arg test%rowtype;  

begin  

    mypk.proc('abc',cur_out_arg,3);  

  --open cur_out_arg;           

    loop             

      --提取一行資料到rec_arg             

      fetch cur_out_arg into rec_arg;             

      --判讀是否提取到值,沒取到值就退出             

      --取到值cur_out_arg%notfound 是false              

      --取不到值cur_out_arg%notfound 是true             

      exit when cur_out_arg%notfound;              

      dbms_output.put_line(rec_arg.id||'-'||rec_arg.name);           

    end loop;         

  --關閉遊標        

  close cur_out_arg;  

end;