Oracle入门(十四.18)之使用动态SQL

一、SQL的执行流程

数据库中的所有SQL语句都经历了不同的阶段:
•解析:预执行“这可能吗?”检查包括语法,对象存在,权限等
•绑定:获取语句中引用的任何变量的实际值
•执行:语句被执行。

•提取:结果返回给用户。

某些阶段可能与所有语句无关;例如,提取阶段适用于查询,但不适用于DML。


二、PL / SQL子程序中SQL的执行流程

当PL / SQL子程序中包含SQL语句时,解析和绑定阶段通常是在编译时完成的,也就是说,当过程,函数或包体是CREATEd时。

如果在创建过程时SQL语句的文本未知,该怎么办? Oracle服务器如何解析它? 它不能。 例如,假设您想要删除一个表,但用户在执行时输入表名:

CREATE PROCEDURE drop_any_table(p_table_name VARCHAR2)
IS BEGINDROP TABLE p_table_name; -- cannot be parsed
END;


三、动态SQL

您使用动态SQL来创建一个SQL语句,其中的文本事先不完全知道。
动态SQL:
•构造并存储为子程序内的字符串。
•是否包含具有不同列数据的SQL语句,或带有或不带有占位符(绑定变量)的不同条件。

•使数据定义,数据控制或会话控制语句能够从PL / SQL写入和执行。

(1)本地动态SQL

PL / SQL不支持直接写在procedure中的DDL语句。 本地动态SQL允许您通过在子程序中构建SQL并将其存储为字符串来解决此问题。 本地动态SQL:
•以PL / SQL语言直接为动态SQL提供本机支持。

•使数据定义,数据控制或会话控制语句能够从PL / SQL写入和执行。

•使用本机动态SQL语句(EXECUTE IMMEDIATE)或DBMS_SQL包执行。
•提供执行直到执行时间结构未知的SQL语句的能力。

•也可以使用OPEN-FOR,FETCH和CLOSE PL / SQL语句。

(2)使用EXECUTE IMMEDIATE语句

在PL / SQL匿名块或子程序中为原生动态SQL使用EXECUTE IMMEDIATE语句:

EXECUTE IMMEDIATE dynamic_string
[INTO {define_variable[, define_variable] ... | record}]
[USING [IN|OUT|IN OUT] bind_argument[, [IN|OUT|IN OUT] bind_argument] ... ];
•INTO用于单行查询,并指定检索列值的变量或记录。

•USING保存所有绑定参数。 如果未指定,则默认参数模式为IN。

•dynamic_string是包含SQL语句文本的字符变量或文字。
•define_variable是一个PL / SQL变量,用于存储选定的列值。
•record是存储选定行的用户定义或%ROWTYPE记录。

•bind_argument是一个表达式,其值在执行时传递给动态SQL语句。

•USING子句保存所有绑定参数。 默认参数模式是IN。

示例1:使用DDL语句的动态SQL

在线构建动态声明:

CREATE PROCEDURE drop_any_table(p_table_name VARCHAR2) IS
BEGINEXECUTE IMMEDIATE 'DROP TABLE '||p_table_name;
END;

在一个变量中构造动态语句:

CREATE PROCEDURE drop_any_table(p_table_name VARCHAR2) ISv_dynamic_stmt VARCHAR2(50);
BEGINv_dynamic_stmt := 'DROP TABLE '||p_table_name;EXECUTE IMMEDIATE v_dynamic_stmt;
END;
BEGINdrop_any_table('EMPLOYEE_NAMES'); 
END;
示例2:使用DML语句的动态SQL

删除任何表中的所有行并返回计数:

CREATE FUNCTION del_rows(p_table_name VARCHAR2)
RETURN NUMBER IS
BEGINEXECUTE IMMEDIATE 'DELETE FROM '||p_table_name;RETURN SQL%ROWCOUNT;
END;

调用该函数:

DECLAREv_count NUMBER;
BEGINv_count := del_rows('EMPLOYEE_NAMES');DBMS_OUTPUT.PUT_LINE(v_count|| ' rows deleted.');
END;
示例3:使用DML语句的动态SQL

这是一个将行插入两列并调用过程的示例。

CREATE PROCEDURE add_row(p_table_name VARCHAR2,p_id NUMBER, p_name VARCHAR2) IS
BEGINEXECUTE IMMEDIATE 'INSERT INTO '||p_table_name||' VALUES (p_id, p_name)';
END;
BEGIN
add_row('EMPLOYEE_NAMES', 250, 'Chang');
END;
示例4:使用本机动态SQL重新编译PL / SQL代码

您可以使用下列ALTER语句重新编译PL / SQL对象而不重新创建它们:

ALTER PROCEDURE procedure-name COMPILE;
ALTER FUNCTION function-name COMPILE;
ALTER PACKAGE package_name COMPILE SPECIFICATION;
ALTER PACKAGE package-name COMPILE BODY;

本示例创建一个过程,用于重新编译在运行时输入其名称和类型的PL / SQL对象。

CREATE PROCEDURE compile_plsql
(p_name VARCHAR2,p_type VARCHAR2,p_options VARCHAR2 := NULL) ISv_stmt VARCHAR2(200);
BEGINv_stmt := 'ALTER '||p_type||' '||p_name||' COMPILE'||' '||p_options;EXECUTE IMMEDIATE v_stmt;
END;
BEGIN compile_plsql('MYPACK','PACKAGE','BODY'); END;


四、使用DBMS_SQL包

(1)DBMS_SQL包的一些过程和功能是:

• OPEN_CURSOR

• PARSE

• BIND_VARIABLE

• EXECUTE

• FETCH_ROWS

• CLOSE_CURSOR

(2)使用带有DML语句的DBMS_SQL

删除行的示例:

CREATE OR REPLACE FUNCTION del_rows
(p_table_name VARCHAR2) RETURN NUMBER ISv_csr_id INTEGER;v_rows_del NUMBER;
BEGINv_csr_id := DBMS_SQL.OPEN_CURSOR;DBMS_SQL.PARSE(v_csr_id,'DELETE FROM '||p_table_name, DBMS_SQL.NATIVE);v_rows_del := DBMS_SQL.EXECUTE (v_csr_id);DBMS_SQL.CLOSE_CURSOR(v_csr_id);RETURN v_rows_del;
END;

请将本文前面的内容与del_rows函数进行比较。 它们功能相同,但更简单?

(3)使用带有参数化DML语句的DBMS_SQL

再次,将其与本课前面的add_row过程进行比较。 你宁愿写什么?
CREATE PROCEDURE add_row (p_table_name VARCHAR2,
p_id NUMBER, p_name VARCHAR2) ISv_csr_id INTEGER;v_stmt VARCHAR2(200);v_rows_added NUMBER;
BEGINv_stmt := 'INSERT INTO '||p_table_name||' VALUES ('||p_id||','''||p_name||''')';v_csr_id := DBMS_SQL.OPEN_CURSOR;DBMS_SQL.PARSE(v_csr_id,v_stmt, DBMS_SQL.NATIVE);v_rows_added := DBMS_SQL.EXECUTE(v_csr_id);DBMS_SQL.CLOSE_CURSOR(v_csr_id);
END;


五、本地动态SQL与DBMS_SQL包的比较

原生动态SQL

•比DBMS_SQL更易于使用
•比DBMS_SQL需要更少的代码

•通常执行速度比DBMS_SQL快,因为执行的语句较少。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/329319.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

天平游码读数例题_初二上册物理实验——托盘天平使用的注意事项

今天给大家讲讲托盘天平的使用和注意事项。(1)首先,我们回忆一下什么是托盘天平如下图托盘天平由底座、横梁、分度盘、托盘、平衡螺母、标尺、游码、托盘等组成,当然还有砝码。托盘天平是称量物体的质量的工具(质量符号m,单位:国际…

3.elasticsearch文档查询dsl

【README】 1.本文elasticsearch版本是 7.2.1; 2.文档查询语句叫做 DSL, domain structure language, 领域特定语言;dsl,参见 Query DSL | Elasticsearch Guide [7.2] | Elastic 3.elasticsearch 基于json 提供了完…

Oracle入门(十四.19)之触发器简介

一、触发器的需求让我们从一个例子开始吧:一条业务规则规定,只要员工的工资发生变化,变更就必须记录在日志记录表中。 可以创建两个过程来执行此操作:UPD_EMP_SAL更新工资,LOG_SAL_CHANGE将行插入日志表。可以从UPD_EM…

搜狐视频Redis私有云cachecloud开源了

项目地址:https://github.com/sohutv/cachecloud/ 一、CacheCloud是做什么的 CacheCloud提供一个Redis云管理平台:实现多种类型(Redis Standalone、Redis Sentinel、Redis Cluster)自动部署、解决Redis实例碎片化现象、提供完善统计、监控、运维功能、减…

springboot 订单重复提交_瞬间几千次的重复提交,我用Spring Boot+Redis扛住了

在实际的开发项目中,一个对外暴露的接口往往会面临,瞬间大量的重复的请求提交,如果想过滤掉重复请求造成对业务的伤害,那就需要实现幂等!我们来解释一下幂等的概念:任意多次执行所产生的影响均与一次执行的…

Oracle入门(十四.21)之创建DML触发器:第二部分

一、使用条件谓词 在上文中,看到了一个触发器,可以防止在周末插入EMPLOYEES: CREATE OR REPLACE TRIGGER secure_emp BEFORE INSERT ON employees BEGINIF TO_CHAR(SYSDATE,DY) IN (SAT,SUN) THENRAISE_APPLICATION_ERROR(-20500,You may ins…

【直播预告】创享未来 2016微软开发者峰会

感谢所有中国开发者对2016微软开发者峰会的热情关注,目前活动已经截止报名了,不过M姐为大家带来新的福利: 2016微软开发者峰会将全程线上直播! 2016微软开发者峰会将全程线上直播! 2016微软开发者峰会将全程线上直播…

定时任务重启后执行策略_C语言操作时间函数time.ctime,实现定时执行某个任务小例子...

时间操作函数在实际项目开发中会经常用到,最近做项目也正好用到就正好顺便整理一下。时间概述由上图可知:通过系统调用函数time()可以从内核获得一个类型为time_t的1个值,该值叫calendar时间,即从1970年1月1日的UTC时间从0时0分0妙…

Oracle入门(十四.20)之创建DML触发器:第一部分

一、什么是DML触发器?DML触发器是执行SQL DML语句(INSERT,UPDATE或DELETE)时自动触发(执行)的触发器。 您可以通过两种方法对DML触发器进行分类: •执行时间:BEFORE,AFTE…

IIS负载均衡-Application Request Route详解第四篇:使用ARR实现三层部署架构

本篇的主要目的是带领大家一起来使用ARR来实现一个三层部署架构。这里的三层部署架构主要是由:服务层,应用程序服务器层已经数据层实现。如下图所示: 每次一提到“层”这个字的时候,似乎感觉这个字特别的惹火。很多朋友开始讨论起…

c遗传算法的终止条件一般_KDD比赛之遗传算法(举例理解)

求最大值问题是这样的:求解函数 f(x) x 10*sin(5*x) 7*cos(4*x) 在区间[0,9]的最大值。这个函数大概长这样:那么如何应用遗传算法如何来找到这个奇怪的函数的最大值呢?事实上,不管一个函数的形状多么奇怪,遗传算法都…

6.elasticsearch查询与过滤上下文(query context与filter contenxt)以及term术语查询

【README】 1.本文总结自: Query and filter context | Elasticsearch Guide [7.2] | Elastichttps://www.elastic.co/guide/en/elasticsearch/reference/7.2/query-filter-context.html2.文档相关性分数是否被计算,取决于查询子句是在查询上下文&…

Oracle入门(十四.22)之创建DDL和数据库事件触发器

一、什么是DDL和数据库事件触发器?DDL语句触发DDL触发器:CREATE,ALTER或DROP。 数据库事件触发器由数据库中的非SQL事件触发,例如: •用户连接到数据库或与数据库断开连接。 •DBA启动或关闭数据库。•用户会话中引发了…

Visual Studio上开发Python?你不可不知道的六大功能!

Visual Studio 2013/2015 搭配 Python Tools for Visual Studio 扩充套件让 Visual Studio 能提供对 Python 程序语言高度整合的开发环境,并完整发挥 Visual Studio 强大的功能,协助您在 Visual Studio 内开发 Python 程序上如虎添翼,提升开发…

qt中sendevent_Qt中postEvent和sendEvent函数

Qt中postEvent和sendEvent函数部分内容参考http://blog.csdn.net/lvmengzou/article/details/65450908qt事件循环需要维护一个事件队列,在Qt的main函数中最后一般调用QApplication::exec()成员函数来保持程序对事件队列的处理,exec()的实质是不停调用pro…

IIS负载均衡-Application Request Route详解第五篇:使用ARR来配置试点项目

看到本篇的题目,大家可能感到有点奇怪!下面,我们就来看看这到底是什么意思。 大家可能遇到过这样的一种情况:希望根据某些请求用户的特性,将用户的请求导向不同的站点(请大家这里区分“亲缘性”的概念&…

Oracle入门(十四.23)之管理触发器

一、触发器需要特权要在模式中创建触发器,需要: •CREATE TRIGGER系统特权 •触发器主体中引用的其他架构中的对象的普通对象特权(SELECT,UPDATE,EXECUTE等) •与触发器关联的表或视图上的ALTER特权。触发器…

为什么哲学是最难的学科_什么是哲学哲学对大师来说可能非常理论化,没有一定哲学基础肯能很难 爱问知识人...

我的总结是科学哲学是从哲学角度考察科学的一门学科。它以科学活动和科学理论为研究对象,探讨科学的本质、科学知识的获得和检验、科学的逻辑结构等有关科学认识论和科学方法论的基本问题。哲学是什么?这是一个问题,一个既简单又复杂的问题。…

8.es更新文档通过版本号实现并发控制

【README】 1.本文介绍了es更新文档时的并发控制策略;2.通过版本号实现并发控制(类似于mysql中基于版本号的乐观锁);3.Es为支持并发控制,为每篇文章设置了版本号_version。初始值为1,每更新1次加1。…

Oracle入门(十五)之数据库锁

一、锁的概念 锁是数据库用来控制共享资源并发访问的机制。锁用于保护正在被修改的数据直到提交或回滚了事务之后,其他用户才可以更新数据二、锁定的优点 一致性 - 一次只允许一个用户修改数据完整性 - 为所有用户提供正确的数据。如果一个用户进行了修改并保存&a…