通常运用DBMS_SQL包一般分为几步:
1. open cursor: 打开cursor
2. parse cursor:解析你要执行的SQL语句
3. bind variable:如果要执行的SQL语句中包含变量,在此就需要绑定变量
4. execute:执行SQL语句
5. close cursor:在执行后关闭此cursor.
如果你还需要返回执行SQL的结果集,还需要使用define_column,define_array等方法。
下面根据不同情况进行详细展示:
在做展示之前,先准备一些基础数据
create table demo (a number,b number,c number); begin for i in 1 .. 15 loop insert into demo values (round(dbms_random.value, 2) * 100, round(dbms_random.value, 2) * 100, round(dbms_random.value, 2) * 100); end loop; commit; end;
create or replace procedure define_column(no in number) is cursor_name integer := dbms_sql.open_cursor; --在初始化参数时,就可以打开cursor; row_process integer; v_b number; begin --解析要执行的SQL. dbms_sql.parse(cursor_name, 'select * from demo where a= :no', dbms_sql.native); --如果要执行的SQL中不需要参数,则可以省略掉bind_variable-- dbms_sql.bind_variable(cursor_name, 'no', no); /*如果需要返回查询语句的结果,则必须在exec之前使用define_column函数定义返回字段;define_column函数的第一个参数是最初定义的cursor name,第二个参数是指需要返回的字段在查询结果中处于第几列,在此例中返回的字段是查询结果中的第二列,即b列;第三个参数就是接收返回结果需要的变量*/ dbms_sql.define_column(cursor_name, 2, v_b); --必须定义一个参数接收exec的结果 row_process := dbms_sql.execute(cursor_name); loop if dbms_sql.fetch_rows(cursor_name) > 0 then --将前面定义的字段返回给变量v_b-- dbms_sql.column_value(cursor_name, 2, v_b); dbms_output.put_line('B is ' || v_b); else exit; end if; end loop; --数据处理完成后记得要将cursor关闭 dbms_sql.close_cursor(cursor_name); exception when others then dbms_sql.close_cursor(cursor_name); end;
create or replace procedure define_array is c NUMBER; d NUMBER; /*DBMS_SQL.NUMBER_TABLE类型实际就是type NUMBER_TABLE is table of number index by binary_integer;*/ n_tab DBMS_SQL.NUMBER_TABLE; n_tab1 DBMS_SQL.NUMBER_TABLE; indx NUMBER := 1; BEGIN c := DBMS_SQL.OPEN_CURSOR; DBMS_SQL.PARSE(c, 'select * from demo where rownum<13 order by 1', DBMS_SQL.NATIVE); /*在此需要特别介绍一下define_array函数的第一个参数是已经打开的cursor名称, 第二个参数是指需要返回的字段在查询结果中处于第几列,第三个参数就是接收返回结果需要的变量,与define_column不同的是此变量是table,而不是普通的字段类型;第四个参数表示一次可以返回的行数;第五个参数是指n_tab的index从哪个数值开始,此数值是递增的.在此例中index是从1开始的,一次得到9行结果集,则有n_tab(1)到n_tab(9),如果循环再得到新的结果集,则index继续增长n_tab(10)....*/ DBMS_SQL.DEFINE_ARRAY(c, 1, n_tab, 9, indx); DBMS_SQL.DEFINE_ARRAY(c, 2, n_tab1, 9, indx); d := DBMS_SQL.EXECUTE(c); loop d := DBMS_SQL.FETCH_ROWS(c); dbms_output.put_line('fetch rows is ' || d); EXIT WHEN d < 9; DBMS_SQL.COLUMN_VALUE(c, 1, n_tab); DBMS_SQL.COLUMN_VALUE(c, 2, n_tab1); for i in 1 .. d loop dbms_output.put_line(n_tab(i) || ',' || n_tab1(i)); end loop; END LOOP; DBMS_SQL.CLOSE_CURSOR(c); EXCEPTION WHEN OTHERS THEN IF DBMS_SQL.IS_OPEN(c) THEN DBMS_SQL.CLOSE_CURSOR(c); END IF; END;
procedure single_insert(c1 in number, c2 in number, r out number) is cursor_name number := dbms_sql.open_cursor; n number; begin dbms_sql.parse(cursor_name, 'insert into demo values (:a,:b) returning :a*:b into :r', dbms_sql.native); dbms_sql.bind_variable(cursor_name, 'a', c1); dbms_sql.bind_variable(cursor_name, 'b', c2); dbms_sql.bind_variable(cursor_name, 'r', r); n := dbms_sql.execute(cursor_name); --使用variable_value函数得到DML操作returning的结果集 dbms_sql.variable_value(cursor_name, 'r', r); dbms_output.put_line(r); dbms_sql.close_cursor(cursor_name); exception when others then dbms_sql.close_cursor(cursor_name); end;
create or replace package DBMS_SQL_DEMO as procedure multi_insert; end; / create or replace package body DBMS_SQL_DEMO as procedure multi_insert_priv(c1 in dbms_sql.Number_Table, c2 in dbms_sql.Number_Table, r out dbms_sql.Number_Table) is cursor_name number := dbms_sql.open_cursor; n number; begin dbms_sql.parse(cursor_name, 'insert into demo values (:a,:b) returning :a*:b into :r', dbms_sql.native); --使用bind_array函数将number_table类型的变量赋值给绑定变量 dbms_sql.bind_array(cursor_name, 'a', c1); dbms_sql.bind_array(cursor_name, 'b', c2); dbms_sql.bind_array(cursor_name, 'r', r); n := dbms_sql.execute(cursor_name); --使用variable_value函数将returning的结果集赋值给number_table类型的变量 dbms_sql.variable_value(cursor_name, 'r', r); dbms_sql.close_cursor(cursor_name); exception when others then dbms_sql.close_cursor(cursor_name); end; procedure multi_insert is c1 dbms_sql.Number_Table; c2 dbms_sql.Number_Table; cursor_name number := dbms_sql.open_cursor; n number; r dbms_sql.Number_Table; indx number := 1; d number; begin dbms_sql.parse(cursor_name, 'select * from demo', dbms_sql.native); dbms_sql.define_array(cursor_name, 1, c1, 5, indx); dbms_sql.define_array(cursor_name, 2, c2, 5, indx); n := dbms_sql.execute(cursor_name); loop d := dbms_sql.fetch_rows(cursor_name); exit when d = 0; dbms_sql.column_value(cursor_name, 1, c1); dbms_sql.column_value(cursor_name, 2, c2); multi_insert_priv(c1, c2, r); for i in 1 .. r.count loop dbms_output.put_line(r(i)); end loop; end loop; exception when others then dbms_sql.close_cursor(cursor_name); end; end; /
以上抄袭自:http://space.itpub.net/13129975/viewspace-624522
其他:
http://www.itpub.net/thread-9530-1-1.html
http://blog.csdn.net/fm0517/archive/2009/05/23/4210370.aspx