oracle动态sql的详细介绍
Oracle的PL / SQL编译器块分为两种类型:一为预链接(早期绑定),在编译程序中的SQL语句已经确定,编译大多数属于这一类型;另一种是后期绑定(后期绑定),只有在运行阶段的SQL语句可以建立,例如当用户输入查询条件,然后Oracle的SQL引擎不会在编译的程序语句的时间是确定的,只有在一定的条件下,处理后提交给SQL引擎对用户输入的查询。通常,静态SQL使用以前的编译模式,而动态SQL使用后者的编写模式。
本文主要讨论动态SQL的开发,并给出了一些实用的开发技术。
2。动态sql程序开发
掌握了动态sql编译的基本原理,掌握了动态sql的基本思想,由于动态sql是一种不确定的SQL,它的实现有其自身的特点,在oracle中提供了执行即时语句来执行动态sql,其语法如下:
复制代码代码如下所示:
立即执行动态SQL语句使用绑定参数列表返回到输出参数的列表;这句话的解释如下:
1)动态SQL是指DDL和DML的不确定性(即DML与参数)
2)绑定参数列表是输入参数列表,也就是说,它的类型是类型,它与动态SQL语句中的参数(实际占位符,在函数中可以理解为函数的形式参数)绑定。
3)输出参数列表是执行动态SQL语句后返回的参数列表。
4)由于动态SQL是在运行时确定的,与静态相比,它将失去一些系统性能,以换取灵活性。
为了更好地说明它的发展过程,下面列出了一个例子。
设置数据库的EMP表,以下数据如下:
身份证件
名称
工资
一百
杰克
五千六百
一百零一
玫瑰
三千
一百零二
约翰
四千五百
要求uff1a
1。创建表并输入相应的数据。
2。他们的姓名和薪水的信息可以根据特定的ID查询。
三.对应于大于特定工资的查询的相应员工信息。
根据前面的需求,您可以创建三个进程,分别使用动态SQL:
过程1:
复制代码代码如下所示:
创建或替换程序create_table作为
开始
立即执行
创建表EMP(ID号),
名称VARCHAR2(10),
工资数);动态SQL DDL语句
插入EMP
值(100,'jacky ',5600);
插入EMP
值(101,'rose ',3000);
插入EMP
值(102,约翰',4500);
最后create_table;
过程中的两个:
复制代码代码如下所示:
创建或替换程序find_info(p_id数)为
v_name VARCHAR2(10);
v_salary数;
开始
立即执行
从EMP中选择名字、薪水
其中id =:1
使用p_id
回到v_name,v_salary;动态SQL查询语句
dbms_output.put_line(v_name | | 'income:| | to_char(v_salary));
例外
当别人然后
dbms_output.put_line(没有找到相应的数据);
最后find_info;
过程三:
复制代码代码如下所示:
Create or replace procedure find_emp (p_salary number) as
r_emp EMP %ROWTYPE;
c_type是REFCURSOR类型;
C1 c_type;
开始
打开C1
从EMP中选择*
工资范围>:1
使用p_salary;
环
取到r_emp C1;
退出时未发现C1 %;
dbms_output.put_line('salary| | to_char(p_salary)| | 'employees:);
dbms_output.put_line('id'to_char(r_emp)| | 'its名称:| | r_emp。名称);
结束循环;
关闭C1;
最后create_table;
注意:流程2中的动态SQL语句使用占位符:1,它相当于函数的形参。它是用来作为前缀,然后使用using语句来代替p_id在运行时:1,在这里p_id相当于函数的实际参数。此外,光标第三开辟过程是动态游标。它也属于动态sql的范畴。整个编译和开发过程非常类似于直接执行的执行过程。
三.动态sql语句的开发技术
上述分析,基于其灵活性的系统性能损失的动态SQL语句的执行,所以优化在一定程度上是必要的,根据实际开发经验,提出了一些开发技巧,需要指出的是,有很多的经验并不局限于动态SQL,也有适用于静态SQL将在注释的描述。
技巧1:尝试使用类似的SQL语句,这样Oracle本身就可以通过SGA中的共享池直接缓存SQL语句。然后,在下一次执行类似语句后,我们将直接调用缓存中的解析语句,从而提高执行效率。
技巧二:当涉及到集合单位时,尽量尽可能使用批量编辑器。例如,一般要求100和101的雇员增加10%的工资。
复制代码代码如下所示:
声明
num_list VARRAY类型是(20)号;
v_id num_list:= num_list(100101);
开始
…
我在v_id。第一..v_id.last环
…
执行immediate'update EMP
设置=工资* 1.2
其中id =:1
使用v_id(我);
结束循环;
结束;
对于上述处理,当数据量较大时会比较慢,所以如果链接的数量,整组一次性一次性传递给SQL引擎,这个处理效率要大大高于分离、批量处理的链接代码:
复制代码代码如下所示:
声明
num_list VARRAY类型是(20)号;
v_id num_list:= num_list(100101);
开始
…
就我在v_id。第一..v_id.last环
…
Execute immediate'update EMP
设置=工资* 1.2
其中id =:1
使用v_id(我);
结束循环;
结束;
这里是批量编辑所有的使用,使得该批处理的情况总结。
1)如果一个循环执行插入、删除、更新、和其他陈述是指集合元素,那么它可以被移动到一个FORALL语句。
2)如果选择进入、进入或返回子句,指一个集合,则应使用批量收集子句进行合并。
3)如果可能的话,应该使用主机数组来实现程序和数据库服务器之间的参数。
技巧三:使用nocopy编译器提高PL / sql.by默认性能的型,在型的价值转移的方式进行参数。但对于对象或类型的传输类型的参数设置,希望损失会很大,为了减少损失,可以用来参考的方式,即在参数声明的关键字参考nocopy规格可以达到同样的效果。例如,创建一个进程:
复制代码代码如下所示:
创建或替换程序测试(在p_object nocopy广场)…结束;
正方形是一个大对象类型,这是唯一的传递地址的方法,而不是整个对象。显然,这种处理也提高了效率。
4。总结
本文讨论了动态sql的编译原理、开发过程和开发技巧。本文在介绍了这篇文章之后,相信读者对动态sql程序的发展有了一个大致的了解,为以后的进一步工作打下了良好的基础。