DBMS_SQL package 学习

这个包提供了一种使用动态sql来访问数据库的方法。

第一步:打开游标

使用函数 function open_cursor return integer;

定义变量 Cur_1 integer; --返回的新游标的ID值

语句是Cur_1 := Dbms_Sql.Open_Cursor;

第二步:解析要执行的语句

使用过程procedure parse(c in integer, statement in varchar2,                  language_flag in integer);

语句是Dbms_Sql.Parse(Cur_1, ’sql语句’, Dbms_Sql.V7);

第三步:定义字段变量,其值对应于指定游标中某个位置元素的值(仅用于SELECT语句)

使用过程procedure define_column(c in integer, position in integer, column in number);

语句是Dbms_Sql.Define_Column(Cur_1, 1, column);

定义第一列为column,可重复定义多个列;

第四步:执行指定游标

使用过程function execute(c in integer) return integer;--返回行数

语句是Rows_1 := Dbms_Sql.EXECUTE(Cur_1);

第五步:从指定的游标中取出记录

使用过程function fetch_rows(c in integer) return integer;--返回行数

采用If Dbms_Sql.Fetch_Rows(Cur_1) > 0 then 判断是否取到数据了

然后返回游标中指定位置的元素,使用过程procedure column_value(c in integer, position in integer, value out number);

语句是Dbms_Sql.Column_Value(Cur_1, 1, column);

把游标中的第一列的值赋值给column,可重复赋值多个列;

要加上end if;

最后关闭游标

语句是Dbms_Sql.Close_Cursor(Cur_1);

通常运用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等方法。

下面根据不同情况进行详细展示:
在做展示之前,先准备一些基础数据

Sql代码  
  1. create table demo (a number,b number,c number);
  2. begin
  3. for i in 1 .. 15 loop
  4. insert into demo
  5. values
  6. (round(dbms_random.value, 2) * 100,
  7. round(dbms_random.value, 2) * 100,
  8. round(dbms_random.value, 2) * 100);
  9. end loop;
  10. commit;
  11. end;

基础数据完成之后,下面开始对一些具体情况进行分析:
1.执行一般的select语句
   首先先介绍最常用情况:

Sql代码  
  1. create or replace procedure define_column(no in number) is
  2. cursor_name      integer := dbms_sql.open_cursor; --在初始化参数时,就可以打开cursor;
  3. row_process      integer;
  4. v_b number;
  5. begin
  6. --解析要执行的SQL.
  7. dbms_sql.parse(cursor_name,
  8. 'select * from demo where a= :no',
  9. dbms_sql.native);
  10. --如果要执行的SQL中不需要参数,则可以省略掉bind_variable--
  11. dbms_sql.bind_variable(cursor_name, 'no', no);
  12. /*如果需要返回查询语句的结果,则必须在exec之前使用define_column函数定义返回字段;define_column函数的第一个参数是最初定义的cursor name,第二个参数是指需要返回的字段在查询结果中处于第几列,在此例中返回的字段是查询结果中的第二列,即b列;第三个参数就是接收返回结果需要的变量*/
  13. dbms_sql.define_column(cursor_name, 2, v_b);
  14. --必须定义一个参数接收exec的结果
  15. row_process := dbms_sql.execute(cursor_name);
  16. loop
  17. if dbms_sql.fetch_rows(cursor_name) > 0 then
  18. --将前面定义的字段返回给变量v_b--
  19. dbms_sql.column_value(cursor_name, 2, v_b);
  20. dbms_output.put_line('B is ' || v_b);
  21. else
  22. exit;
  23. end if;
  24. end loop;
  25. --数据处理完成后记得要将cursor关闭
  26. dbms_sql.close_cursor(cursor_name);
  27. exception
  28. when others then
  29. dbms_sql.close_cursor(cursor_name);
  30. end;

2.使用define_array方法得到查询结果
    前面已经分析了如何使用define_column方法得到查询结果,但有时我们想要一次得到多行查询结果,此时我们就需要使用define_array方法,此方法常用于DML操作,稍后会有例子对此介绍,现在先来看一下如果使用define_array.

Sql代码  
  1. create or replace procedure define_array is
  2. c      NUMBER;
  3. d      NUMBER;
  4. /*DBMS_SQL.NUMBER_TABLE类型实际就是type NUMBER_TABLE is table of number index by binary_integer;*/
  5. n_tab  DBMS_SQL.NUMBER_TABLE;
  6. n_tab1 DBMS_SQL.NUMBER_TABLE;
  7. indx   NUMBER := 1;
  8. BEGIN
  9. c := DBMS_SQL.OPEN_CURSOR;
  10. DBMS_SQL.PARSE(c,
  11. 'select * from demo where rownum<13 order by 1',
  12. DBMS_SQL.NATIVE);
  13. /*在此需要特别介绍一下define_array函数的第一个参数是已经打开的cursor名称, 第二个参数是指需要返回的字段在查询结果中处于第几列,第三个参数就是接收返回结果需要的变量,与define_column不同的是此变量是table,而不是普通的字段类型;第四个参数表示一次可以返回的行数;第五个参数是指n_tab的index从哪个数值开始,此数值是递增的.在此例中index是从1开始的,一次得到9行结果集,则有n_tab(1)到n_tab(9),如果循环再得到新的结果集,则index继续增长n_tab(10)....*/
  14. DBMS_SQL.DEFINE_ARRAY(c, 1, n_tab, 9, indx);
  15. DBMS_SQL.DEFINE_ARRAY(c, 2, n_tab1, 9, indx);
  16. d := DBMS_SQL.EXECUTE(c);
  17. loop
  18. d := DBMS_SQL.FETCH_ROWS(c);
  19. dbms_output.put_line('fetch rows is ' || d);
  20. EXIT WHEN d < 9;
  21. DBMS_SQL.COLUMN_VALUE(c, 1, n_tab);
  22. DBMS_SQL.COLUMN_VALUE(c, 2, n_tab1);
  23. for i in 1 .. d loop
  24. dbms_output.put_line(n_tab(i) || ',' || n_tab1(i));
  25. end loop;
  26. END LOOP;
  27. DBMS_SQL.CLOSE_CURSOR(c);
  28. EXCEPTION
  29. WHEN OTHERS THEN
  30. IF DBMS_SQL.IS_OPEN(c) THEN
  31. DBMS_SQL.CLOSE_CURSOR(c);
  32. END IF;
  33. END;

3.使用variable_value显示DML后的返回结果(单条记录)
   以上我们介绍了如何使用DBMS_SQL包来处理数据查询,如果我们把查询语句更换成DML语句,则可以完成各种DML操作。
  在PL/SQL中我们可以使用returning方法返回DML操作结果,在DBMS_SQL包中可不可以实现呢?答案当然是可以,用variable_value方法就可以实现。下面就分别用两个例子来展示如何实现,一个是返回单条记录,另一个是返回多条记录。

(1)返回单条记录

Sql代码  
  1. procedure single_insert(c1 in number, c2 in number, r out number) is
  2. cursor_name number := dbms_sql.open_cursor;
  3. n   number;
  4. begin
  5. dbms_sql.parse(cursor_name,
  6. 'insert into demo values (:a,:b) returning :a*:b into :r',
  7. dbms_sql.native);
  8. dbms_sql.bind_variable(cursor_name, 'a', c1);
  9. dbms_sql.bind_variable(cursor_name, 'b', c2);
  10. dbms_sql.bind_variable(cursor_name, 'r', r);
  11. n := dbms_sql.execute(cursor_name);
  12. --使用variable_value函数得到DML操作returning的结果集
  13. dbms_sql.variable_value(cursor_name, 'r', r);
  14. dbms_output.put_line(r);
  15. dbms_sql.close_cursor(cursor_name);
  16. exception
  17. when others then
  18. dbms_sql.close_cursor(cursor_name);
  19. end;

(2)返回多条记录
结合define_array使用,可以更好的完成DML操作。

Sql代码  
  1. create or replace package DBMS_SQL_DEMO as
  2. procedure multi_insert;
  3. end;
  4. /
  5. create or replace package body DBMS_SQL_DEMO as
  6. procedure multi_insert_priv(c1 in dbms_sql.Number_Table,
  7. c2 in dbms_sql.Number_Table,
  8. r  out dbms_sql.Number_Table) is
  9. cursor_name number := dbms_sql.open_cursor;
  10. n           number;
  11. begin
  12. dbms_sql.parse(cursor_name,
  13. 'insert into demo values (:a,:b) returning :a*:b into :r',
  14. dbms_sql.native);
  15. --使用bind_array函数将number_table类型的变量赋值给绑定变量
  16. dbms_sql.bind_array(cursor_name, 'a', c1);
  17. dbms_sql.bind_array(cursor_name, 'b', c2);
  18. dbms_sql.bind_array(cursor_name, 'r', r);
  19. n := dbms_sql.execute(cursor_name);
  20. --使用variable_value函数将returning的结果集赋值给number_table类型的变量
  21. dbms_sql.variable_value(cursor_name, 'r', r);
  22. dbms_sql.close_cursor(cursor_name);
  23. exception
  24. when others then
  25. dbms_sql.close_cursor(cursor_name);
  26. end;
  27. procedure multi_insert is
  28. c1          dbms_sql.Number_Table;
  29. c2          dbms_sql.Number_Table;
  30. cursor_name number := dbms_sql.open_cursor;
  31. n           number;
  32. r           dbms_sql.Number_Table;
  33. indx        number := 1;
  34. d           number;
  35. begin
  36. dbms_sql.parse(cursor_name, 'select * from demo', dbms_sql.native);
  37. dbms_sql.define_array(cursor_name, 1, c1, 5, indx);
  38. dbms_sql.define_array(cursor_name, 2, c2, 5, indx);
  39. n := dbms_sql.execute(cursor_name);
  40. loop
  41. d := dbms_sql.fetch_rows(cursor_name);
  42. exit when d = 0;
  43. dbms_sql.column_value(cursor_name, 1, c1);
  44. dbms_sql.column_value(cursor_name, 2, c2);
  45. multi_insert_priv(c1, c2, r);
  46. for i in 1 .. r.count loop
  47. dbms_output.put_line(r(i));
  48. end loop;
  49. end loop;
  50. exception
  51. when others then
  52. dbms_sql.close_cursor(cursor_name);
  53. end;
  54. end;
  55. /

DBMS_SQL包使用相关推荐

  1. 使用Oracle的DBMS_SQL包执行动态SQL语句

    引用自:http://blog.csdn.net/ggjjzhzz/archive/2005/10/17/507880.aspx 在某些场合下,存储过程或触发器里的SQL语句需要动态生成.Oracle ...

  2. Oracle之DBMS_SQL包用法详解

    Oracle之DBMS_SQL包用法详解 原文  http://zhangzhongjie.iteye.com/blog/1948093 通常运用 DBMS_SQL 包一般分为 如下 几步: 1. o ...

  3. oracle中sql行数的计算,Oracle技术网—如何利用DBMS_SQL包和游标计算当前用户下所有表的行数...

    实现方法: SQL> conn scott/tiger SQL> set serveroutput on size 1000000 SQL> SQL> DECLARE 2 t_ ...

  4. DBMS_SQL使用

    一.简介 DBMS_SQL包提供一个接口,用于执行动态SQL(包括DDL 和DML). DBMS_SQL定义了一个实体叫游标ID,游标ID是一个PL/SQL整型数,通过游标ID,可以对游标进行操作. ...

  5. DBMS_SQL的使用

    DBMS_SQL包提供的函数 DBMS_SQL包提供的过程 示例 CREATE OR REPLACE PROCEDURE DBMS_SQL_TEST (TABLE_NAME IN VARCHAR2 ) ...

  6. Oracle数据库中的包(七)

    目录 1.Oracle中包 2.包的创建 (1)可视化方式创建包 (2)以命令方式创建包 ①创建包头 ②创建包体 ③删除包 3.包的初始化 4.重载 ①相关概念和注意事项 ②系统内置的包 Oracle ...

  7. Oracle基础 动态SQL语句

    一.静态SQL和动态SQL的概念. 1.静态SQL 静态SQL是我们常用的使用SQL语句的方式,就是编写PL/SQL时,SQL语句已经编写好了.因为静态SQL是在编写程序时就确定了,我们只能使用SQL ...

  8. 每周一书《Oracle 12 c PL(SQL)程序设计终极指南》

    本周为大家送出的书是<Oracle 12 c PL(SQL)程序设计终极指南>,此书由机械工业出版社出版, 孙风栋,王澜,郭晓惠 著. 内容简介: <Oracle 12c PL/SQ ...

  9. 基于oracle的sql优化

    [基于oracle的sql优化] 基于oracle的sql优化 [博主]高瑞林 [博客地址]http://www.cnblogs.com/grl214 一.编写初衷描述 在应有系统开发初期,由于数据库 ...

最新文章

  1. 一文详解激光点云的物体聚类
  2. C++ 接口 函数导出_Python玩转Excel:实现函数自动填充、数据排序
  3. SSIS中循环遍历组件[Foreach Loop Container]
  4. 解决 windows10和ubuntu16.04双系统下时间不对的问题
  5. Flask备注4(Structure)
  6. 来看一下:构造函数的小秘密详解
  7. 翻译spring4.2官方文档(3)
  8. java接口深入理解_深入理解Java的接口和抽象类
  9. WIN10如何管理开机启动项?
  10. Linux版的led显示屏控制软件,中航Led显示屏控制软件下载
  11. Springboot网络微小说的设计与实现毕业设计源码031758
  12. 火剪剪辑系统,火剪矩阵系统,火剪系统源码框架
  13. OVP 过压保护电路
  14. Ardunio开发实例-红外遥控器解码与LED控制
  15. C++嵌套类的使用及对外部类的访问权限
  16. 给出n个数,找出这n个数的最大,最小,和值
  17. Tomcat-- 掌握汤姆猫,看这一篇文章就够了
  18. 清理电脑垃圾的命令代码
  19. java寻仙红尘缘修改版_微信拍一拍后缀创意搞笑文字大全 微信拍一拍搞笑后缀的句子...
  20. 汽车早讯丨庞大集团董事长回应高管降薪;一嗨租车达成新私有化协议

热门文章

  1. HTML5 + CSS 左右排版自适应高
  2. Aspose Cells 控件如何实现数据过滤(附代码和下载地址)
  3. MKMapView自定义大头针
  4. HDU Redraw Beautiful Drawings 推断最大流是否唯一解
  5. 第36-37 Tomcat SVN
  6. linux fastQC 操作命令,linux-ubuntu下fastQC的安裝及使用
  7. html中纯js互斥按钮,JS如何实现checkbox互斥功能
  8. 从 Alpha 到 Beta,这次是 New mPaaS
  9. Serverless对研发效能的变革和创新
  10. 跟随弹幕停不下来?智慧文娱还有哪些新玩法