使用Oracle的DBMS_SQL包执行动态SQL语句
引用自:http://blog.csdn.net/ggjjzhzz/archive/2005/10/17/507880.aspx
在某些场合下,存储过程或触发器里的SQL语句需要动态生成。Oracle的DBMS_SQL包可以用来执行动态SQL语句。本文通过一个简单的例子来展示如何利用DBMS_SQL包执行动态SQL语句:
|
DECLARE |
结果:
| 3095;S051013XW00010;15-10月-05 3112;A051013XW00027;10-10月-05 3113;A051013XW00028;13-10月-05 3116;S051013XW00031;13-10月-05 |
附:DBMS_SQL的文档(来源:http://www.psoug.org)
Oracle DBMS_SQL |
||
| Version 10.2 |
| General | |||||||||||||
| Note: DMBS_SQL is the traditional form of dynamic SQL in Oracle.
For most purposes native dynamic sql (NDS) will suffice but there are some things the DBMS_SQL package does that can not be done any other way. This page emphasizes those areas where there is no substitute. |
|||||||||||||
| Purpose | |||||||||||||
| Source | {ORACLE_HOME}/rdbms/admin/dbmssql.sql | ||||||||||||
| Constants |
|
||||||||||||
| Defined Data Types | General Types TYPE desc_rec IS RECORD ( col_type binary_integer := 0, col_max_len binary_integer := 0, col_name varchar2(32) := '', col_name_len binary_integer := 0, col_schema_name varchar2(32) := '', col_schema_name_len binary_integer := 0, col_precision binary_integer := 0, col_scale binary_integer := 0, col_charsetid binary_integer := 0, col_charsetform binary_integer := 0, col_null_ok boolean := TRUE); TYPE desc_rec2 IS RECORD ( TYPE desc_tab IS TABLE OF desc_rec TYPE desc_tab2 IS TABLE OF desc_rec2 TYPE varchar2a IS TABLE OF VARCHAR2(32767) TYPE varchar2s IS TABLE OF VARCHAR2(256) Bulk SQL Types TYPE Binary_Double_Table IS TABLE OF binary_double TYPE Binary_Float_Table IS TABLE OF binary_float TYPE Clob_Table IS TABLE OF clob TYPE Date_Table IS TABLE OF date TYPE interval_day_to_second_Table IS TABLE OF TYPE interval_year_to_MONTH_Table IS TABLE OF TYPE Number_Table IS TABLE OF NUMBER TYPE time_Table IS TABLE OF time_unconstrained TYPE time_with_time_zone_Table IS TABLE OF TIME_TZ_UNCONSTRAINED INDEX BY binary_integer; TYPE timestamp_Table IS TABLE OF timestamp_unconstrained TYPE timestamp_with_ltz_table IS TABLE OF TYPE Urowid_Table IS TABLE OF urowid TYPE timestamp_with_time_zone_table IS TABLE OF TYPE Varchar2_Table IS TABLE OF VARCHAR2(2000) |
||||||||||||
| Dependencies | SELECT name FROM dba_dependencies WHERE referenced_name = 'DBMS_SQL' UNION SELECT referenced_name FROM dba_dependencies WHERE name = 'DBMS_SQL'; |
||||||||||||
| Exceptions |
|
||||||||||||
| BIND_ARRAY | |||||||||||||
| Binds a given value to a given collection | dbms_sql.BIND_ARRAY( c IN INTEGER, name IN VARCHAR2, <table_variable> IN <datatype> [,index1 IN INTEGER, index2 IN INTEGER)]); |
||||||||||||
| DECLARE stmt VARCHAR2(200); dept_no_array dbms_sql.number_table; c NUMBER; dummy NUMBER; BEGIN dept_no_array(1) := 10; dept_no_array(2) := 20; dept_no_array(3) := 30; dept_no_array(4) := 40; dept_no_array(5) := 30; dept_no_array(6) := 40; stmt := 'delete from emp where deptno = :dept_array'; c := dbms_sql.open_cursor; dbms_sql.parse(c, stmt, dbms_sql.NATIVE); dbms_sql.bind_array(c, ':dept_array', dept_no_array, 1, 4); dummy := dbms_sql.execute(c); dbms_sql.close_cursor(c); EXCEPTIONS |
|||||||||||||
| BIND_VARIABLE | |||||||||||||
| Binds a given value to a given variable | dbms_sql.bind_variable ( c IN INTEGER, name IN VARCHAR2, value IN <datatype>) |
||||||||||||
| CREATE OR REPLACE PROCEDURE demo(salary IN NUMBER) AS cursor_name INTEGER; rows_processed INTEGER; BEGIN cursor_name := dbms_sql.open_cursor; dbms_sql.parse(cursor_name, 'DELETE FROM emp WHERE sal > :x', dbms_sql.NATIVE); dbms_sql.bind_variable(cursor_name, ':x', salary); rows_processed := dbms_sql.execute(cursor_name); dbms_sql.close_cursor(cursor_name); EXCEPTION WHEN OTHERS THEN dbms_sql.close_cursor(cursor_name); END; / |
|||||||||||||
| BIND_VARIABLE_CHAR | |||||||||||||
| Binds a given value to a given variable | dbms_sql.bind_variabl_char ( c IN INTEGER, name IN VARCHAR2, value IN CHAR CHARACTER SET ANY_CS [,out_value_size IN INTEGER]); |
||||||||||||
| See bind_variable demo | |||||||||||||
| BIND_VARIABLE_RAW | |||||||||||||
| Binds a given value to a given variable | dbms_sql.bind_variable_raw ( c IN INTEGER, name IN VARCHAR2, value IN RAW [,out_value_size IN INTEGER]); |
||||||||||||
| See bind_variable demo | |||||||||||||
| BIND_VARIABLE_ROWID | |||||||||||||
| Binds a given value to a given variable | dbms_sql.bind_variable_rowid ( c IN INTEGER, name IN VARCHAR2, value IN ROWID); |
||||||||||||
| See bind_variable demo | |||||||||||||
| CLOSE_CURSOR | |||||||||||||
| Closes cursor and free memory | dbms_sql.close_cursor(c IN OUT INTEGER); | ||||||||||||
| See is_open demo | |||||||||||||
| COLUMN_VALUE | |||||||||||||
| Returns value of the cursor element for a given position in a cursor | dbms_sql.column_value ( c IN INTEGER, position IN INTEGER, value OUT <datatype> [,column_error OUT NUMBER] [,actual_length OUT INTEGER]); |
||||||||||||
| See final demo | |||||||||||||
| COLUMN_VALUE_CHAR | |||||||||||||
| Returns value of the cursor element for a given position in a cursor | dbms_sql.column_value_char ( c IN INTEGER, position IN INTEGER, value OUT CHAR CHARACTER SET ANY_CS [,column_error OUT NUMBER] [,actual_length OUT INTEGER]); |
||||||||||||
| See column_value in final demo | |||||||||||||
| COLUMN_VALUE_LONG | |||||||||||||
| Returns a selected part of a LONG column, that has been defined using DEFINE_COLUMN_LONG | dbms_sql.column_value_long ( c IN INTEGER, position IN INTEGER, length IN INTEGER, offset IN INTEGER, value OUT VARCHAR2, value_length OUT INTEGER); |
||||||||||||
| See column_value in final demo | |||||||||||||
| COLUMN_VALUE_RAW | |||||||||||||
| Returns value of the cursor element for a given position in a cursor | dbms_sql.column_value_raw ( c IN INTEGER, position IN INTEGER, value OUT RAW [,column_error OUT NUMBER] [,actual_length OUT INTEGER]); |
||||||||||||
| See column_value in final demo | |||||||||||||
| COLUMN_VALUE_ROWID | |||||||||||||
| Undoc | dbms_sql.column_value_rowid ( c IN INTEGER, position IN INTEGER, value OUT ROWID [,column_error OUT NUMBER] [,actual_length OUT INTEGER]); |
||||||||||||
| See column_value in final demo | |||||||||||||
| DEFINE_ARRAY | |||||||||||||
| Defines a collection to be selected from the given cursor, used only with SELECT statements | dbms_sql.define_array ( c IN INTEGER, position IN INTEGER, <table_variable> IN <datatype> cnt IN INTEGER, lower_bnd IN INTEGER); |
||||||||||||
| DECLARE c number; d number; n_tab dbms_sql.number_table; indx number := -10; BEGIN c := dbms_sql.open_cursor; dbms_sql.parse(c,'select n from t order by 1',dbms_sql.NATIVE); dbms_sql.define_array(c, 1, n_tab, 10, indx); d := dbms_sql.execute(c); LOOP dbms_sql.close_cursor(c); EXCEPTIONS |
|||||||||||||
| DEFINE_COLUMN | |||||||||||||
| Defines a column to be selected from the given cursor, used only with SELECT statements | dbms_sql.define_column ( c IN INTEGER, position IN INTEGER, column IN <datatype>) |
||||||||||||
| See final demo | |||||||||||||
| DEFINE_COLUMN_CHAR | |||||||||||||
| Undoc | dbms_sql.define_column_char ( c IN INTEGER, position IN INTEGER, column IN CHAR CHARACTER SET ANY_CS, column_size IN INTEGER); |
||||||||||||
| See define_column in final demo | |||||||||||||
| DEFINE_COLUMN_LONG | |||||||||||||
| Defines a LONG column to be selected from the given cursor, used only with SELECT statements | dbms_sql.define_column_long ( c IN INTEGER, position IN INTEGER); |
||||||||||||
| See define_column in final demo | |||||||||||||
| DEFINE_COLUMN_RAW | |||||||||||||
| Undoc | dbms_sql.define_column_raw ( c IN INTEGER, position IN INTEGER, column IN RAW, column_size IN INTEGER); |
||||||||||||
| See define_column in final demo | |||||||||||||
| DEFINE_COLUMN_ROWID | |||||||||||||
| Undoc | dbms_sql.define_column_rowid ( c IN INTEGER, position IN INTEGER, column IN ROWID); |
||||||||||||
| See define_column in final demo | |||||||||||||
| DESCRIBE_COLUMNS | |||||||||||||
| Describes the columns for a cursor opened and parsed through DBMS_SQL | dbms_sql.describe_columns ( c IN INTEGER, col_cnt OUT INTEGER, desc_t OUT DESC_TAB); |
||||||||||||
| DECLARE c NUMBER; d NUMBER; col_cnt PLS_INTEGER; f BOOLEAN; rec_tab dbms_sql.desc_tab; col_num NUMBER; PROCEDURE print_rec(rec in dbms_sql.desc_rec) IS BEGIN dbms_sql.parse(c, 'select * from scott.bonus', dbms_sql.NATIVE); d := dbms_sql.execute(c); dbms_sql.describe_columns(c, col_cnt, rec_tab); /* IF (col_num IS NOT NULL) THEN dbms_sql.close_cursor(c); |
|||||||||||||
| DESCRIBE_COLUMNS2 | |||||||||||||
| Describes the specified column, an alternative method | dbms_sql.describe_columns2 ( c IN INTEGER, col_cnt OUT INTEGER, desc_tab2 OUT DESC_TAB); |
||||||||||||
| Why? Research | |||||||||||||
| EXECUTE | |||||||||||||
| Execute dynamic SQL cursor | dbms_sql.execute(c IN INTEGER) RETURN INTEGER; | ||||||||||||
| DECLARE sqlstr VARCHAR2(50); tCursor PLS_INTEGER; RetVal NUMBER; BEGIN sqlstr := 'DROP SYNONYM my_synonym'; tCursor := dbms_sql.open_cursor; dbms_sql.parse(tCursor, sqlstr, dbms_sql.NATIVE); RetVal := dbms_sql.execute(tCursor); dbms_sql.close_cursor(tCursor); END; / |
|||||||||||||
| EXECUTE_AND_FETCH | |||||||||||||
| Executes a given cursor and fetch rows | dbms_sql.execute_and_fetch(c IN INTEGER, exact IN BOOLEAN DEFAULT FALSE) RETURN INTEGER; |
||||||||||||
| Combine demo w/ last_row_count and last_row_id demos | |||||||||||||
| FETCH_ROWS | |||||||||||||
| Fetches a row from a given cursor | dbms_sql.fetch_rows(c IN INTEGER) RETURN INTEGER; | ||||||||||||
| See final demo | |||||||||||||
| IS_OPEN | |||||||||||||
| Determine whether a cursor is open | dbms_sql.is_open(c IN INTEGER) RETURN BOOLEAN; | ||||||||||||
| set serveroutput on
DECLARE IF dbms_sql.is_open(tCursor) THEN dbms_sql.close_cursor(tCursor); IF dbms_sql.is_open(tCursor) THEN |
|||||||||||||
| LAST_ERROR_POSITION | |||||||||||||
| Returns byte offset in the SQL statement text where the error occurred | dbms_sql.last_error_position RETURN INTEGER; | ||||||||||||
| LAST_ROW_COUNT | |||||||||||||
| Returns cumulative count of the number of rows fetched | dbms_sql.last_row_count RETURN INTEGER; | ||||||||||||
| LAST_ROW_ID | |||||||||||||
| Returns ROWID of last row processed | dbms_sql.last_row_id RETURN ROWID; | ||||||||||||
| LAST_SQL_FUNCTION_CODE | |||||||||||||
| Returns SQL function code for statement | dbms_sql.last_sql_function_code RETURN INTEGER; | ||||||||||||
| OPEN_CURSOR | |||||||||||||
| Open dynamic SQL cursor and return cursor ID number of new cursor | dbms_sql.open_cursor RETURN INTEGER; | ||||||||||||
| See is_open demo | |||||||||||||
| PARSE | |||||||||||||
| Parse statement Overload 1 |
dbms_sql.parse(<cursor_variable>, <sql_string>, dbms_sql.NATIVE); |
||||||||||||
| CREATE SYNONYM test_syn FOR dual;
SELECT * SELECT synonym_name DECLARE SELECT synonym_name |
|||||||||||||
| -- with returning clause
create or replace procedure single_Row_insert |
|||||||||||||
| Parse statement Overload 2 |
dbms_sql.parse( c IN INTEGER, statement IN VARCHAR2A, lb IN INTEGER, ub IN INTEGER, lfflg IN BOOLEAN, language_flag IN INTEGER); |
||||||||||||
| Parse statement Overload 3 |
dbms_sql.parse( c IN INTEGER, statement IN VARCHAR2S, lb IN INTEGER, ub IN INTEGER, lfflg IN BOOLEAN, language_flag IN INTEGER); |
||||||||||||
| VARIABLE_VALUE | |||||||||||||
| Returns value of named variable for given cursor Overload 1 |
dbms_sql.variable_value( c IN INTEGER, name IN VARCHAR2, value OUT <datatype>); |
||||||||||||
| Returns value of named variable for given cursor Overload 2 |
dbms_sql.variable_value( c IN INTEGER, name IN VARCHAR2, <table_varaible> IN <datatype>); |
||||||||||||
| VARIABLE_VALUE_CHAR | |||||||||||||
| Undoc | dbms_sql.variable_value_char( c IN INTEGER, name IN VARCHAR2, value OUT CHAR CHARACTER SET ANY_CS); |
||||||||||||
| VARIABLE_VALUE_RAW | |||||||||||||
| Undoc | dbms_sql.variable_value_raw( c IN INTEGER, name IN VARCHAR2, value OUT RAW); |
||||||||||||
| VARIABLE_VALUE_ROWID | |||||||||||||
| Undoc | dbms_sql.variable_value_rowid( c IN INTEGER, name IN VARCHAR2, value OUT ROWID); |
||||||||||||
| Demos | |||||||||||||
| Drop Synonym Demo | SELECT synonym_name FROM user_synonyms; CREATE SYNONYM d FOR dept; SELECT synonym_name CREATE OR REPLACE PROCEDURE dropsyn IS CURSOR syn_cur IS RetVal NUMBER; BEGIN EXCEPTION END dropsyn; exec dropsyn; SELECT synonym_name |
||||||||||||
| Executing CLOBS Demo Tables | CREATE TABLE workstations ( srvr_id NUMBER(10), ws_id NUMBER(10), location_id NUMBER(10), cust_id VARCHAR2(15), status VARCHAR2(1), latitude FLOAT(20), longitude FLOAT(20), netaddress VARCHAR2(15)) TABLESPACE data_sml; CREATE TABLE test (test NUMBER(10)); |
||||||||||||
| Run Demo | CREATE OR REPLACE PROCEDURE execute_plsql_block( plsql_code_block CLOB) IS ds_cur PLS_INTEGER := dbms_sql.open_cursor; c_buf_len CONSTANT BINARY_INTEGER := 256; --------------------------- BEGIN BEGIN LOOP sql_table(NVL(sql_table.LAST, 0) + 1) := v_beg := v_beg + c_BUF_LEN; IF v_accum >= v_loblen THEN -- Parse the pl/sql and execute it END execute_plsql_block; |
||||||||||||
| Executing CLOBS Demo Data | DECLARE
clob_in CLOB; BEGIN execute_plsql_block(clob_in); END; |
||||||||||||
| Final Demo | CREATE OR REPLACE PROCEDURE copy( source IN VARCHAR2, destination IN VARCHAR2) IS id_var NUMBER; BEGIN dbms_sql.DEFINE_COLUMN(source_cursor, 1, id_var); ignore := dbms_sql.execute(source_cursor); -- Prepare a cursor to insert into the destination table: -- Fetch a row from the source table and insert it into the destination table: -- Bind the row into the cursor that inserts into the destination table. You could alter this example to require the use of dynamic SQL by inserting an if condition before the bind. -- Commit and close all cursors: IF dbms_sql.is_open(destination_cursor) THEN |
||||||||||||
| Bulk Insert Demo | DECLARE stmt varchar2(200); empno_array dbms_sql.number_table; empname_array dbms_sql.varchar2_table; c NUMBER; dummy NUMBER; BEGIN FOR i IN 0..9 LOOP empno_array(i) := 1000 + i; empname_array(I) := get_name(i); END LOOP; stmt := 'insert into emp values(:num_array, :name_array)'; EXCEPTIONS |
||||||||||||
使用Oracle的DBMS_SQL包执行动态SQL语句的更多相关文章
- Java下拼接执行动态SQL语句(转)
在实际业务中经常需要拼接动态SQL来完成复杂数据计算,网上各类技术论坛都有讨论,比如下面这些问题: http://bbs.csdn.net/topics/390876591 http://bbs.cs ...
- 存储过程中执行动态Sql语句
MSSQL为我们提供了两种动态执行SQL语句的命令,分别是EXEC和sp_executesql;通常,sp_executesql则更具有优势,它提供了输入输出接口,而EXEC没有.还有一个最大的好处就 ...
- Oracle 强制中止正在执行的SQL语句
-- 1 查询正在执行的sql语句 select b.sid, b.username, b.serial#, a.spid, b.paddr, c.sql_text, b.machine from v ...
- 怎样SQL存储过程中执行动态SQL语句
MSSQL为我们提供了两种动态执行SQL语句的命令,分别是EXEC和sp_executesql;通常,sp_executesql则更具有优势,它提供了输入输出接口,而EXEC没有.还有一个最大的好处就 ...
- 用sp_executesql执行动态SQL语句及获得返回值
过去我执行拼凑出来的动态SQL语句,都直接使用EXEC @sql 的方式.有好几次,都看到有资料说,应该尽量使用 sp_executesql. 究其原因,是因为仅仅参数不同的情况下,sp_execut ...
- 自定义函数执行动态sql语句
--函数中不能调用动态SQL,使用用存储过程吧.如果还要对函数做其他操作,换成存储过程不方便,可以考虑把其他操作一起封装在存储过程里面.如: create proc [dbo].[FUN_YSCL ...
- MySQL存储过程中实现执行动态SQL语句
sql语句中的任何部分都可以作为参数. DROP PROCEDURE if exists insertdata; delimiter //CREATE PROCEDURE insertdata(IN ...
- Oracle PLSQL Demo - 31.执行动态SQL拿一个返回值
DECLARE v_sql ) := ''; v_count NUMBER; BEGIN v_sql := v_sql || 'select count(1) from scott.emp t'; E ...
- Oracle基础 动态SQL语句
一.静态SQL和动态SQL的概念. 1.静态SQL 静态SQL是我们常用的使用SQL语句的方式,就是编写PL/SQL时,SQL语句已经编写好了.因为静态SQL是在编写程序时就确定了,我们只能使用SQL ...
随机推荐
- 调整JVM内存大小
首次运行公司项目,出现了内存溢出,具体出现java.lang.OutOfMemoryError: PermGen space和java.lang.OutOfMemoryError:GC overhea ...
- Servlet的客户端请求
以下内容引用自http://wiki.jikexueyuan.com/project/servlet/client-request.html: 当浏览器请求网页时,它会向Web服务器发送大量信息,这些 ...
- 003 rip
r0#config t Enter configuration commands, one per line. End with CNTL/Z. r0(config)#router rip r0(c ...
- Centos 备份 还原
備份: tar cvpzf backup.tgz / --exclude=/backup.tgz --exclude=/mnt 記得一定要排除備份文件本身哦! 還原: tar xvpfz backup ...
- 编程算法 - n个骰子的点数(递归) 代码(C)
n个骰子的点数(递归) 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 把n个骰子仍在地上, 全部骰子朝上一面的点数之和为s. 输入n, 打印出 ...
- AutoCAD如何倒角 倒圆角 倒直角
倒圆角:输f 再输r 再输入你想倒的半径,然后选相邻的两边倒直角:输chamfer 再输d 再输你想倒的距离,然后先相邻的两边 祝你成功
- C# .Net 多进程同步 通信 共享内存 内存映射文件 Memory Mapped 转 VC中进程与进程之间共享内存 .net环境下跨进程、高频率读写数据 使用C#开发Android应用之WebApp 分布式事务之消息补偿解决方案
C# .Net 多进程同步 通信 共享内存 内存映射文件 Memory Mapped 转 节点通信存在两种模型:共享内存(Shared memory)和消息传递(Messages passing). ...
- 简单区分iphone和ipad的宏定义
在公共头文件里作例如以下定义: #define IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) 使用时: if( IS_I ...
- js坑爹笔试题目汇总(持续更新中)
把你的面试官问倒,你就是一个合格的面试者了,以下总结一些易错的js笔试题目,会持续更新中.欢迎关注 1,考察this var length = 10 function fn(){ alert(this ...
- 十分简便的APK反编译(Mac 版本号 具体解释)
之前參考了网上大神们介绍的apk for mac 的反编译的文章,里面写的十分具体而有用,可是因为apk for mac中反编译细节十分繁琐,过程也相对照较复杂,针对这个缺陷本人对其反编译的过程进行 ...