游标类别:静态游标(指在编译的时候,游标就与一个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的更多相关文章

  1. 游标、动态sql、异常

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAlIAAAFeCAIAAADBl2bCAAAgAElEQVR4nOyddXgU197H12OEELxIkV

  2. 在PL/SQL中使用游标、动态sql和绑定变量的小例子

    需求:查询并输出30号部门的雇员信息 方式一:使用 loop...fetch SET serveroutput ON; DECLARE CURSOR c_emp IS ; v_emp emp%rowt ...

  3. 动态SQL详解

    动态SQL 在之前用户所编写的PL/SQL程序时有一个最大的特点:就是所操作的数据库对象(例如:表)必须存在,否则创建的子程序就会出问题,而这样的操作在开发之中被称为静态SQL操作,而动态SQL操作可 ...

  4. Mysql - 游标/动态sql/事务

    游标这个在我目前的项目里面用的还不多, 但是其功能还是很强大的. 动态sql以前都没用过, 是跟着富士康(不是张全蛋的富土康哦)过来的同事学的. 还是挺好用的. 我的数据库方面, 跟他学了不少. 在此 ...

  5. 动态游标(例如表名作为参数)以及动态SQL分析

    表名作为参数的动态游标 DECLARE v_table_name VARCHAR2(30) := 'CUX_MES_WIP_BARCODE_MAP'; --l_rec SYS_REFCURSOR; T ...

  6. MySQL通过视图(或临时表)实现动态SQL(游标)

    >参考de优秀文章 写MySQL存储过程实现动态执行SQL Dynamic cursor in stored procedure MySQL通过视图(或临时表)实现动态SQL(游标). 因在实现 ...

  7. 在PL/SQL使用游标获取数据及动态SQL

    1.游标概念: 当在PL/SQL块中执行DML(增删改)时,Oracle会为其分配上下文区(Context Area),游标是指向上下文区的指针 2.  游标分类: A.  隐式游标 a.  在PL/ ...

  8. 动态游标(比如表名作为參数)以及动态SQL分析

    表名作为參数的动态游标 DECLARE v_table_name VARCHAR2(30) := 'CUX_MES_WIP_BARCODE_MAP'; --l_rec SYS_REFCURSOR; T ...

  9. 游标使用 和sp_executesql动态sql

    /****** Script for SelectTopNRows command from SSMS ******/ declare @oid int declare @cid int declar ...

随机推荐

  1. Share Your Knowledge and Experiences

     Share Your Knowledge and Experiences Paul W. Homer FRoM All oF ouR ExpERiEnCES, including both suc ...

  2. Log使用

    学习参考:http://blog.csdn.net/hu_shengyang/article/details/6754031 log4j三种主要组件: logger记录对象 appender输出对象 ...

  3. Linux以下基于TCP多线程聊天室(client)

    不怎么会弄这个博客的排版,就直接将代码附上: 主要是使用多线程去等待接受数据和发送数据.以下是client的代码: tcpsed.h文件 1 2 3 4 5 6 7 8 9 10 11 12 13 1 ...

  4. Unable to access the IIS metabase

    https://stackoverflow.com/questions/12859891/error-unable-to-access-the-iis-metabase 解决方法1 On Window ...

  5. linux下配置虚拟域名

    linux下配置虚拟域名 1.hosts文件位置! /etc/hosts 2.增加一行 127.0.0.1 xxxxx 3.修改apache中的vhosts vi /etc/httpd/extra/h ...

  6. dns tunnel C&C

    通过DNS控制主机以及执行命令 我的ubuntu 安装过程 1854 mkdir dns_tunnel_tool 1855 cd dns_tunnel_tool/ 1856 ls 1857 git c ...

  7. css元素垂直居中方法

    1.Line-height 适用情景:单行文字垂直居中技巧 这个方式应该是最多人知道的了,常见于单行文字的应用,像是按钮这一类对象,或者是下拉框.导航此类元素最常见到的方式了.此方式的原理是在于将单行 ...

  8. JEE Spring-boot 简单的ioc写法。

    什么是ioc,就是你可能会有一些生活必需品,这些东西你必须要用才能存活.但是你不是每天都回去买,去哪一家点去买.而这些用品会一直放在哪里,每一个商店就是一个容器,包裹着这些物品. 创建ioc项目,首先 ...

  9. SQL Server-聚焦聚集索引对非聚集索引的影响

      前言 在学习SQL 2012基础教程过程中会时不时穿插其他内容来进行讲解,相信看过SQL Server 2012 T-SQL基础教程的童鞋知道前面写的所有内容并非都是摘抄书上内容,如若是这样那将没 ...

  10. C语言宏定义#define用法

    #define是C语言中提供的宏定义命令,其主要目的是为程序员在编程时提供一定的方便,并能在一定程度上提高程序的运行效率,但学生在学习时往往不能 理解该命令的本质,总是在此处产生一些困惑,在编程时误用 ...