码迷,mamicode.com
首页 > 数据库 > 详细

function dynamic fetch in Oracle

时间:2015-11-29 19:33:19      阅读:185      评论:0      收藏:0      [点我收藏+]

标签:

In coding, we often meet some sql queries like ‘ select many cloumns from tablename where condition; ‘. When the number of cloumns is dynamic, we should use ResultSet to achieve in Java. As we all know, the class ResultSet has been defined in Java class library. We can use it to get the result of query with optional cloumns directly. However, we now in Oracle/PLSQL, and if we want to get the same effect as Java, we should get one better way to solve that. You may think about using cursor to achieve you want. Actually, you will realized that‘s not exactly what you think. There is one solution for what we said, the following function makes full use of cursor to get what we want.

 

create or replace function func_dynamic_fetch 
(   p_sql in varchar2, 
    p_no_of_cols integer,  
    p_return_multiple_row boolean := true)
return anydatalist is 
    lc_rs sys_refcursor;
    strlist varchar2List := varchar2List();
    n number := 3;
    code varchar2(32767);
    TYPE ref_cursor IS REF CURSOR;
    rc_         ref_cursor;  
    c_          NUMBER;
    i_          NUMBER;
    col_count_  NUMBER;
    desc_tab_   DBMS_SQL.DESC_TAB2;
    col_num  NUMBER;
    n2 number;
    l_any_list anydatalist;
    l_types varchar2list; 
    l_add_stmts varchar2list;
    l_fetch_type varchar2(32767);
    c_date_type constant number := 12;
    c_timestamp_type constant number := 180;


    function repeatStmt(n in integer, template in varchar2, seperator in varchar2 := ‘‘, vals in varchar2list := null) return varchar2 is
        l_result varchar2(32767);
        l_stmt varchar2(32767);
    begin
        for i in 1..n loop
            l_stmt := template;
            if vals is not null then
                l_stmt := replace(template, ‘__val__‘, vals(i)); 
            end if;
            l_result := l_result || replace(l_stmt, ‘__$__‘, i); 
            if i < n then
                l_result := l_result || seperator;
            end if;
        end loop;
        return l_result;
    end repeatStmt;
begin  
    open rc_ for p_sql;  
    n2 := p_no_of_cols;
    c_ := DBMS_SQL.to_cursor_number(rc_);
    DBMS_SQL.DESCRIBE_COLUMNS2(c_, col_count_, desc_tab_);
    col_num := desc_tab_.first;
    l_types := varchar2list();
    l_add_stmts := varchar2list();
    if col_num is not null then
        loop
            if desc_tab_(col_num).col_type = c_date_type or desc_tab_(col_num).col_type =c_timestamp_type then 
                varchar2listAdd(l_types, ‘date‘);
                --to conform to jdbc date format 
                varchar2listAdd(l_add_stmts, ‘varchar2ListAdd(l_str_list, to_char(a__$__, ‘‘yyyy-mm-dd hh:mi:ss‘‘));‘);
            else 
                varchar2listAdd(l_types, ‘varchar2(32767)‘);
                varchar2listAdd(l_add_stmts, ‘varchar2ListAdd(l_str_list, a__$__);‘);
            end if;
            col_num:= desc_tab_.next(col_num);
            exit when (col_num is null);
        end loop;
    end if;

    --dbms_output.put_line(‘cursor count: ‘ || col_count_);
    n := col_count_; 
    if n2 > n then 
        n2 := n; 
    end if;
    --dbms_output.put_line(‘number of columns: ‘ || n );
    --dbms_output.put_line(‘number of columns to fetch: ‘ || n2 );
    dbms_sql.close_cursor(c_);
    --if rc_%isopen then 
    --    close rc_;
    --end if;
    code := 
    ‘ declare
        lc_rs sys_refcursor;
        l_sql varchar2(32767);
        l_str_list varchar2list; 
        l_counter integer;
        l_any_list anydatalist; ‘ ||  
        repeatStmt(n, ‘a__$__ __val__; ‘,  seperator => chr(10), vals => l_types) || ‘
      begin
        l_sql := :0;
        --dbms_output.put_line(l_sql);
        open lc_rs for l_sql;
        l_any_list := anydatalist();
        l_counter := 0; 
        loop
            fetch lc_rs into ‘ || repeatStmt(n, ‘a__$__‘, ‘, ‘) || ‘;‘ || ‘
            exit when lc_rs%notfound;
            l_counter := l_counter + 1; 
            l_str_list := varchar2List();‘ || 
            --repeatStmt(n2, ‘varchar2ListAdd(l_str_list, a__$__);‘, chr(10), vals => l_types) || ‘
            repeatStmt(n2, ‘__val__‘, chr(10), vals => l_add_stmts) || ‘
            anydataListAdd(l_any_list, anydata.convertCollection(l_str_list)); ‘ || 
            (case when p_return_multiple_row = false then 
            ‘exit when l_counter = 1;‘
            end) || ‘
        end loop;
        if lc_rs%isopen then 
            close lc_rs;
        end if;
        :1 := l_any_list;
      exception when others then  
        dbms_output.put_line(‘‘ func_dynamic_fetch exec immediate exception: ‘‘ || sqlerrm);
        raise;
        if lc_rs%isopen then close lc_rs; end if;
      end;
    ‘ ; 
    --dbms_output.put_line(code);
    execute immediate code using p_sql, out l_any_list;
    return l_any_list;
exception when others then 
    if rc_%isopen then close rc_; end if; 
    dbms_output.put_line(‘func_dynamic_fetch: exception: ‘ || sqlerrm);
    return anydatalist();
end;
 /
show errors;

 

function dynamic fetch in Oracle

标签:

原文地址:http://www.cnblogs.com/Jeffrey-xu/p/5005204.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!