一、简介

DBMS_SQL包提供一个接口,用于执行动态SQL(包括DDL 和DML)

DBMS_SQL定义了一个实体叫游标ID,游标ID是一个PL/SQL整型数,通过游标ID,可以对游标进行操作。

DBMS_SQL包和本地动态SQL在功能上有许多重叠的地方,但是有的功能只能通过本地动态SQL实现,而有些功能只能通过DBMS_SQL实现。

二、主要函数

DBMS_SQL封装过程中的主要函数:
1、OPEN_CURSOR:返回新游标的ID值
2、PARSE:解析要执行的语句
3、BIND_VARIABLE:将给定的数量与特定的变量相连接
4、DEFINE_COLOUMN:定义字段变量,其值对应于指定游标中某个位置元素的值 (仅用于SELECT语句) 
5、EXECUTE:执行指定的游标 
6、EXECUTE_AND_FETCH:执行指定的游标并取记录 
7、FETCH_ROWS:从指定的游标中取出记录 
8、COLUMN_VALUE:返回游标中指定位置的元素 
9、IS_OPEN:当指定的游标状态为OPEN时返回真值 
10、CLOSE_CURSOR:关闭指定的游标并释放内存 
11、LAST_ERROR_POSITION:返回出错SQL语句的字节偏移量 
12、LAST_ROW_ID:返回最后一条记录的ROWID 
13、LAST_SQL_FUNCTION_CODE:返回语句的SQL FUNCTION CODE

三、一般过程

对于一般的select 操作,如果使用动态的sql语句则需要进行以下几个步骤:   
open   cursor --->parse--->define column--->excute--->fetch rows--->close cursor;    
而对于dml操作(insert , update )则需要进行以下几个步骤:   
open   cursor --->parse--->bind variable--->execute--->close cursor;    
对于delete 操作只需要进行以下几个步骤:   
open   cursor --->parse--->execute--->close cursor;    
DDL操作需要进行一下几个步骤
open cursor--->parse---->close cursor;

利用DBMS_SQL执行DDL语句:
CREATE OR REPLACE PROCEDURE CreateTable2(tablename VARCHAR2)
IS
SQL_string VARCHAR2(1000);--存放SQL语句
V_cur integer;--定义整形变量,用于存放游标
BEGIN
SQL_string := 'CREATE TABLE ' || tablename || '(nameVARCHAR(20))';
V_cur := dbms_sql.open_cursor;--打开游标
dbms_sql.parse(V_cur,SQL_string,DBMS_SQL.NATIVE);--解析并执行SQL语句
dbms_sql.close_cursor(V_cur);--关闭游标
END;
利用DBMS_SQL执行SELECT语句:
open  cursor--->parse---> define  column--->excute---> fetch  rows--->close  cursor;DECLAREv_cursor NUMBER;--游标IDsqlstring VARCHAR2(200);--用于存放SQL语句v_phone_name VARCHAR2(20);--手机名字v_producer VARCHAR2(20);--手机生产商v_price  NUMBER :=500;--手机价钱v_count INT;--在这里无意义,只是存放函数返回值
BEGIN--:p是占位符--SELECT 语句中的第1列是phone_name,第2列是producer,第3列是pricesqlstring :='SELECTphone_name,producer,price FROM phone_infor WHERE price> :p';v_cursor :=dbms_sql.open_cursor;--打开游标;dbms_sql.parse(v_cursor ,sqlstring,dbms_sql.native);--解析动态SQL语句;--绑定输入参数,v_price的值传给 :pdbms_sql.bind_variable(v_cursor,':p',v_price);--定义列,v_phone_name对应SELECT 语句中的第1列dbms_sql.define_column(v_cursor,1,v_phone_name,20);--定义列,v_producer对应SELECT语句中的第2列dbms_sql.define_column(v_cursor,2,v_producer,20);--定义列,v_price对应SELECT语句中的第3列dbms_sql.define_column(v_cursor,3,v_price);v_count := dbms_sql.EXECUTE(v_cursor);--执行动态SQL语句。
  LOOP--从游标中把数据检索到缓存区(BUFFER)中,缓冲区的值只能被函数COULUMN_VALUE()所读取EXIT WHENdbms_sql.fetch_rows(v_cursor)<=0;--函数column_value()把缓冲区的列的值读入相应变量中。--第1列的值被读入v_phone_name中dbms_sql.column_value(v_cursor,1,v_phone_name);--第2列的值被读入v_producer中dbms_sql.column_value(v_cursor,2,v_producer);--第2列的值被读入v_price中dbms_sql.column_value(v_cursor,3,v_price);--打印变量的值dbms_output.put_line(v_phone_name || ' '||v_producer|| ' '||v_price);END LOOP;dbms_sql.close_cursor(v_cursor);--关闭游标END;
利用DBMS_SQL执行DML语句:
open  cursor--->parse---> bind  variable--->execute---> close  cursor;DECLAREv_cursor NUMBER;--游标IDsqlstring VARCHAR2(200);--用于存放SQL语句v_phone_name VARCHAR2(20);--手机名字v_producer VARCHAR2(20);--手机生产商v_price  NUMBER :=500;--手机价钱v_count INT;--被DML语句影响的行数
BEGINsqlstring :='INSERT INTO phone_infor values(:a,:b,:c)';-- :a,:b,:c 是占位符
v_phone_name  :='S123';v_producer  :='索尼AA';v_price   := 999;v_cursor :=dbms_sql.open_cursor;--打开游标;dbms_sql.parse(v_cursor ,sqlstring,dbms_sql.native);--解析动态SQL语句;--绑定输入参数,v_price的值传给 :pdbms_sql.bind_variable(v_cursor,':a',v_phone_name);dbms_sql.bind_variable(v_cursor,':b',v_producer);dbms_sql.bind_variable(v_cursor,':c',v_price);v_count := dbms_sql.EXECUTE(v_cursor);--执行动态SQL语句。
  dbms_sql.close_cursor(v_cursor);--关闭游标dbms_output.put_line(' INSERT ' || to_char(v_count) ||' row ');--打印有多少行被插入COMMIT;END;  

四、demo

示例1

--这是一个创建一个表的过程的例子。该过程有两个参数:表名和字段及其类型的列表。
CREATE OR REPLACE PROCEDURE ddlproc (tablename varchar2, cols varchar2) AS   cursor1 INTEGER;
BEGIN   cursor1 := dbms_sql.open_cursor;   dbms_sql.parse(cursor1, 'CREATE TABLE ' tablename ' ( ' cols ' )', dbms_sql.v7);   dbms_sql.close_cursor(cursor1);
end;   

示例2

--用DBMS_SQL包和游标计算用户下所有表行数
DECLARE  t_c1_tname user_tables.table_name%TYPE;  t_command varchar2(200);  t_cid integer;  t_total_records number(10);  stat integer;  row_count integer;  t_limit integer := 0;   --限制只取出记录大于0的表的情况  cursor c1 is select table_name from user_tables order by table_name; --查出所有表的名字
BEGIN  t_limit := 0;  open c1;  loop  fetch c1 into t_c1_tname;                                --取出一个表名  exit when c1%NOTFOUND;                                   --如果游标记录取完,退出循环  t_command := 'SELECT COUNT(0) FROM '||t_c1_tname;   --定义SQL命令  t_cid := DBMS_SQL.OPEN_CURSOR;                      --创建一个游标  DBMS_SQL.PARSE(t_cid,t_command,dbms_sql.native);    --向服务器发出一个语句并检查这个语句的语法和语义错误  DBMS_SQL.DEFINE_COLUMN(t_cid,1,t_total_records);    --定义将从FetchRows()函数接收数据的变量的数据类型与大小  stat := DBMS_SQL.EXECUTE(t_cid);                    --执行此语句,因为执行的是查询,所以必须跟着Fetch_Rows函数并为单个行检索数据  row_count := DBMS_SQL.FETCH_ROWS(t_cid);            --取回一行数据放入局部缓冲区  DBMS_SQL.COLUMN_VALUE(t_cid,1,t_total_records);     --返回调用FetchRows()取回的一列的值,这一列的值存储在t_total_records中  if t_total_records > t_limit then  DBMS_OUTPUT.PUT_LINE(rpad(t_c1_tname,55,' ')||  to_char(t_total_records,'99999999')||' record(s)');  end if;  DBMS_SQL.CLOSE_CURSOR(t_cid);  end loop;  close c1;
END;  

具体参考以下三篇:

http://blog.csdn.net/u013516966/article/details/49002769

http://blog.csdn.net/tianping168/article/details/3980134

https://www.cnblogs.com/zeromyth/archive/2009/09/29/1576627.html

DBMS_SQL使用相关推荐

  1. oracle 游标 内联,oracle – EXEC_SQL,EXECUTE IMMEDIATE,DBMS_SQL和内联SQL之间的区别

    1)您不能在PL / SQL块内执行直接DDL. BEGIN CREATE TABLE TEST AS ( SELECT * FROM FND_USER ); EXCEPTION WHEN OTHER ...

  2. DBMS_SQL系统包的使用

    转自:http://taosst.javaeye.com/blog/284770 PL/SQL中使用动态SQL编程 在PL/SQL程序设计过程中,会遇到很多必须使用动态sql的地方,oracle系统所 ...

  3. DBMS_SQL包使用

    DBMS_SQL package 学习 这个包提供了一种使用动态sql来访问数据库的方法. 第一步:打开游标 使用函数 function open_cursor return integer; 定义变 ...

  4. oracle dbms_sql.describe_columns,PL/SQL Challenge 每日一题:2017-3-6 DBMS_SQL.DESCRIBE_COLUMNS

    (原发表于 2011-6-20) 最先答对且答案未经编辑的puber将获得纪念章一枚(答案不可编辑但可发新贴补充或纠正),其他会员如果提供有价值的分析.讨论也可获得纪念章一枚. 每两周的优胜者可获得i ...

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

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

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

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

  7. DBMS_SQL的使用

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

  8. XTTS 增量备份同步scn xttdriver.pl  -s PLS-00201: identifier 'DBMS_SQL.VARCHAR2_TABLE' must be declare运行报错

    报错日志如下: 同步scn 的操作应当在源端环境去操作: [node1]zkemr2$$ORACLE_HOME/perl/bin/perl xttdriver.pl  -s -L ========== ...

  9. Oracle之DBMS_SQL包用法详解

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

最新文章

  1. AutoShape:实时单目3D检测网络(ICCV2021)
  2. spring boot security ajax_Spring 和 SpringBoot 之间到底有啥区别?
  3. oracle10g 创建分区表,oracle10G分区的创建与维护Oracle分区表和本地索引
  4. swarm 容器_Oracle应用容器云上的WildFly Swarm
  5. 用cmd运行java可以javac不行(win10)
  6. vue PC端国际化一站式解决方案
  7. oracle acfs snap 恢复,删除ACFS系统碰到的问题
  8. 移动前端开发之viewport的深入理解(转)
  9. 打印机扫描找不到计算机用户名,打印机扫描到pc显示不可用 打印机扫描到pc显示不可用的解决方法...
  10. 稳压二极管的工作原理是什么?
  11. matlab学习五,二元函数绘图方法
  12. 目标检测之RFB Net
  13. 接口收到CRC错包怎么处理
  14. python爬虫和java爬虫哪个好_应用数据下载
  15. 第五章 澄清概念意义
  16. PS简单入门须知的小技巧
  17. poi doc转docx_文件批量操作之.doc转成.docx
  18. Linux Bash漏洞最新最全的修复方法
  19. sizeof结构体指针
  20. java学习--装饰器设计模式

热门文章

  1. HTML 5 学习笔记之 canvas 标签
  2. 更改 Office 解决方案的安装路径
  3. 互联网下一个热点:服务业电子商务
  4. How to adjust IFrame height on it's content (转载)
  5. OpenCV Contours 使用记录
  6. solr7在tomcat上的部署
  7. win10安装git,打开git bash闪退
  8. CSS-伪类选择器(未完待续。。。)
  9. 无限滚动加载最佳实践
  10. 简单易懂的snmpd.conf配置文件说明