在開發過程的中,我們經常要用到Oracle游標來進行相關的統計(不用臨時表)並且返回其統計結果,但是游標的後面SQL語句往往是動態的,例如select * from tablename where ?order ?."?"代表條件,這樣該如何處理呢?
在同事的幫助下我實踐了一下。總結出來。
假設tablename表中有fIEld如下:
- fIEld1 varchar2(50)
- fIEld2 Varchar2(50)
- fIEld3 Varchar(50)
- fIEld4 varchar2(50)
- fIEld5 varchar2(20)
- fIEld6 float,
- fIEld7 float
1.定義游標
- create or replace package RefCursor is
- -- Author : Ricky
- -- Created : 2003-9-1 14:08:45
- -- Purpose :
- -- Public type declarations
- type t_RefCursor is ref cursor;
- end RefCursor;
2.創建類型
創建的類型與tablename中表的fields一致,當然也要看你實際是否要統計所有的fIElds.
- create or replace type TableType as object
- (
- -- Author : Ricky
- -- Created : 2003-8-25 9:12:08
- -- Purpose :
- -- Attributes
- fIEld1 varchar2(50),
- fIEld2 Varchar2(50),
- fIEld3 Varchar(50),
- fIEld4 varchar2(50),
- fIEld5 varchar2(20),
- fIEld6 float,
- fIEld7 float
- );
3.創建表類型
- create or replace type TableTypeList as table of TableType;
4.在存儲過程或者函數中使用,下面在函數中使用(存儲過程中不能用return一個表結構,要用到臨時表)
- CREATE OR REPLACE FUNCTION "TEST" (
- return TableTypeList pipelined as
- begin
- v_Cur RefCursor.t_Refcursor;
- v_SQLStatement string(10000);
- v_Table tablename%rowtype;
- tmp1 tablename.fIEld1%Type;
- tmp2 tablename.fIEld2%Type;
- tmp3 tablename.fIEld3%Type;
- tmp4 tablename.fIEld4%Type;
- tmp5 tablename.fIEld5%Type;
- tmp6 tablename.fIEld6%Type;
- tmp7 tablename.fIEld6%Type;
- v_SQLStatement := 'Select * From tablename where fIEld1='1' order by fIEld1';
- open v_Cur for v_SQLStatement;
- loop
這裡是循環過程
- fetch v_Cur into v_Comm;
- exit when v_CommCur%notfound;
這裡是你要處理的統計過程,中間的過程我沒有做統計,各位在實踐中按需要自己添加。
- fIEld1 = v_Cur.fIEld1;
- fIEld2 = v_Cur.fIEld2;
- fIEld3 = v_Cur.fIEld3;
- fIEld4 = v_Cur.fIEld4;
- fIEld5 = v_Cur.fIEld5;
- fIEld6 = v_Cur.fIEld6;
- fIEld7 = v_Cur.fIEld7;
- v_Table = TableType(fIEld1,
- fIEld2,
- fIEld3,
- fIEld4,
- fIEld5,
- fIEld6,
- fIEld7)
- pipe row(v_Table);
- end loop
- end;