DBMS_SQL使用
一、简介
DBMS_SQL包提供一个接口,用于执行动态SQL(包括DDL 和DML)。
DBMS_SQL定义了一个实体叫游标ID,游标ID是一个PL/SQL整型数,通过游标ID,可以对游标进行操作。
二、主要函数
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;
DECLARE
v_cursor NUMBER;--游标ID
sqlstring 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列是price
sqlstring :='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的值传给 :p
dbms_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;
DECLARE
v_cursor NUMBER;--游标ID
sqlstring VARCHAR2(200);--用于存放SQL语句
v_phone_name VARCHAR2(20);--手机名字
v_producer VARCHAR2(20);--手机生产商
v_price NUMBER :=500;--手机价钱
v_count INT;--被DML语句影响的行数
BEGIN sqlstring :='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的值传给 :p
dbms_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,'')||' 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使用的更多相关文章
- dbms_sql包的用法
http://blog.itpub.net/20948385/viewspace-691398 对于一般的select操作,如果使用动态的sql语句则需要进行以下几个步骤: open cursor ...
- Oracle12c中PL/SQL(DBMS_SQL)新特性之隐式语句结果(DBMS_SQL.RETURN_RESULT and DBMS_SQL.GET_NEXT_RESULT)
隐式数据结果特性将能简化从其他数据库到Oracle12c存储过程迁移.1. 背景T-SQL中允许查询结果的隐式返回.例如:下面T-SQL存储过程隐式返回查询结果.CREATE PROCEDURE Ge ...
- ORACLE中使用DBMS_SQL获取动态SQL执行结果中的列名和值
1.获取动态SQL中的列名及类型 DECLARE l_curid INTEGER; l_cnt NUMBER; l_desctab dbms_sql.desc_tab; l_sqltext ); BE ...
- PL/SQL之DBMS_SQL程序包使用(1)(学习笔记)
dbms_sql程序包dbms_sql程序包是系统提供给我们的另一种使用动态SQL的方法:使用DBMS_SQL包实现动态的SQL的步骤如下:1.将要执行的SQL语句或者一个语句放到一个字符串变量中2. ...
- 二十四、DBMS_SQL
1.概述 1) 在整个程序的设计过程中,对游标的操作切不可有省略的部分,一旦省略其中某一步骤,则会程序编译过程既告失败,如在程序结尾处未对改游标进行关闭操作,则在再次调用过程时会出现错误. 2) db ...
- Oracle之DBMS_SQL包用法详解
对于一般的(select)操作,如果使用动态的sql语句则需要进行以下几个步骤:open cursor--->parse---> bind variable ---> defi ...
- ORACLE中DBMS_SQL的用法
ORACLE中DBMS_SQL的用法 对于一般的select操作,如果使用动态的sql语句则需要进行以下几个步骤: open cursor---> parse---> define ...
- 使用Oracle的DBMS_SQL包执行动态SQL语句
引用自:http://blog.csdn.net/ggjjzhzz/archive/2005/10/17/507880.aspx 在某些场合下,存储过程或触发器里的SQL语句需要动态生成.Oracle ...
- ORA 各种oraclesql错误
ORA-00001: 违反唯一约束条件 (.) ORA-00017: 请求会话以设置跟踪事件 ORA-00018: 超出最大会话数 ORA-00019: 超出最大会话许可数 ORA-00020: 超出 ...
随机推荐
- [转]Android适配器之ArrayAdapter、SimpleAdapter和BaseAdapter的简单用法与有用代码片段
收藏ArrayAdapter.SimpleAdapter和BaseAdapter的一些简短代码片段,希望用时方便想起其用法. 1.ArrayAdapter 只可以简单的显示一行文本 代码片段: A ...
- C# MATLAB混合编程
我附带把matlab配置过程也给大家上传上来.[转载]终于学会C#调用matlab函数了,原来这么简单(也可以下载附件查看)自己的配置: (1)Microsoft Visual Studio 2005 ...
- POJ 3237 Tree (树链剖分)
Tree Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 2825 Accepted: 769 Description ...
- Ubuntu下gcc多版本共存和版本切换
https://my.oschina.net/u/2306127/blog/538139 摘要: Ubuntu系统使用的gcc版本随着发布版本的不同而不同,在编译android系统时不同的版本推荐用不 ...
- 程序猿怎样变身IT讲师
我以前写过一篇文章,"一张图道尽程序猿的出路",里面有一张图: 这张图随着"一张图道尽程序猿的出路"这篇文章,以前被伯乐在线.docin(豆丁网).IT面试.J ...
- C# 如何做类似微博和QQ的授权登录
记录下吧,dotnet下有这个http://dotnetopenauth.net/开源的框架可以用来实现服务端和客户端的实现,具体的使用方法还真研究,第一次接触OAuth这个概念
- XDroidRequest网络请求框架,新开源
XDroidRequest 是一款网络请求框架,它的功能也许会适合你.这是本项目的第三版了,前两版由于扩展性问题一直不满意,思考来 思考去还是觉得Google的Volley的扩展性最强,于是借鉴了Vo ...
- Redis事务为什么不支持回滚
在事务运行期间,虽然Redis命令可能会执行失败,但是Redis仍然会执行事务中余下的其他命令,而不会执行回滚操作,你可能会觉得这种行为很奇怪.然而,这种行为也有其合理之处:只有当被调用的Redis命 ...
- OpenCV定制化创建角点检测子
定制化创建角点检测子 目标 在这个教程中我们将涉及: 使用 OpenCV 函数 cornerEigenValsAndVecs 来计算像素对应的本征值和本征向量来确定其是否是角点. 使用OpenCV 函 ...
- ndk 编译 c++ 兼容性问题汇总整理
转自:http://blog.csdn.net/wenrenwang/article/details/12003671 1.__int64找不到符号 采用int64_t来代替: #if defined ...