`

dbms_sql的使用

阅读更多
通常运用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;

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

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

  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;

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

(1)返回单条记录
  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;
(2)返回多条记录
结合define_array使用,可以更好的完成DML操作。

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;
/
分享到:
评论

相关推荐

    DBMS_SQL的使用

    ### Oracle DBMS_SQL 使用详解 #### 一、概述 在Oracle数据库中,`DBMS_SQL`包是一个功能强大的工具,用于执行动态SQL语句。它提供了处理动态SQL语句的能力,使得开发人员能够灵活地构建和执行SQL语句,而不需要...

    DBMS_SQL.rar_dbms_oracle

    下面是一个简单的示例,展示了如何使用DBMS_SQL执行动态SQL: ```sql DECLARE v_cursor INTEGER; v_sql VARCHAR2(200) := 'SELECT * FROM employees WHERE employee_id = :1'; v_employee_id NUMBER := 101; v_...

    DBMS_XMLDOM DBMS_XMLPARSER DBMS_XMLQUERY 文档

    Oracle数据库系统提供了强大的XML处理能力,这主要体现在其内置的几个PL/SQL包上,如DBMS_XMLDOM、DBMS_XMLPARSER和DBMS_XMLQUERY。这些包为开发者提供了处理XML文档的一整套工具,使得在数据库环境中进行XML数据的...

    Oracle动态SQL之DBMS_SQL系统包的使用.pdf

    本文将探讨Oracle中的动态SQL实现机制,重点介绍DBMS_SQL系统包的结构与使用方法,通过实例展示动态SQL的基本用法和相关技巧。 动态SQL是指在程序执行时才能确定的SQL语句,它与静态SQL相对。静态SQL的语句在编写...

    ORACLE数据库封装过程DBMS_SQL的应用.pdf

    DBMS_SQL 的应用可以解决在项目开发中对用户管理和 DDL 使用的问题。 静态联接和动态联接是两种不同的联接方式。在静态联接中,PL/SQL 编译器会在编译时查找程序中引用的 ORACLE 对象的定义,然后将它们的存储地址...

    PLSQL开发过程中,动态使用DBMS_SQL[借鉴].pdf

    dbms_sql.parse(cur, sql_stmt, dbms_sql.native); dbms_sql.execute(cur); dbms_sql.close_cursor(cur); end; 在这个示例中,我们使用 DBMS_SQL 包来执行一个 SELECT 语句,获取 dinya_test 表中的所有记录。 ...

    使用dbms_stats包手工收集统计信息

    Oracle 数据库中使用 dbms_stats 包手动收集统计信息 在 Oracle 数据库中,dbms_stats 包提供了一种手动收集统计信息的方式,包括基于表、用户和索引的统计信息。通过使用 dbms_stats 包,我们可以手动收集统计信息...

    oracle dbms_lob

    在实际应用中,`DBMS_LOB`包通常与SQL DML语句结合使用,以处理LOB字段。例如,可以使用`DBMS_LOB.WRITE`在INSERT或UPDATE语句中修改LOB值,或者使用`DBMS_LOB.APPEND`在已有的LOB后面添加新内容。 学习`DBMS_LOB`...

    ORACLE SYS.DBMS_REGISTRY_SYS has errors

    标题中的问题“ORACLE SYS.DBMS_REGISTRY_SYS has errors”指的是在Oracle数据库系统中,系统包BODY `SYS.DBMS_REGISTRY_SYS` 出现错误,导致了一系列的PL/SQL调用失败。这种错误通常与数据库的元数据注册功能有关,...

    DBMS_STATS.GATHER_TABLE_STATS详解.pdf

    1. **对于分区表**:建议使用 `DBMS_STATS` 而不是 `ANALYZE` 语句,因为 `DBMS_STATS` 支持并行处理、可以收集整个分区表的数据以及单个分区的数据,并且可以在不同级别上计算统计信息。 2. **对于非分区表**:同样...

    dbms_obfuscation_toolkit加密解密数据

    ### DBMS_OBFUSCATION_TOOLKIT:Oracle 数据库中的加密与解密工具包 DBMS_OBFUSCATION_TOOLKIT是Oracle数据库提供的一种用于数据加密解密的强大工具包,自Oracle 8i版本开始引入。它支持多种加密算法,如DES、...

    怎样禁用及回收java的授权dbms_java

    ### 如何禁用及回收Java的授权:dbms_java 授权管理详解 #### 一、引言 在Oracle数据库环境中,`dbms_java`包提供了一系列功能强大的工具,用于管理和控制Java应用程序的安全性。这对于那些在Oracle环境中部署了...

    DBMS_RANDOM.VALUE OR DBMS_RANDOM.STRING

    请注意,使用`DBMS_RANDOM`时需要注意其性能影响,因为生成随机数和字符串涉及计算,可能会比直接查询数据库更消耗资源。在处理大量数据或频繁调用时,要特别注意这一点。 在源码层面,`DBMS_RANDOM`的实现可能涉及...

    SQL Tuning Advisor使用总结

    DBMS_OUTPUT.put_line('l_sql_tune_task_id: ' || l_sql_tune_task_id); END; ``` - **从游标缓存中获取SQL**: ```plsql DECLARE l_sql_tune_task_id VARCHAR2(100); BEGIN l_sql_tune_task_id := DBMS_...

    dbms_logmnr使用

    dbms_logmnr 使用 DBMS_LOGMNR 是 Oracle 中的一个日志分析包,用于分析和解释redo日志文件,以便追踪和诊断数据库中的操作。下面是 DBMS_LOGMNR 的使用方法。 首先,需要安装 LogMiner 工具,包括两个脚本 dbmslm...

    dbms_lock控制串行详解

    这篇博文深入探讨了DBMS_LOCK的功能、使用方法以及在实际应用中的重要性。 首先,我们要理解DBMS_LOCK的作用。在多用户环境下,数据库系统需要确保事务的隔离级别,防止并发操作导致的数据不一致。DBMS_LOCK提供了...

    DBMS_JOB使用方法

    ### DBMS_JOB 使用方法详解 #### 一、概述 `DBMS_JOB` 是 Oracle 数据库提供的用于调度任务的包,可以实现对定时任务的管理,包括任务的创建、修改、删除及执行等操作。该包提供了多种过程和函数,允许用户以灵活...

    DBMS(java).zip_DBMS.java_consistog1_dbms_dbms sql解析器_java 实现dbms

    "dbms_sql解析器"则提示我们这个系统包含了一个用于解析SQL语句的组件,这是DBMS的重要组成部分,用于理解用户输入的查询并执行相应的操作。"java 实现dbms"明确了整个系统是用Java编程语言实现的。 在描述中,提到...

    dbms.rar_DBMS实现_SQL语句_dbms_dbms java_java 实现dbms

    本项目“dbms.rar”提供了一个自定义实现的DBMS系统,它支持SQL语句的编译和解析,这在理解数据库系统的工作原理和进行数据库相关开发时具有很高的学习价值。 SQL(Structured Query Language)是用于处理关系...

Global site tag (gtag.js) - Google Analytics