当前位置: 首页 > 编程日记 > 正文

Oracle基础 动态SQL语句

一、静态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
DECLAREtablename VARCHAR2(20);        --表名field1 VARCHAR2(20);           --字段1名称datatype1 VARCHAR2(20);        --字段1类型field2 VARCHAR2(20);           --字段2名称datatype2 VARCHAR2(20);        --字段2类型str_sql VARCHAR2(500);         --拼接SQL语句的字符串
BEGINtablename := 't1';field1:='id';datatype1:='number';field2:='name';datatype2:='varchar(20)';str_sql := 'create table '||tablename||'('||field1 ||' '||datatype1||','||field2 ||' '||datatype2||')';EXECUTE IMMEDIATE str_sql;EXCEPTIONWHEN OTHERS THENDBMS_OUTPUT.put_line('操作失败!');
END;

动态插入数据;

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

查询表中的数据有多少行

--处理单行查询的SELECT举例,查询表中的数据有多少行
DECLAREv_count NUMBER;str_sql VARCHAR2(500);
BEGINstr_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表中所有的数据。

DECLARETYPE ref_cur IS REF CURSOR;rc ref_cur;emprow emp%ROWTYPE;v_sql VARCHAR2(100):= 'select * from emp where deptno = :x';   --动态执行的SQL语句
BEGINOPEN rc FOR v_sql USING 30;   --打开游标,绑定执行的SQL语句,并传递参数
  LOOPFETCH 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创建表

DECLAREtablename 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;                                   --行数
BEGINv_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;

向表中插入一条数据:

DECLAREv_id NUMBER := &vid;v_name VARCHAR2(20) := '&vname';v_sql VARCHAR2(100) := 'insert into t2 values(:id,:name)';v_cursor NUMBER;v_row NUMBER;
BEGINv_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中的数据

DECLAREV_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;
BEGINV_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语句,需要有接受返回值
LOOPEXIT 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;

转载于:https://www.cnblogs.com/zhengcheng/p/4207376.html

相关文章:

dataTables常用参数

一、新版本和老版本的区别 新版本的改进&#xff1a;https://datatables.net/new/1.10 新老版本参数变化列表&#xff1a;http://datatables.club/upgrade/1.10-convert.html 老版本参数列表&#xff1a; http://legacy.datatables.net/usage/features http://legacy.datatable…

[微信小程序]获取用户当前的城市

有问题可以扫码加我微信&#xff0c;有偿解决问题。承接小程序开发。 微信小程序开发交流qq群 173683895 、 526474645 &#xff1b; 正文&#xff1a; // 获取用户当前位置的名称和城市 util.jsfunction location() {// 实例化腾讯位置服务里面微信小程序JS SDK的API核心…

构建一个react项目_您想要了解更多有关React的内容吗? 让我们构建一个游戏,然后玩。...

构建一个react项目by Samer Buna通过Samer Buna 您想要了解更多有关React的内容吗&#xff1f; 让我们构建一个游戏&#xff0c;然后玩。 (Do you want to learn more about React? Let’s build — and then play — a game.) Update: This article is now part of my book …

vijos 1476 旅游规划题解

题目链接&#xff1a;https://vijos.org/p/1476 解&#xff1a;因为这一定是一棵树&#xff0c;所以我们多画几次图&#xff0c;就会发现所有的最长路径中心点都一样&#xff0c;且中心点把这条最长路径分成两段等长的路。 那么做法就很简单啦&#xff0c;先求出图的最长路径长…

JQ实现导航效果(附效果图)

微信小程序开发交流qq群 581478349 承接微信小程序开发。扫码加微信。 正文&#xff1a; 为了不浪费大家时间, 首先来一张效果图看是不是你需要的 下面是完整的代码和详细的注释. 直接copy就可以用了. html <div id"tab" class"tab"><div…

.NET如何从配置文件中获取连接字符串

一.设置配置文件 <configuration><!--在configuration下创建一个connectionStrings--><connectionStrings><!--以类似键值对的形式&#xff0c;设置好名字和连接字符串--><add name"连接名" connectionString"连接字符串"/>…

javascript 代码_如何使您JavaScript代码保持简单并提高其可读性

javascript 代码by Leonardo Lima莱昂纳多利马(Leonardo Lima) 如何使您JavaScript代码保持简单并提高其可读性 (How to keep your JavaScript code simple and increase its readability) After a few years working almost exclusively with Ruby on Rails and some jQuery,…

《转》Python学习(14)-对文件的操作(一)

转自 http://www.cnblogs.com/BeginMan/p/3166644.html 一、文件对象 我理解的文件对象就是一个接口&#xff0c;通过这个接口对文件进行相关操作。 《Python 核心编程》上说的很晦涩&#xff0c;这里没有深刻理解到&#xff0c;希望有人能解释给我听。 >>> f open(d…

[微信小程序]组件化开发,以一个自定义模块框组件当做示例(附完整示例代码和效果图)

微信小程序开发交流qq群 173683895 承接微信小程序开发。扫码加微信。 正文&#xff1a; 自定义组件我把它分为简单的三个步骤, 1.创建组件 --- 2.编写组件 --- 3.调用,使用组件. 第一步:创建组件 创建一个modal文件夹,里面包含 josn.wxml.wcss.js 四个文件,然后在jo…

openstack安装在虚拟机上重启之后无法启动问题

http://www.byywee.com/page/M0/S931/931767.html 运行rejoin-stack.sh脚本的核心&#xff1a; exec screen -c $TOP_DIR/stack-screenrc stack-screenrc文件存储启动的信息&#xff1a; 例如trove的启动 screen -t tr-api bash stuff "/usr/local/bin/trove-api --config…

让我们讨论一下变量,以及为什么要在JavaScript中使用它们。

by Zell Liew由Zell Liew 让我们讨论一下变量&#xff0c;以及为什么要在JavaScript中使用它们。 (Let’s talk about variables — and why you should use them in JavaScript.) The main purpose of coding is to solve problems. For example, what happens when you clic…

Services(服务)

开启服务有两种方式&#xff1a; 如果不会可以看老师的百度音乐盒的案例1、start方式&#xff1a;start方式的生命周期&#xff1a;*服务只会被开启一次&#xff0c;直到用户手动停止 服务才会被销毁*开启需要调用startService 会执行onCreate(),onStartCommand() *注&…

[敏捷开发实践](2) 用于开发和维持复杂产品的敏捷开发框架Scrum

[敏捷开发实践]&#xff08;2&#xff09; 用于开发和维持复杂产品的敏捷开发框架Scrum 1&#xff0c;Scrum概述 上篇中提到敏捷开发有两种主流的方法&#xff0c;一个是XP&#xff0c;另一个是Scrum&#xff0c;本篇简要介绍Scrum方法。Scrum是一套开发和维护复杂产品的框架或…

js 实现多选框(复选框) 和单选框,下拉框功能完整示例代码附效果图

<!DOCTYPE html> <html><head><meta charset"utf-8" /><script src"http://cdn.static.runoob.com/libs/jquery/2.1.1/jquery.min.js"></script><title>单选框,复选框,下拉菜单简单示例</title></head…

ruby on rails_我成为了Ruby on Rails和React的贡献者,你也可以

ruby on railsI am really grateful to have contributed to a few open source projects, including two I currently use on a regular basis: Ruby on Rails and React.我非常感谢为一些开源项目做出了贡献&#xff0c;其中包括我目前定期使用的两个项目&#xff1a; Ruby o…

MySQL加密算法

1.不可逆加密&#xff1a; PASSWORD()&#xff0c;ENCRYPT(&#xff0c;)&#xff0c;MD5()&#xff0c;SHA5()。 2.可逆的加密算法&#xff1a; ENCODE(,) DECODE(,)&#xff1a;加密解密字符串。该函数有两个参数&#xff1a;被加密或解密的字符串和作为加密或解密基础的密…

js回调函数和函数带参数的使用示例

微信小程序开发交流qq群 173683895 承接微信小程序开发。扫码加微信。 //demo1 <html><head><meta charset"UTF-8"><script src"http://cdn.static.runoob.com/libs/jquery/2.1.1/jquery.min.js"></script></head>&…

mvc-3模型和数据(1)

MVC和命名空间 var User function(atts) {this.attribute atts || {}; } //和具体user相关的方法 User.prototype.destroy function() {}; //和具体user不相关的函数和变量 User.fetchRemove function() {}; var user new User({name:jinks}); user.destroy();构建对象关系…

初步了解:使用JavaScript进行表达式(De Do Do Do,De Da Da Da)

by Donavon West由Donavon West 初步了解&#xff1a;使用JavaScript进行表达式(De Do Do Do&#xff0c;De Da Da Da) (A first look: do expressions in JavaScript (De Do Do Do, De Da Da Da)) This article is not about about the The Police’s 1980 hit song from alb…

div 下 的img水平居中

设置text-align:center; 这个div必须要设置宽度&#xff1b; 如&#xff1a;{text-align:center; width:100%;}转载于:https://www.cnblogs.com/zzd0916/p/6626772.html

Understanding SOAP

Understanding SOAP转载于:https://www.cnblogs.com/daishuguang/p/4227983.html

js删除组数中的某一个元素(完整代码附效果图)

微信小程序开发交流qq群 173683895 承接微信小程序开发。扫码加微信。 正文&#xff1a; <view class"big-logos"> <imagebindtap"addimg"src../../../image/s.png></image> <blockwx:for"{{img_arr}}"wx:key"in…

c专家编程/c陷阱_如何避免常见的初学者陷阱并像专家一样开始编码

c专家编程/c陷阱by Dmitri Grabov德米特里格拉波夫(Dmitri Grabov) 如何避免常见的初学者陷阱并像专家一样开始编码 (How to avoid common beginner pitfalls and start coding like a pro) Learning to code is tough. We’ve all encountered cryptic errors and code break…

xmpp关于后台挂起的消息接收,后台消息推送,本地发送通知

想问下&#xff0c;在xmpp即时通讯的项目中&#xff0c;我程序如果挂起了&#xff0c;后台有消息过来&#xff0c;我这边的推送不过来&#xff0c;所以我的通知就会收不到消息&#xff0c;当我重新唤醒应用的时候&#xff0c;他才会接收到通知&#xff0c;消息就会推送过来&…

[冲昏头脑]IDEA中的maven项目中学习log4j的日志操作

第一&#xff0c;你要有log4j的对应的包&#xff0c;由于我用的maven&#xff0c;所以直接在pom.xml文件依赖下载则可&#xff0c;如你尚为有此包&#xff0c;请自行百度下载导入&#xff0c;或上http://www.mvnrepository.com/搜索。上如则是我的log4j的包的版本。好了&#x…

女神推荐, 卡片,广告图 ,点击查看更多

微信小程序开发交流qq群 581478349 承接微信小程序开发。扫码加微信。 正文&#xff1a; <view><view classtitle>女神推荐 </view> <image stylemargin-top:25rpx; classtab_img src{{img list_data.q1[1].image}}></image><view classv…

aws lambda_恐怕您正在考虑AWS Lambda的冷启动完全错误

aws lambdaby Yan Cui崔燕 恐怕您正在考虑AWS Lambda的冷启动完全错误 (I’m afraid you’re thinking about AWS Lambda cold starts all wrong) When I discuss AWS Lambda cold starts with folks in the context of API Gateway, I often get responses along the line of…

python tkinter窗口弹出置顶的方法

加上下面两句即可实现root窗口的置顶显示&#xff0c;可以用于某些程序的消息提示&#xff0c;能够弹出到桌面显示 root Tk() root.wm_attributes(-topmost,1) 转载于:https://www.cnblogs.com/shuchengxiang/p/6632140.html

用Quartus II Timequest Timing Analyzer进行时序分析 :实例讲解 (一)

一&#xff0c;概述 用Altera的话来讲&#xff0c;timequest timing analyzer是一个功能强大的&#xff0c;ASIC-style的时序分析工具。采用工业标准--SDC&#xff08;synopsys design contraints&#xff09;--的约束、分析和报告方法来验证你的设计是否满足时序设计的要求。在…

软件工程与软件测试基础知识_这是我在软件工程工作九个月中学到的知识

软件工程与软件测试基础知识I’ve been working for about nine months at Dexter as a software developer. I wrote a blog post about landing the job initially, as well as a technical post about a self positioning component I made in my first couple of months at…