一、静态SQL和动态SQL的概念。

  1、静态SQL

  静态SQL是我们常用的使用SQL语句的方式,就是编写PL/SQL时,SQL语句已经编写好了。因为静态SQL是在编写程序时就确定了,我们只能使用SQL中的DML和事务控制语句,但是DDL语句,以及会话控制语句却不能再PL/SQL中直接使用,如动态创建表或者某个不确定的操作时,这就需要动态SQL来实现。

  2、动态SQL

  动态SQL是指在PL/SQL编译时SQL语句是不确定的,如根据用户输入的参数的不同来执行不同的操作。编译程序对动态语句部分不进行处理,只是在程序运行时动态创建语句,对语句进行分析,病执行该语句。

  静态SQL的优势是性能较高,但不灵活。动态SQL的优势是灵活,缺点是性能稍差。

二、动态创建DML、DDL的SQL语句。

  动态创建SQL有一下几类:

  1、DDL语句、DCL语句、非查询的DML语句、单行查询的SELECT语句,这类可以使用EXECUTE IMMEDIATE语句执行。

  2、多行查询的SELECT语句可以使用游标来实现。

  3、通过DBMS_SQL程序包实现。

  下面来介绍以上3种情况:

  1、使用EXECUTE IMMEDIATE语句处理相关语句:

  语法:

  EXECUTE IMMEDIATE dynamic_sql_string

  [into define_variable_list]

  [using bind_argument_list];

  例:  

动态创建表t1
--处理DDL、DCL语句,根据用户输入的表明及字段名动态创建表t1
DECLARE
tablename VARCHAR2(20); --表名
field1 VARCHAR2(20); --字段1名称
datatype1 VARCHAR2(20); --字段1类型
field2 VARCHAR2(20); --字段2名称
datatype2 VARCHAR2(20); --字段2类型
str_sql VARCHAR2(500); --拼接SQL语句的字符串
BEGIN
tablename := 't1';
field1:='id';
datatype1:='number';
field2:='name';
datatype2:='varchar(20)';
str_sql := 'create table '||tablename||'('||field1 ||' '||datatype1||','||field2 ||' '||datatype2||')';
EXECUTE IMMEDIATE str_sql;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.put_line('操作失败!');
END;

  动态插入数据;  

--动态处理费查询的DML语句:向刚才创建的表中插入数据
DECLARE
v_id NUMBER; --输入序号;
v_name VARCHAR(20); --输入姓名;
str_sql VARCHAR2(500); --保存拼接的SQL语句
BEGIN
v_id := &vid;
v_name := '&name';
str_sql := 'insert into t1 values(:1,:2)'; --使用占位符代表变量
EXECUTE IMMEDIATE str_sql
USING v_id,v_name; --使用变量替换SQL中的占位符,v_id替换:1,v_name替换:2,依此类推。
COMMIT; --执行完毕后直接提交
END;

  查询表中的数据有多少行

--处理单行查询的SELECT举例,查询表中的数据有多少行
DECLARE
v_count NUMBER;
str_sql VARCHAR2(500);
BEGIN
str_sql := 'select count(*) from t1';
EXECUTE IMMEDIATE str_sql INTO v_count; --将查询的结果存放到变量v_count中。
DBMS_OUTPUT.put_line(v_count);
END;

  绑定变量的优缺点:

  1)可以再库缓存中共享游标,节省了CPU等资源,可以避免额外开销。

  2)SQL语句使用绑定变量可以避免被注入攻击。

  3)绑定变量是一种减少应用程序在分析查询时使用栓锁数目的可靠方法。

  

  不适合使用变量绑定的情况:

  1)对于隔相当长一段时间才执行一次的SQL语句,利用绑定变量的好处hi被不能有效利用而抵消。

  2)在数据仓库的情况下。

  3)在对建有索引的字段,且字段非常大时,利用绑定变量可能会导致查询计划错误,从而导致查询效率非常低。

  实现DDL语句中的注意事项:

  PL/SQL块使用动态SQL执行DDL语句的时候与其它不同,在DDL中不能使用绑定变量。

  实现DML语句中的注意事项:

  不能使用绑定变量替换实际的数据库对象名(表,视图,列等),只能替换字面两,如果对象名在运行时生成的,我们只能使用字符串拼接。

  2、通过游标实现多行查询的SELECT语句

  REF游标可以处理返回届国际的动态SQL。实现动态SQL的REF游标声明和普通REF游标相同,知识OPEN时绑定的是动态SQL字符串。

  例:查询emp表中所有的数据。

DECLARE
TYPE ref_cur IS REF CURSOR;
rc ref_cur;
emprow emp%ROWTYPE;
v_sql VARCHAR2(100):= 'select * from emp where deptno = :x'; --动态执行的SQL语句
BEGIN
OPEN rc FOR v_sql USING 30; --打开游标,绑定执行的SQL语句,并传递参数
LOOP
FETCH rc INTO emprow;
EXIT WHEN rc%NOTFOUND;
dbms_output.put_line('name:'||emprow.ename||' sal:'||emprow.sal);
END LOOP;
CLOSE rc;
END;

  3、DBMS_SQL程序包

  DBMS_SQL程序包是系统提供给我们的另一种使用动态SQL的方法。程序包中封装了一些列存储过程,帮助我们动态执行SQL。

  使用DBMS_SQL包实现动态SQL的步骤如下:

  1)将要执行的SQL语句或一个语句块放到一个字符串变量中。

  2)使用DBMS_SQL包的parse过程来分析该字符串。

  3)使用DBMS_SQL包的bind_variable过程来绑定变量。

  4)使用DBMS_SQL包的execute函数来执行语句。

  例:使用DBMS_SQL创建表  

DECLARE
tablename VARCHAR2(20) :='t2'; --表名
field1 VARCHAR2(20) :='id'; --字段1名称
datatype1 VARCHAR2(20) :='number'; --字段1类型
field2 VARCHAR2(20) :='name'; --字段2名称
datatype2 VARCHAR2(20) :='varchar(20)'; --字段2类型
v_sql VARCHAR2(500) := 'create table '||tablename||'('||field1 ||' '||datatype1||','||field2 ||' '||datatype2||')'; --拼接SQL语句的字符串
v_cursor NUMBER; --定义光标
v_row NUMBER; --行数
BEGIN
v_cursor:=dbms_sql.open_cursor; --为处理打开光标
dbms_sql.parse(v_cursor,v_sql,dbms_sql.native); --分析语句;
v_row:=DBMS_SQL.execute(v_cursor); --执行sql语句;
dbms_sql.close_cursor(v_cursor); --关闭光标;
DBMS_OUTPUT.put_line(v_row);
END;

  向表中插入一条数据:

DECLARE
v_id NUMBER := &vid;
v_name VARCHAR2(20) := '&vname';
v_sql VARCHAR2(100) := 'insert into t2 values(:id,:name)';
v_cursor NUMBER;
v_row NUMBER;
BEGIN
v_cursor:=dbms_sql.open_cursor;
dbms_sql.parse(v_cursor,v_sql,dbms_sql.native);
dbms_sql.bind_variable(v_cursor,':id',v_id);
dbms_sql.bind_variable(v_cursor,':name',v_name);
v_row := dbms_sql.execute(v_cursor);
dbms_sql.close_cursor(v_cursor);
COMMIT;
DBMS_OUTPUT.put_line(v_row);
END;

  查询EMP中的数据

  

DECLARE
V_DEPTNO NUMBER := &DEPTNO;
V_SQL VARCHAR2(100) := 'select empno,ename,sal from emp where deptno = :deptno';
V_CURSOR NUMBER;
V_NO NUMBER;
V_ENAME VARCHAR2(20);
V_SAL NUMBER;
v_start NUMBER;
BEGIN
V_CURSOR := DBMS_SQL.OPEN_CURSOR; --打开游标
DBMS_SQL.PARSE(V_CURSOR, V_SQL, DBMS_SQL.NATIVE); --解析动态SQL语句
DBMS_SQL.BIND_VARIABLE(V_CURSOR, ':deptno', V_DEPTNO); --传递参数 DBMS_SQL.DEFINE_COLUMN(V_CURSOR, 1, V_NO); --定义输出的列,和查询的列相匹配
DBMS_SQL.DEFINE_COLUMN(V_CURSOR, 2, V_ENAME,20);
DBMS_SQL.DEFINE_COLUMN(V_CURSOR, 3, V_SAL); v_start := DBMS_SQL.execute(V_CURSOR); --执行SQL语句,需要有接受返回值 LOOP
EXIT WHEN DBMS_SQL.FETCH_ROWS(V_CURSOR) <= 0; --解析游标,
DBMS_SQL.COLUMN_VALUE(V_CURSOR, 1, V_NO); --将当前行的数据写入上面对应的列中。
DBMS_SQL.COLUMN_VALUE(V_CURSOR, 2, V_ENAME);
DBMS_SQL.COLUMN_VALUE(V_CURSOR, 1, V_SAL); DBMS_OUTPUT.PUT_LINE('no:' || V_NO || ' enmae:' || V_ENAME ||' sal:' || V_SAL); --输出内容
END LOOP;
dbms_sql.close_cursor(v_cursor); --关闭游标
END;

Oracle基础 动态SQL语句的更多相关文章

  1. oracle 存储过程 动态sql语句

    一.在oracle项目开发中越到问题: 在利用ODP向oracle中插入数据时,如果这样写:   insert into clobTable (id, story) values(1,'....'); ...

  2. MySQL基础----动态SQL语句

    尊重原创:http://blog.csdn.net/abc19900828/article/details/39501643   动态sql语句基本语法 1 :普通SQL语句可以用Exec执行 eg: ...

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

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

  4. oracle中动态SQL使用详细介绍

    Oracle编译PL/SQL程序块分为两个种:通常静态SQL采用前一种编译方式,而动态SQL采用后一种编译方式,需要了解的朋友可以参考下     1.静态SQLSQL与动态SQL Oracle编译PL ...

  5. (转)Oracle中动态SQL详解

    本文转载自:http://www.cnblogs.com/gaolonglong/archive/2011/05/31/2064790.html 1.静态SQLSQL与动态SQL Oracle编译PL ...

  6. [转载]Oracle中动态SQL详解

    1.静态SQLSQL与动态SQL Oracle编译PL/SQL程序块分为两个种:其一为前期联编(early binding),即SQL语句在程序编译期间就已经确定,大多数的编译情况属于这种类型:另外一 ...

  7. Oracle中动态SQL详解(EXECUTE IMMEDIATE)

    Oracle中动态SQL详解(EXECUTE IMMEDIATE) 2017年05月02日 18:35:48 悠悠倾我心 阅读数:744 标签: oracle动态sqloracle 更多 个人分类:  ...

  8. MyBatis学习(三)、动态SQL语句

    三.动态SQL语句 有些时候,sql语句where条件中,需要一些安全判断,例如按某一条件查询时如果传入的参数是空,此时查询出的结果很可能是空的,也许我们需要参数为空时,是查出全部的信息.使用Orac ...

  9. 三、动态SQL语句

    //备注:该博客引自:http://limingnihao.iteye.com/blog/106076 有些时候,sql语句where条件中,需要一些安全判断,例如按某一条件查询时如果传入的参数是空, ...

随机推荐

  1. 【LeetCode】 Subsets

    Given a set of distinct integers, S, return all possible subsets. Note: Elements in a subset must be ...

  2. 关于favicon.ico的使用

    http://www.cnblogs.com/LoveJenny/archive/2012/05/22/2512683.html

  3. FlashPaper 使用经验之谈

    李志海  20101229  QQ:76855049 CSDN:资源下载地址:http://lizhihai_99.download.csdn.net/ http://download.csdn.ne ...

  4. Ember学习(8):REOPENING CLASSES AND INSTANCES

    英文原址:http://emberjs.com/guides/object-model/reopening-classes-and-instances/ 你不须要一次就完毕类所有内容的定义,通过reo ...

  5. codeforces 377A. Puzzles 水题

    A. Puzzles Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://codeforces.com/problemset/problem/33 ...

  6. Linux中搭建SVNserver

    一 下载工具 1. subversion-1.6.17.tar.gz 2. subversion-deps-1.6.17.tar.gz 二 解压两个包: 1.在此之前,我已经创建了一个用户svnroo ...

  7. [连载]JavaScript讲义(05)--- 数据处理

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamFja2ZydWVk/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA ...

  8. static使用方法小结

    static使用方法小结 statickeyword是C, C++中都存在的keyword, 它主要有三种使用方式, 当中前两种仅仅指在C语言中使用, 第三种在C++中使用(C,C++中详细细微操作不 ...

  9. Redis缓存服务搭建及实现数据读写

    发现博客园中好多大牛在介绍自己的开源项目是很少用到缓存,比如Memcached.Redis.mongodb等,今天得空抽时间把Redis缓存研究了一下,写下来总结一下,跟大家一起分享 一下.由于小弟水 ...

  10. iOS开发——动画编程Swift篇&(四)CABasicAnimation动画

    CABasicAnimation动画 //CABasicAnimation-不透明度 @IBAction func cabOpacity() { let animation = CABasicAnim ...