技术标签: oracle --------1.1 ORACLE
我们经常需要运行可变化的SQL语句,这种通常称为动态SQL,在ORACLE中执行动态的SQL语句,需要了解ORACLE的动态SQL语句的相关规定。
SQL动态语句是由程序或者存储过程生成的SQL语句,这种语句的特点是,不能简单的去运行。因为它不是标准的,其中含有变化的成分,因此ORACLE提供了一个执行动态SQL语句的模式:
EXECUTE IMMEDIATE
这句话的含义是立即执行,而不先去进行语法检查,在执行过程中可能会发生逻辑错误,则通过错误中断进行处理。
/***
DBMS_OUTPUT.PUT_LINE(uSQL);
p_Money_TJ
CALL p_Money_TJ();
测试在SQL*PLUS下进行
VAR r refcursor;
Exec p_Money_TJ(:r);
print r;
***/
CREATE OR REPLACE PROCEDURE p_Money_TJ(p_cur out sys_refcursor)
AS
-- 变量定义
Cursor CC IS
SELECT FTYPE FROM APP_MONEY GROUP BY FTYPE;
uSQL VARCHAR2(32600);
BEGIN
uSQL := 'BEGIN OPEN :p_cur for ';
uSQL := uSQL || 'SELECT FMID 会员账号,F_GETXM(FMID) 会员姓名';
FOR C IN CC LOOP
uSQL := uSQL || ',SUM(CASE WHEN FTYPE = '''||C.FTYPE||''' THEN FMONEY END) '||C.FTYPE;
END LOOP;
uSQL := uSQL || ' FROM APP_MONEY GROUP BY FMID';
uSQL := uSQL || '; END;';
EXECUTE IMMEDIATE uSQL USING p_cur;
END;
1、声明动态游标
TYPE cc_type IS REF CURSOR;
2、声明游标变量
my_cursor cc_type;
3、使用游标
n_deptno:=20;
uSQL := 'SELECT empno,ename FROM emp WHERE deptno = '||n_deptno;
OPEN my_cursor FOR uSQL;
LOOP
FETCH my_cursor INTO n_empno,v_ename;
EXIT WHEN my_cursor%NOTFOUND;
--用n_empno,v_ename做其它处理
--....
END LOOP;
CLOSE my_cursor;
4、小结
动态游标可以胜任大多数动态SQL的需求了,使用简洁方便。
最早大家都使用DBMS_SQL包,但是太太麻烦了,最终都放弃了。但是自从有了EXECUTE IMMEDIATE之后,但要注意以下几点:
EXECUTE IMMEDIATE代替了以前 Oracle8i 中 DBMS SQL package包, 它解析并马上执行动态的SQL语句或非运行时创建的PL/SQL块。动态创建和执行SQL语句性能超前,EXECUTE IMMEDIATE的目标在于减小企业费用并获得较高的性能,较之以前它相当容易编码。尽管DBMS_SQL仍然可用,但是推荐使用EXECUTE IMMEDIATE,因为它获的收益在包之上。
使用技巧
1. EXECUTE IMMEDIATE将不会提交一个DML事务执行,应该显式提交如果通过EXECUTE IMMEDIATE处理DML命令,那么在完成以前需要显式提交或者作为EXECUTE IMMEDIATE自己的一部分. 如果通过EXECUTE IMMEDIATE处理DDL命令,它提交所有以前改变的数据
2. 不支持返回多行的查询,这种交互将用临时表来存储记录(参照例子如下)或者用REF cursors.
3. 当执行SQL语句时,不要用分号,当执行PL/SQL块时,在其尾部用分号.
4. 在Oracle手册中,未详细覆盖这些功能。下面的例子展示了所有用到Execute immediate的可能方面.希望能给你带来方便.
5. 对于Forms开发者,当在PL/SQL 8.0.6.3.版本中,Forms 6i不能使用此功能.
begin
execute immediate 'set role all';
end;
declare
l_depnam varchar2(20) := 'testing';
l_loc varchar2(10) := 'Dubai';
begin
execute immediate 'insert into dept values (:1, :2, :3)'
using 50, l_depnam, l_loc;
commit;
end;
declare
l_cnt varchar2(20);
begin
execute immediate 'select count(1) from emp'
into l_cnt;
dbms_output.put_line(l_cnt);
end;
例程中用到的绑定变量参数必须指定参数类型.黓认为IN类型,其它类型必须显式指定
declare
l_routin varchar2(100) := 'gen2161.get_rowcnt';
l_tblnam varchar2(20) := 'emp';
l_cnt number;
l_status varchar2(200);
begin
execute immediate 'begin ' || l_routin || '(:2, :3, :4); end;'
using in l_tblnam, out l_cnt, in out l_status;
if l_status != 'OK' then
dbms_output.put_line('error');
end if;
end;
同样也可用%rowtype变量
declare
type empdtlrec is record (empno number(4),ename varchar2(20),deptno number(2));
empdtl empdtlrec;
begin
execute immediate 'select empno, ename, deptno '||'from emp where empno = 7934'
into empdtl;
end;
INTO子句用在USING子句前
declare
l_dept pls_integer := 20;
l_nam varchar2(20);
l_loc varchar2(20);
begin
execute immediate 'select dname, loc from dept where deptno = :1'
into l_nam, l_loc
using l_dept ;
end;
对此选项用insert语句填充临时表,用临时表进行进一步的处理,也可以用REF cursors纠正此缺憾.
declare
l_sal pls_integer := 2000;
begin
execute immediate 'insert into temp(empno, ename) ' ||
' select empno, ename from emp ' ||
' where sal > :1'
using l_sal;
commit;
end;
对于处理动态语句,EXECUTE IMMEDIATE比以前可能用到的更容易并且更高效.当意图执行动态语句时,适当地处理异常更加重要.应该关注于捕获所有可能的异常.
Oracle 动态SQL
Oracle 动态SQL有两种写法:用 DBMS_SQL 或 execute immediate,建议使用后者。试验步骤如下:
/*** DDL ***/
begin
EXECUTE IMMEDIATE 'drop table temp_1';
EXECUTE IMMEDIATE 'create table temp_1(name varchar2(8))';
end;
/*** DML ***/
declare
v_1 varchar2(8);
v_2 varchar2(10);
str varchar2(50);
begin
v_1:='测试人员';
v_2:='北京';
str := 'INSERT INTO test (name ,address) VALUES (:1, :2)';
EXECUTE IMMEDIATE str USING v_1, v_2;
commit;
end;
declare
str varchar2(500);
c_1 varchar2(10);
r_1 test%rowtype;
begin
c_1:='测试人员';
str:='select * from test where name=:c WHERE ROWNUM=1';
execute immediate str into r_1 using c_1;
DBMS_OUTPUT.PUT_LINE(R_1.NAME||R_1.ADDRESS);
end ;
CREATE OR REPLACE package pkg_test as
/* 定义ref cursor类型
不加return类型,为弱类型,允许动态sql查询,
否则为强类型,无法使用动态sql查询;
*/
type myrctype is ref cursor;
--函数申明
function get(intID number) return myrctype;
end pkg_test;
/
CREATE OR REPLACE package body pkg_test as
--函数体
function get(intID number) return myrctype is
rc myrctype; --定义ref cursor变量
sqlstr varchar2(500);
begin
if intID=0 then
--静态测试,直接用select语句直接返回结果
open rc for select id,name,sex,address,postcode,birthday from
student;
else
--动态sql赋值,用:w_id来申明该变量从外部获得
sqlstr := 'select id,name,sex,address,postcode,birthday from student
where id=:w_id';
--动态测试,用sqlstr字符串返回结果,用using关键词传递参数
open rc for sqlstr using intid;
end if;
return rc;
end get;
end pkg_test;
最近涉及到一个关于数据分析的需求,入手学习python1.pythonmac上有自带的python ,系统大于等于OS X 10.8,系统自带了Python 2.7以上的版本。登录终端输入python可以进入交互式环境,进行简单的一些操作,如果是设计编程开发就使用一个支持python的编译器也很方便。 在终端输入 type -a python 可以查看路径 2.编辑器配置python我_pycharm 安装'mlxtend
小程序的生命周期_小程序生命周期有哪些
我们知道java中有三种注释方式1. // 单行2. /* .......*/ 单行 或多行3. /** .......*/ 单行 或多行我们的目的就是把以上三种特征的注释替换以下是例子 String s = “。。。。。。。。”; // 将文件的内容赋值给s Pattern pattern1 = Pattern
ENVI5.1于2013年12月正式发布,延续ENVI5的界面风格。支持最新的传感器、支持hdf5数据;新的光谱曲线显示窗口;新增流程化的镶嵌工具,能自动生成接边线、新增高级的色彩平衡功能;全新的ROI工具,可将ROI用于任何与之有地理重叠的栅格数据;提供更多的波谱库数据、全球DEM数据、全球小比例尺shapefile矢量数据;新增工程化的管理方式,能将打开的多个数据保存成...
1.写一个NSString类的实现+ (id)initWithCString:(const char*)nullTerminatedCString encoding:(NSStringEncoding)encoding{ NSString*obj; obj= [self allocWithZone: NSDefaultMallocZone()]; obj=
单元测试(UT)工具:一键测试所有Bean/DTO的SetGet方法_单元测试databasebean
专家简介 张效信,博士生导师,研究员,服务于中国气象局国家卫星气象中心/国家空间天气监测预警中心,担任国家空间天气预报台台长,主要负责推动中国气象局天地一体化的空间天气业务发展。承担多项国家/部委级项目,多次参与国内重大空间学术活动和计划,包括中国双星计划、夸父计划、子午工程、风云卫星工程以及中国气象局气象灾害与监测预警工程等。目前担任世界气象组织(World Meteorological Or...
open() “/var/lib/nginx/tmp/client_body/0000000001” failed (13: Permission denied)1. 首先查看 /var/lib/nginx/tmp/client_body 目录权限2.与php-fpm nginx 用户一致查看 php 用户查看nginx 3.查看nginx.conf配置增加如下配置client_max_body_size 64m; 默认1m 根据机器性能调 cl..._/var/lib/nginx/tmp/client_body/0000000001" failed
Java解leetcode,助力面试之简单10道题(九)第671题 二叉树中第二小的节点解题思路代码第680题 验证回文字符串 Ⅱ解题思路代码第693题 交替位二进制数解题思路代码第696题 计数二进制子串解题思路代码第697题 数组的度解题思路代码第704题 二分查找解题思路代码第705题 设计哈希集合解题思路代码第720题 词典中最长的单词解题思路代码第744题 寻找比目标字母大的最小字母解题思路代码第766题 托普利茨矩阵解题思路代码第671题 二叉树中第二小的节点示例 1:输入输出
剑指offer——15.二进制中 1 的个数——分析及代码[Java]一、题目二、分析及代码1. 各位依次判断(1)思路(2)代码(3)结果2. 更高效的算法(1)思路(2)代码(3)结果三、其他一、题目输入一个整数,输出该数二进制表示中 1 的个数,其中负数用补码表示。二、分析及代码1. 各位依次判断(1)思路判断二进制中 1 的个数,可以通过将输入整数的各个位置依次与仅该位置为 1...
SpringBoot 多模块项目遇到的坑(一)一、问题:ERROR: Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources) on project demo-web-b: Input length = 1 -> [Help 1]---------------------------------------------------------
1、安装Bluster 驱动:2、查看FPGA开发板的硬件资源;3、下载例子,熟悉流程;4、Modelsim联合Quartus II进行仿真。对应的文档下载:http://pan.baidu.com/s/