游标和动态SQL
游标类别:静态游标(指在编译的时候,游标就与一个select语句进行了静态绑定的游标。这样的游标仅仅能作用于一个查询语句)和动态游标(就是希望我们的查询语句在执行的时候才跟游标绑定。为了使用动态游标,必须声明游标变量)。
动态游标分两种,各自是强类型和弱类型。强类型的动态游标仅仅能支持查询结果与他类型匹配的这样的查询语句。弱类型的动态游标能够支持不论什么的查询语句。
静态游标分为两种,隐式游标和显示游标。显示游标是实用户声明和操作的一种游标。隐式游标是Oracle为全部的数据操作语句自己主动声明的一种游标。
在每一个用户的会话中,我们能够同一时候打开多个游标,这个数量有数据库初始化參数文件里的OPEN CURSORS这个參数来定义。
显示游标的使用方法步骤:
1、声明显式游标,语法:CURSOR<游标名>ISSELECT<语句>;
在声明游标的时候通常还要声明一些变量用来存放查询语句产生的查询结果。声明游标和变量都在declare中的。通常先声明变量,在声明游标。
2、打开游标,从打开游标開始。后面的步骤都是在begin和end中运行的。语法:open<游标名>;当打开游标后查询语句就開始运行了,查询结果放到Oracle的缓冲区中,然后游标指向了这个缓冲区中查询结果的第一行记录之前。
3、提取游标,通过提取游标,游标依次指向查询结果的每一行。语法:FETCH<游标名>INTO<变量列表>;
4、关闭游标。语法:CLOSE<游标名>;
演示样例:
declare
name varchar2(50); --定义变量存储employees表中的内容。 department_name varchar2(20); --定义变量存储departments表中的内容;
cursor emp_cur IS --定义游标emp_cur
select name,department_name --选出全部员工的姓名和所做部门。 from employees e,departments d
where e.department_id=d.department_id;
begin
open emp_cur; --打开游标
LOOP
FETCH emp_cur INTO name,depart_name; --将第一行数据放入变量中,游标后移。 EXIT WHEN emp_cur%NOTFOUND;
dbms_output.put_line(name||’在’||department_name);
END LOOP;
CLOSE emp_cur;
END;
游标的属性:%ISOPEN,游标是否打开;%FOUND,游标是否指向有效行;%NOTFOUND。游标是否没有指向有效行;%ROWCOUNT。游标抽取过的行数。
语法:游标名%属性名。
比如:公司上市,决定给员工提高薪资。入职时间超过1年涨100。1000元封顶。
declare
hire_date date; --存放员工入职日期
e_id number; --存放员工id
cursor emp_cur is --定义游标
select id,hire_date from employees;
begin
open emp_cur; --打开游标
loop
fetch emp_cur into e_id,hire_date --将数据逐条存入变量
exit when emp_cur%NOTFOUND;
if 100*(2014-to_char(hire_date,’yyyy’))<1000 then
update salary setsalaryvalue=salaryvalue+100*(2010-to_char(hire_date,’yyyy’)) where employee.id=e_id;
else
update salary setsalaryvalue=salaryvalue+1000 where employee.id=e_id;
end if;
end loop;
close emp_cur;
end
使用循环游标游标的读取。语法:FOR <类型>
IN <游标名>LOOP –操作各行数据 END LOOP;
DECLARE
CURSOR emp_cur IS
SELECT name,department_name
FROM employees e,departments d;
WHERE e.department_id=d.department_id;
BEGIN
FOR employ_record IN emp_cur LOOP
dnms_output.put_line(employ_record.name||’在’||employee_record.department_name);
END LOOP;
END;
隐式游标
隐式游标与显示游标的差别:1、不用声明游标。2、不用打开和关闭游标。3、必须使用INTO子句,结果仅仅能是一条。
隐式游标与显示游标的同样的:有同样的属性。隐式游标使用属性的方法是在属性名前面加上SQL%。即SQL%FOUND。SQL%ISOPEN等。
DECLARE
name VARCHAR2(50);
department_name varchar(20);
BEGIN
SELECT name,department_name
INTO name,deprtment_name
FROM employees e,departments d;
WHERE e.department_id=d.department_id and e.id=1;
dbms_output.put_line(name||’在’||department_name);
END;
由于隐式游标查询结果仅仅有一行,所以假设用来计数没有多大的意义。所以%ROECOUNT这个属性经经常使用来推断插入、删除、更新是否成功,可是要在COMMIT语句之前。假设在COMMIT之后,%ROECOUNT仅仅能是0;
begin
update employees set name=name||’A’
where id=7;
if sql%rowcount=1 then
dbms_output.put_line(‘表已更新!’);
else
dbms_output.put_line(‘编号未找到’);
end if;
end;
REF动态游标
ref动态游标能够在执行的时候与不同的语句进行关联。他是动态的。ref动态游标被用于处理多行的查询结果集,ref动态游标是ref类型的变量,类似于指针。
定义ref动态游标类型:type<类型名>
is ref cursor return <返回类型>;
声明ref动态游标:<游标名>
<类型名>;
打开ref动态游标:OPEN<游标名>
FOR <查询语句>;
演示样例:
DECLARE
TYPE refcur_t IS REF CURSOR
RETURN employess%ROWTYPE;
refcur refcur_t;
v_emp employees%ROWTYPE;
BEGIN
OPEN refcur FOR
SELECT * FROM employees;
LOOP
FETCH refcur INTO v_emp;
EXIT WHEN refcur%NOTFOUND;
dbms_output.put_line(refcur%ROWCOUNT||’‘||v_emp.name);
END LOOP;
CLOSE refcur;
END;
强类型ref动态游标:带有RETURN语句的REF动态游标。
弱类型ref动态游标:不带有RETURN语句的REF动态游标。
比如:
DECLARE
TYPE refcur_t IS REF CURSOR
refcur refcur_t;
e_id number;
e_name varchar2(50);
BEGIN
OPEN refcur FOR
SELECT id,name FROM employees;
FETCH refcur INTO e_id,e_name;
WHILE refcur%FOUND LOOP
dbms_output.put_line(‘#’||e_id||’:’||e_name);
FETCH refcur INTO e_id,e_name;
END LOOP;
CLOSE refcur;
END;
依据用户的输入(员工、部门)信息打印
DECLARE
TYPE refcur_t IS REF CURSOR;
refcur refcur_t;
p_id NUMBER;
p_name VARCHAR2(50);
selection VARCHAR2(1) :=UPPER(SUBSTR(‘&tab’,1,1));
BEGIN
IF selection = ‘E’ THEN
OPEN refcur FOR
SELECT id,name FROMemployees;
dbms_output.put_line(‘===员工信息===’);
ELSEIF selection = ‘D’ THEN
OPEN refcur FOR
SELECTdepartment_id,department_name FROM departments;
dbms_output.put_line(‘===部门信息===’);
ELSE
dbms_output.put_line(‘请输入员工信息E或部门信息D’);
RETURN;
END IF;
FETCH refcur INTO p_id,p_name;
WHILE refcur%FOUND LOOP
dbms_output.put_line(‘#’||p_id||’:’||p_name);
FETCH refcur INTO p_id,p_name;
END LOOP;
CLOSE refcur;
END;
创建动态SQL语句。
静态SQL,编译时确定。
动态SQL。不编译,运行时动态确定。依据用户输入參数等才干确定SQL语句。解决PL/SQL中不支持DDL语句的问题。
创建动态DML.DDL的SQL语句语法:
EXECUTEIMMEDIATE ‘DML、DDL语句’;[INTO<变量序列>]
[USING <參数序列>];仅仅能运行返回一行或0行的语句。
假设后面的语句是个select语句。则能够使用into子句用于接收select语句选择的记录值。
能够是一个变量序列,或者一个记录型变量也就是record型的变量。假设SQL语句中有參数须要动态确定,那么我们使用USING子句。USING子句用于绑定输入的參数变量。
SQL语句中若有參数。使用”:參数名”
演示样例:动态创建表
BEGIN
EXECUTE IMMEDIATE
‘CREATE TABLE bonus(id NUMBER,amtNUMBER)’;
END;
演示样例:动态查询一个员工电话
DECLARE
sql_stmt VARCHAR2(200);
emp_id NUMBER(10) :=’&emp_id’;
emp_rec employees%ROWTYPE;
BEGIN
sql_stmt :=’select * from employees WHEREid =:id’;
EXECUTE IMMEDIATE sql_stmt INTO emp_recUSING emp_id;
END;
演示样例:动态插入记录
DECLARE
Sql_stmt varchar2(200);
emp_id NUMBER(10) := ‘&emp_id’;
emp_rec employees%ROWTYPE;
BEGIN
sql_stmt := ‘INSERT INTO employees(id)values(:id)’;
EXECUTE IMMEDIATE sql_stmt USING emp_id;
Dbms_output.put_line(emp.rec.phone);
END;
EXECUTEIMMEDIATE语句仅仅能返回一行或没有返回,假设编写返回多行的SQL语句,能够使用ref动态游标,他的语法:OPEN
cursor_name FOR <SQL语句> [USING <參数序列>];
演示样例:动态输出工资大于某个数额的员工信息
DECLARE
e_id NUMBER(10);
e_name VARCHAR2(50);
s_salary NUMBER(8);
TYPE c_type is REF CURSOR;
cur c_type;
p_salary NUMBER := ‘&p_id’;
BEGIN
OPEN cur FOR ‘selecte.id,e.name,e.salaryvalue from employees e,salary s where e.id=s.employeeid ands.salaryvalue >:sal ORDER BY id ASC’;
USING p_salary;
dbms_output.put_line(‘薪水大于’||p_salary||’的员工有:’);
LOOP
FETCH cur INTOe_id,e_name,e_salary;
EXIT WHEN cur%NOTFOUND;
dbms_output.put_line(‘编号:’||e_id||’姓名:’||e_name||’薪水:’||e_salary);
END LOOP
CLOSE cur;
END;
游标和动态SQL的更多相关文章
- 游标、动态sql、异常
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAlIAAAFeCAIAAADBl2bCAAAgAElEQVR4nOyddXgU197H12OEELxIkV
- 在PL/SQL中使用游标、动态sql和绑定变量的小例子
需求:查询并输出30号部门的雇员信息 方式一:使用 loop...fetch SET serveroutput ON; DECLARE CURSOR c_emp IS ; v_emp emp%rowt ...
- 动态SQL详解
动态SQL 在之前用户所编写的PL/SQL程序时有一个最大的特点:就是所操作的数据库对象(例如:表)必须存在,否则创建的子程序就会出问题,而这样的操作在开发之中被称为静态SQL操作,而动态SQL操作可 ...
- Mysql - 游标/动态sql/事务
游标这个在我目前的项目里面用的还不多, 但是其功能还是很强大的. 动态sql以前都没用过, 是跟着富士康(不是张全蛋的富土康哦)过来的同事学的. 还是挺好用的. 我的数据库方面, 跟他学了不少. 在此 ...
- 动态游标(例如表名作为参数)以及动态SQL分析
表名作为参数的动态游标 DECLARE v_table_name VARCHAR2(30) := 'CUX_MES_WIP_BARCODE_MAP'; --l_rec SYS_REFCURSOR; T ...
- MySQL通过视图(或临时表)实现动态SQL(游标)
>参考de优秀文章 写MySQL存储过程实现动态执行SQL Dynamic cursor in stored procedure MySQL通过视图(或临时表)实现动态SQL(游标). 因在实现 ...
- 在PL/SQL使用游标获取数据及动态SQL
1.游标概念: 当在PL/SQL块中执行DML(增删改)时,Oracle会为其分配上下文区(Context Area),游标是指向上下文区的指针 2. 游标分类: A. 隐式游标 a. 在PL/ ...
- 动态游标(比如表名作为參数)以及动态SQL分析
表名作为參数的动态游标 DECLARE v_table_name VARCHAR2(30) := 'CUX_MES_WIP_BARCODE_MAP'; --l_rec SYS_REFCURSOR; T ...
- 游标使用 和sp_executesql动态sql
/****** Script for SelectTopNRows command from SSMS ******/ declare @oid int declare @cid int declar ...
随机推荐
- JavaScript AMD规范简单介绍(一)
AMD是"Asynchronous Module Definition"的缩写.意思就是"异步模块定义". AMD定义了我们所用的模块都是是异步载入的,所以我们 ...
- Swift - 制作一个在线流媒体音乐播放器(使用StreamingKit库)
在之前的文章中,我介绍了如何使用 AVPlayer 制作一个简单的音乐播放器(点击查看1.点击查看2).虽然这个播放器也可以播放网络音频,但其实际上是将音频文件下载到本地后再播放的. 本文演示如何使用 ...
- phpmyadmin客户端多服务器配置
修改libraries/config.default.php 545行,添加 $cfg['Servers']['2'] = $cfg['Servers'][$i];$cfg['Servers']['2 ...
- java.lang.ClassNotFoundException: org.objectweb.asm.ClassWriter
转自:https://www.cnblogs.com/yfceshi/p/6814802.html Caused by: javax.xml.ws.WebServiceException: java. ...
- [JavaEE] Maven简介
转载自:百度 http://baike.baidu.com/view/336103.htm?fr=aladdin 一.简介 Maven是基于项目对象模型(POM),可以通过一小段描述信息来管理项目的构 ...
- 不使用Store安装WSL
Windows Store经常会因为各种原因打不开, 这时候我们可以尝试直接下载安装WSL 1. PowerShell里运行下载: PS C:\WINDOWS\system32> Inv ...
- c++ set_union set_intersection使用
自定义类型也可以构造set,但同样必须定义“小于”运算符,set中的元素从小到大排列好了 #include<iostream>#include<string>#include ...
- 项目中解决实际问题的代码片段-javascript方法,Vue方法(长期更新)
总结项目用到的一些处理方法,用来解决数据处理的一些实际问题,所有方法都可以放在一个公共工具方法里面,实现不限ES5,ES6还有些Vue处理的方法. 都是项目中来的,有代码跟图片展示,长期更新. 1.获 ...
- JQuery学习系列篇(一)
jQuery是一套Javascript脚本库:注意jQuery是脚本库, 而不是脚本框架. "库"不等于"框架", 比如"System程序集" ...
- Android Studio配置GreenDAO 3.2.0和使用方法
我相信,在平时的开发过程中,大家一定会或多或少地接触到SQLite.然而在使用它时,我们往往需要做许多额外的工作,像编写SQL语句与解析查询结果等.所以,适用于Android ORM框架也就孕育而生了 ...