文档库 最新最全的文档下载
当前位置:文档库 › Oracle 游标使用全解

Oracle 游标使用全解

Oracle 游标使用全解
Oracle 游标使用全解

-- 声明游标;CURSOR cursor_name IS select_statement

--For 循环游标

--(1)定义游标

--(2)定义游标变量

--(3)使用for循环来使用这个游标

declare

--类型定义

cursor c_job

is

select empno,ename,job,sal

from emp

where job='MANAGER';

--定义一个游标变量v_cinfo c_emp%ROWTYPE ,该类型为游标c_emp中的一行数据类型

c_row c_job%rowtype;

begin

for c_row in c_job loop

dbms_output.put_line(c_row.empno||'-'||c_row.ename||'-'||c_row.job||'-'||c_row.sal);

end loop;

end;

--Fetch游标

--使用的时候必须要明确的打开和关闭

declare

--类型定义

cursor c_job

is

select empno,ename,job,sal

from emp

where job='MANAGER';

--定义一个游标变量

c_row c_job%rowtype;

begin

open c_job;

loop

--提取一行数据到c_row

fetch c_job into c_row;

--判读是否提取到值,没取到值就退出

--取到值c_job%notfound 是false

--取不到值c_job%notfound 是true

exit when c_job%notfound;

dbms_output.put_line(c_row.empno||'-'||c_row.ename||'-'||c_row.job||'-'||c_row.sal);

end loop;

--关闭游标

close c_job;

end;

--1:任意执行一个update操作,用隐式游标sql的属性%found,%notfound,%rowcount,%isopen观察update语句的执行情况。

begin

update emp set ENAME='ALEARK'WHERE EMPNO=7469;

if sql%isopen then

dbms_output.put_line('Openging');

else

dbms_output.put_line('closing');

end if;

if sql%found then

dbms_output.put_line('游标指向了有效行');--判断游标是否指向有效行

else

dbms_output.put_line('Sorry');

end if;

if sql%notfound then

dbms_output.put_line('Also Sorry');

else

dbms_output.put_line('Haha');

end if;

dbms_output.put_line(sql%rowcount);

exception

when no_data_found then

dbms_output.put_line('Sorry No data');

when too_many_rows then

dbms_output.put_line('Too Many rows');

end;

declare

empNumber emp.EMPNO%TYPE;

empName emp.ENAME%TYPE;

begin

if sql%isopen then

dbms_output.put_line('Cursor is opinging');

else

dbms_output.put_line('Cursor is Close');

end if;

if sql%notfound then

dbms_output.put_line('No Value');

else

dbms_output.put_line(empNumber);

end if;

dbms_output.put_line(sql%rowcount);

dbms_output.put_line('-------------');

select EMPNO,ENAME into empNumber,empName from emp where EMPNO=7499; dbms_output.put_line(sql%rowcount);

if sql%isopen then

dbms_output.put_line('Cursor is opinging');

else

dbms_output.put_line('Cursor is Closing');

end if;

if sql%notfound then

dbms_output.put_line('No Value');

else

dbms_output.put_line(empNumber);

end if;

exception

when no_data_found then

dbms_output.put_line('No Value');

when too_many_rows then

dbms_output.put_line('too many rows');

end;

--2,使用游标和loop循环来显示所有部门的名称

--游标声明

declare

cursor csr_dept

is

--select语句

select DNAME

from Depth;

--指定行指针,这句话应该是指定和csr_dept行类型相同的变量

row_dept csr_dept%rowtype;

begin

--for循环

for row_dept in csr_dept loop

dbms_output.put_line('部门名称:'||row_dept.DNAME);

end loop;

end;

--3,使用游标和while循环来显示所有部门的的地理位置(用%found属性)

declare

--游标声明

cursor csr_TestWhile

is

--select语句

select LOC

from Depth;

--指定行指针

row_loc csr_TestWhile%rowtype;

begin

--打开游标

open csr_TestWhile;

--给第一行喂数据

fetch csr_TestWhile into row_loc;

--测试是否有数据,并执行循环

while csr_TestWhile%found loop

dbms_output.put_line('部门地点:'||row_loc.LOC);

--给下一行喂数据

fetch csr_TestWhile into row_loc;

end loop;

close csr_TestWhile;

end;

select*from emp

--4,接收用户输入的部门编号,用for循环和游标,打印出此部门的所有雇员的所有信息(使用循环游标)

--CURSOR cursor_name[(parameter[,parameter],...)] IS select_statement;

--定义参数的语法如下:Parameter_name [IN] data_type[{:=|DEFAULT} value]

declare

CURSOR

c_dept(p_deptNo number)

is

select*from emp where emp.depno=p_deptNo;

r_emp emp%rowtype;

begin

for r_emp in c_dept(20) loop

dbms_output.put_line('员工号:'||r_emp.EMPNO||'员工名:'||r_emp.ENAME||'工资:'||r_emp.SAL);

end loop;

end;

select*from emp

--5:向游标传递一个工种,显示此工种的所有雇员的所有信息(使用参数游标)

declare

cursor

c_job(p_job nvarchar2)

is

select*from emp where JOB=p_job;

r_job emp%rowtype;

begin

for r_job in c_job('CLERK') loop

dbms_output.put_line('员工号'||r_job.EMPNO||''||'员工姓名'||r_job.ENAME);

end loop;

end;

SELECT*FROM EMP

--6:用更新游标来为雇员加佣金:(用if实现,创建一个与emp表一摸一样的emp1表,对emp1表进行修改操作),并将更新前后的数据输出出来--https://www.wendangku.net/doc/0619092217.html,/blog/815770

create table emp1 as select*from emp;

declare

cursor

csr_Update

is

select*from emp1 for update OF SAL;

empInfo csr_Update%rowtype;

saleInfo emp1.SAL%TYPE;

begin

FOR empInfo IN csr_Update LOOP

IF empInfo.SAL<1500THEN

saleInfo:=empInfo.SAL*1.2;

elsif empInfo.SAL<2000THEN

saleInfo:=empInfo.SAL*1.5;

elsif empInfo.SAL<3000THEN

saleInfo:=empInfo.SAL*2;

END IF;

UPDATE emp1 SET SAL=saleInfo WHERE CURRENT OF csr_Update;

END LOOP;

END;

--7:编写一个PL/SQL程序块,对名字以‘A’或‘S’开始的所有雇员按他们的基本薪水(sal)的10%给他们加薪(对emp1表进行修改操作) declare

cursor

csr_AddSal

is

select*from emp1 where ENAME LIKE'A%'OR ENAME LIKE'S%'for update OF SAL;

r_AddSal csr_AddSal%rowtype;

saleInfo emp1.SAL%TYPE;

begin

for r_AddSal in csr_AddSal loop

dbms_output.put_line(r_AddSal.ENAME||'原来的工资:'||r_AddSal.SAL);

saleInfo:=r_AddSal.SAL*1.1;

UPDATE emp1 SET SAL=saleInfo WHERE CURRENT OF csr_AddSal;

end loop;

end;

--8:编写一个PL/SQL程序块,对所有的salesman增加佣金(comm)500

declare

cursor

csr_AddComm(p_job nvarchar2)

is

select*from emp1 where JOB=p_job FOR UPDATE OF COMM;

r_AddComm emp1%rowtype;

commInfo https://www.wendangku.net/doc/0619092217.html,m%type;

begin

for r_AddComm in csr_AddComm('SALESMAN') LOOP

commInfo:=r_https://www.wendangku.net/doc/0619092217.html,M+500;

UPDATE EMP1 SET COMM=commInfo where CURRENT OF csr_AddComm;

END LOOP;

END;

--9:编写一个PL/SQL程序块,以提升2个资格最老的职员为MANAGER(工作时间越长,资格越老)

--(提示:可以定义一个变量作为计数器控制游标只提取两条数据;也可以在声明游标的时候把雇员中资格最老的两个人查出来放到游标中。)declare

cursor crs_testComput

is

select*from emp1 order by HIREDATE asc;

--计数器

top_two number:=2;

r_testComput crs_testComput%rowtype;

begin

open crs_testComput;

FETCH crs_testComput INTO r_testComput;

while top_two>0 loop

dbms_output.put_line('员工姓名:'||r_testComput.ENAME||' 工作时间:'||r_testComput.HIREDATE);

--计速器减一

top_two:=top_two-1;

FETCH crs_testComput INTO r_testComput;

end loop;

close crs_testComput;

end;

--10:编写一个PL/SQL程序块,对所有雇员按他们的基本薪水(sal)的20%为他们加薪,

--如果增加的薪水大于300就取消加薪(对emp1表进行修改操作,并将更新前后的数据输出出来)

declare

cursor

crs_UpadateSal

is

select*from emp1 for update of SAL;

r_UpdateSal crs_UpadateSal%rowtype;

salAdd emp1.sal%type;

salInfo emp1.sal%type;

begin

for r_UpdateSal in crs_UpadateSal loop

salAdd:= r_UpdateSal.SAL*0.2;

if salAdd>300then

salInfo:=r_UpdateSal.SAL;

dbms_output.put_line(r_UpdateSal.ENAME||': 加薪失败。'||'薪水维持在:'||r_UpdateSal.SAL);

else

salInfo:=r_UpdateSal.SAL+salAdd;

dbms_output.put_line(r_UpdateSal.ENAME||': 加薪成功.'||'薪水变为:'||salInfo);

end if;

update emp1 set SAL=salInfo where current of crs_UpadateSal;

end loop;

end;

--11:将每位员工工作了多少年零多少月零多少天输出出来

--近似

--CEIL(n)函数:取大于等于数值n的最小整数

--FLOOR(n)函数:取小于等于数值n的最大整数

--truc的用法 https://www.wendangku.net/doc/0619092217.html,/2005/1028/20051028034101.shtml

declare

cursor

crs_WorkDay

is

select ENAME,HIREDATE, trunc(months_between(sysdate, hiredate) /12) AS SPANDYEARS,

trunc(mod(months_between(sysdate, hiredate), 12)) AS months,

trunc(mod(mod(sysdate - hiredate, 365), 12)) as days

from emp1;

r_WorkDay crs_WorkDay%rowtype;

begin

for r_WorkDay in crs_WorkDay loop

dbms_output.put_line(r_WorkDay.ENAME||'已经工作了'||r_WorkDay.SPANDYEARS||'年,零'||r_WorkDay.months||'月,零'||r_WorkDay.days||'天');

end loop;

end;

--12:输入部门编号,按照下列加薪比例执行(用CASE实现,创建一个emp1表,修改emp1表的数据),并将更新前后的数据输出出来

-- deptno raise(%)

-- 10 5%

-- 20 10%

-- 30 15%

-- 40 20%

-- 加薪比例以现有的sal为标准

--CASE expr WHEN comparison_expr THEN return_expr

--[, WHEN comparison_expr THEN return_expr]... [ELSE else_expr] END

declare

cursor

crs_caseTest

is

select*from emp1 for update of SAL;

r_caseTest crs_caseTest%rowtype;

salInfo emp1.sal%type;

begin

for r_caseTest in crs_caseTest loop

case

when r_caseTest.DEPNO=10

THEN salInfo:=r_caseTest.SAL*1.05;

when r_caseTest.DEPNO=20

THEN salInfo:=r_caseTest.SAL*1.1;

when r_caseTest.DEPNO=30

THEN salInfo:=r_caseTest.SAL*1.15;

when r_caseTest.DEPNO=40

THEN salInfo:=r_caseTest.SAL*1.2;

end case;

update emp1 set SAL=salInfo where current of crs_caseTest;

end loop;

end;

--13:对每位员工的薪水进行判断,如果该员工薪水高于其所在部门的平均薪水,则将其薪水减50元,输出更新前后的薪水,员工姓名,所在部门编号。--AVG([distinct|all] expr) over (analytic_clause)

---作用:

--按照analytic_clause中的规则求分组平均值。

--分析函数语法:

--FUNCTION_NAME(,...)

--OVER

--()

--PARTITION子句

--按照表达式分区(就是分组),如果省略了分区子句,则全部的结果集被看作是一个单一的组

select*from emp1

DECLARE

CURSOR

crs_testAvg

IS

select EMPNO,ENAME,JOB,SAL,DEPNO,AVG(SAL) OVER (PARTITION BY DEPNO ) AS DEP_AVG

FROM EMP1 for update of SAL;

r_testAvg crs_testAvg%rowtype;

salInfo emp1.sal%type;

begin

for r_testAvg in crs_testAvg loop

if r_testAvg.SAL>r_testAvg.DEP_AVG then

salInfo:=r_testAvg.SAL-50;

end if;

update emp1 set SAL=salInfo where current of crs_testAvg;

end loop;

end;

oracle游标的使用及属性

oracle游标的使用及属性 oracle游标的使用 游标是从数据表中提取出来的数据,以临时表的形式存放到内存中,在游标中有一个数据指针,在初始状态下指向的是首记录,利用fetch语句可以移动该指针,从而对游标中的数据进行各种操作,然后将操作结果写回到数据库中。 一:定义游标 cursor游标名isselect语句; 示例: setserveroutputon declare tempsalscott.emp.sal%type; cursormycursorisselect *fromscott.empwheresal>tempsal; begin tempsal:=800; openmycursor; end; 二:打开游标 语法结构:open游标名 打开游标分为两步:1将符合条件的记录送入内存2将指针指向第一条记录 三:提取游标数据

语法形式:fetch游标名into变量名1,变量名2,.....;或者 fetch游标名into记录型变量名; 示例: setserveroutputon declare tempsalscott.emp.sal%type; cursormycursorisselect*fromscott.empwheresal>tempsal; cursorrecordmycursor%rowtype; begin tempsal:=800; openmycursor; fetchmycursorintocursorrecord; dbms_output.put_line(to_char(cursorrecord.deptno)); end; 四:关闭游标 close游标名; Oracle游标的属性之一------%isopen %isopen 属性----测试游标是否打开,没打开的情况下使用fetch语句将提示错误。 示例:

Oracle 游标使用全解

-- 声明游标;CURSOR cursor_name IS select_statement --For 循环游标 --(1)定义游标 --(2)定义游标变量 --(3)使用for循环来使用这个游标 declare --类型定义 cursor c_job is select empno,ename,job,sal from emp where job='MANAGER'; --定义一个游标变量v_cinfo c_emp%ROWTYPE ,该类型为游标c_emp中的一行数据类型 c_row c_job%rowtype; begin for c_row in c_job loop dbms_output.put_line(c_row.empno||'-'||c_row.ename||'-'||c_row.job||'-'||c_row.sal); end loop; end; --Fetch游标 --使用的时候必须要明确的打开和关闭 declare --类型定义 cursor c_job is select empno,ename,job,sal from emp where job='MANAGER'; --定义一个游标变量 c_row c_job%rowtype; begin open c_job; loop --提取一行数据到c_row fetch c_job into c_row; --判读是否提取到值,没取到值就退出 --取到值c_job%notfound 是false --取不到值c_job%notfound 是true exit when c_job%notfound; dbms_output.put_line(c_row.empno||'-'||c_row.ename||'-'||c_row.job||'-'||c_row.sal);

Oracle显式游标和隐式游标

Oracle显式游标和隐式游标 SQL是用于访问Oracle数据库的语言,PL/SQL扩展和加强了SQL的功能,它同时引入了更强的程序逻辑, 下面在本文中将对游标的使用进行一下讲解,希望可以和大家共同学习进步。 游标字面理解就是游动的光标。游标是SQL的一个内存工作区,由系统或用户以变量的形式定义。在某些情况下,需要把数据从存放在磁盘的表中调到计算机内存中进行处理,最后将处理结果显示出来或最终写回数据库。这样数据处理的速度才会提高,否则频繁的磁盘数据交换会降低效率。用数据库语言来描述游标就是映射在结果集中一行数据上的位置实体,有了游标,用户就可以访问结果集中的任意一行数据了,将游标放置到某行后,即可对该行数据进行操作,例如提取当前行的数据等。 游标有两种类型:显式游标和隐式游标。游标一旦打开,数据就从数据库中传送到游标变量中,然后应用程序再从游标变量中分解出需要的数据,并进行处理。 当系统使用一个隐式游标时,可以通过隐式游标的属性来了解操作的状态和结果,进而控制程序的流程。隐式游标可以使用名字SQL来访问,但要注意,通过SQL游标名总是只能访问前一个处理操作或单行SELECT操作的游标属性。所以通常在刚刚执行完操作之后,立即使用SQL游标名来访问属性。游标的属性有四种,分别是 SQL %ISOPEN,SQL %FOUND,SQL %NOTFOUND,SQL %ROWCOUNT。 SQL%ISOPEN返回的类型为布尔型,判断游标是否被打开,如果打开%ISOPEN等于true,否则等于false,即执行过程中为真,结束后为假。 SQL%NOTFOUND返回值为布尔型,判断游标所在的行是否有效,如果有效, 则%FOUNDD等于true,否则等于false,即与%FOUND属性返回值相反。 SQL%FOUND返回值的类型为布尔型,值为TRUE代表插入删除更新或单行查询操作成功。 SQL%ROWCOUNT返回值类型为整型,返回当前位置为止游标读取的记录行数,

oracle11g游标及触发器相关知识

oracle11g 游标: 1. 当在PL/SQL中使用SQL语句时,Oracle会为其分配上下文区域,这是一段 私有的内存区域,用于暂时保存SQL语句影响到的数据。游标是指向这段内存区域的指针。 2. Oracle中主要有两种类型的游标: (1) 隐式游标:所有的DML语句和PL/SQL SELECT 语句都有; (2) 显式游标:由开发人员声明和控制。 3. 可以使用的游标属性包括四种:%ROWCOUNT、%FOUND、%NOTFOUND、 %ISOPEN,这四种属性对于显式游标和隐式游标都有用,但是含义和使用方法略有不同。游标在使用属性时,需要以游标名称作为前缀,以表明该属性是哪个游标的,隐式游标没有名称,所以在使用隐式游标时采取了统一的一个名称SQL。 4. 在PL/SQL中的SELECT语句只能且必须取出一行数据,取出多行或者零行都 被认为是异常,所以在对多行数据进行操作时,必须使用显式游标来实现。 5. 使用显式游标的步骤: (1)声明游标:CURSOR cursor_name is select_statement; (2)打开游标:OPEN cursor_name; (3)取游标中的数据:FETCH cursor_name INTO variable1,variable2,...; (4)关闭游标:CLOSE cursor_name; 6.用变量接收游标中的数据 sql> declare v_name emp.ename%TYPE; v_sal emp.sal%TYPE; cursor emp_cursor is select ename,sal from emp where deptno=10; begin open emp_cursor; loop fetch emp_cursor into v_name,v_sal; exit when emp_cursor%NOTFOUND; dbms_output.put_line(v_name || ‘的薪水是’ || v_sal);

Oracle 函数返回游标的方法及应用

Oracle函数返回游标的方法及应用简析 王凤利康俊霞 河北北方学院张家口职业技术学院 【摘要】Oracle函数除了可以返回数值类型和字符类型等常用数据类型的数 据以外,还可以返回游标类型的数据,在某些情况下,返回游标类型的函数为我们 解决一些应用中的难题。本文就是通过一个实例来介绍返回游标函数的创建过程。 【关键字】Oracle,函数,包,游标。 1 问题的提出 在油田信息系统建设过程中,遇到了这样一个问题:输油站泵运行数据表(DHC05)的结构为:时间(SJ)、单位名称(DWMC)、泵号(BH)、泵压(BY1)、电压(DY)、电流(DL)、排量(PL),主键为:时间、单位名称、泵号,每整点对运行泵取一次数据,不存储不运行泵(运行时间为0)的数据。现要输出如下报表: 报表的查询条件为单位名称和日期(yyyymmdd格式字符串)。运行泵号及泵台数根据各单位实际运行情况而定。 2 系统简介 系统采用B/S三层体系结构,数据库采用Oracle9.2版本,WEB服务器采用IIS6.0版本,客户端采用IE6.0及以上版本。 报表采用了统一的制表解释程序进行输出,该解释程序可以从一个单一的Oracle查询语句中提取数据,报表的输出样式为简单的二维表。 3 解决方案 根据目前的系统现状,要想直接利用当前系统输出本报表是不可能的,经过分析认为共有以下几种解决方案: a)修改数据表结构 将原始数据表的结构进行调整,把时间、单位名称作为主键,将同一时刻的各个泵的数据逐个列出作为数据列,大致结构为:时间、单位名称、1号泵泵压、1号泵电压、1号泵电流、1号泵排量、2号泵泵压、2号泵电压、2号泵电流、2号泵排量、…。 本方案违背了数据库设计的基本原则,因各个单位的泵数不相等,只能按最大泵数进行数据库结构设计,当站库继续扩大、泵数继续增加时需要对数据库结构和所有用到该数据表

【黑马程序员】Oracle 游标使用全解

【黑马程序员】Oracle 游标使用全解 有很多同学在使用oracle 数据库的时候对游标这个东西不知道如何处理,感觉使用起来很难,今天我们就讨论一下游标的使用,满满的都是干货,以下代码几乎包含了oracle 游标使用的方方面面,全部通过了测试! -- 声明游标; 1 C URSOR cursor_name IS select_statement --For 循环游标 --(1)定义游标 --(2)定义游标变量 --(3)使用for 循环来使用这个游标 01 02 03 04 05 06 07 08 09 10 11 12 13 14 declare --类型定义 cursor c_job is select empno ,ename ,job ,sal from emp where job ='MANAGER'; --定义一个游标变量v_cinfo c_emp%ROWTYPE ,该类型为游标c_emp 中的一行数据类型 c_row c_job%rowtype; begin for c_row in c_job loop dbms_output.put_line (c_row.empno||'-'||c_row.ename||'-'||c_row.job||'-'||c_row.sal ); end loop; end ; --Fetch 游标 --使用的时候必须要明确的打开和关闭 01 02 03 declare --类型定义 cursor c_job

04 05 06 07 08 09 10 11 12 13 14 15 16 is select empno,ename,job,sal from emp where job='MANAGER'; --定义一个游标变量 c_row c_job%rowtype; begin open c_job; loop --提取一行数据到c_row fetch c_job into c_row; --判读是否提取到值,没取到值就退出 --取到值c_job%notfound 是false --取不到值c_job%notfound 是true exit when c_job%notfound; dbms_output.put_line(c_row.empno||'-'||c_row.ename||'-'||c_row.job||' -'||c_row.sal); end loop; --关闭游标 close c_job; end; --1:任意执行一个update操作,用隐式游标sql的属 性%found,%notfound,%rowcount,%isopen观察update语句的执行情况。 begin update emp set ENAME='ALEARK' WHERE EMPNO=7469; if sql%isopen then dbms_output.put_line('Openging'); else dbms_output.put_line('closing'); end if; if sql%found then dbms_output.put_line('游标指向了有效行');--判断游标是否指向有效行 else dbms_output.put_line('Sorry'); end if; if sql%notfound then dbms_output.put_line('Also Sorry'); else dbms_output.put_line('Haha'); end if;

Oracle存储过程学习_游标CURSOR使用

游标CURSOR的使用学习 游标的类型: 1,隐式游标:在 PL/SQL 程序中执行DML SQL 语句时自动创建隐 式游标,名字固定叫sql。 2,显式游标:显式游标用于处理返回多行的查询。 3,REF 游标:REF 游标用于处理运行时才能确定的动态 SQL 查询 的结果 一、隐式游标 在PL/SQL中使用DML语句时自动创建隐式游标 q隐式游标自动声明、打开和关闭,其名为 SQL q通过检查隐式游标的属性可以获得最近执行的DML 语句的信息q隐式游标的属性有: q%FOUND – SQL 语句影响了一行或多行时为 TRUE q%NOTFOUND – SQL 语句没有影响任何行时为TRUE q%ROWCOUNT – SQL 语句影响的行数 q%ISOPEN - 游标是否打开,始终为FALSE begin update student s set s.sage = s.sage + 10; if sql %FOUND then dbms_output.put_line('这次更新了' || sql% rowcount); else dbms_output.put_line('一行也没有更新'); end if; end; 在select中有两个中比较常见的异常: 1. NO_DATA_FOUND 2. TOO_MANY_ROWS declare sname1 student.sname%TYPE; begin

select sname into sname1 from student; if sql%found then dbms_output.put_line(sql%rowcount); else dbms_output.put_line('没有找到数据'); end if; exception when too_many_rows then dbms_output.put_line('查找的行记录多于1行'); when no_data_found then dbms_output.put_line('未找到匹配的行'); end; 显式游标: sqlserver与oracle的不同之处在于:最后sqlserver会deallocate 丢弃游标,而oracle只有前面四步:声明游标、打开游标、使用游标读取记录、关闭

Oracle数据库游标在包中的使用

--创建学员信息表 create table stuInfo ( stuId varchar2(15) not null, --学员Id,主键 stuName varchar2(10) not null, --学员姓名 stuNo varchar2(10) not null, --学号,外键应用stuMarks的stuNo stuAge int not null, --年龄 stuAddress varchar2(100) default('中国') not null,--家庭住址 stuEmail varchar2(100) not null --电子邮箱 ); alter table stuInfo add constraint PK_stuId primary key(stuId); alter table stuInfo add constraint CK_stuAge check(stuAge between 18 and 40); alter table stuInfo add constraint CK_stuEmail check(stuEmail like '%@%'); --创建序列 create sequence SQ_ID increment by 1 start with 10000; --为学员信息表创建触发器TG_STUID create or replace trigger TG_STUID before insert on stuInfo for each row begin select 'SID'||SQ_ID.Nextval into :new.stuId from dual; end; --向学员信息表中添加数据 insert into stuInfo(stuName,stuNo,stuAge,stuAddress,stuEmail) values ('张飞','s1t0102',30,'三国',''); insert into stuInfo(stuName,stuNo,stuAge,stuAddress,stuEmail) values ('关羽','s1t0830',35,'蜀国',''); insert into stuInfo(stuName,stuNo,stuAge,stuAddress,stuEmail) values ('马超','s2t1326',25,'三国',''); insert into stuInfo(stuName,stuNo,stuAge,stuAddress,stuEmail) values ('刘备','s3t0403',40,'蜀国',''); insert into stuInfo(stuName,stuNo,stuAge,stuAddress,stuEmail) values ('诸葛亮','s2t1521',21,'蜀国',''); insert into stuInfo(stuName,stuNo,stuAge,stuAddress,stuEmail) values ('刘翔','s3t0706',29,'上海',''); insert into stuInfo(stuName,stuNo,stuAge,stuAddress,stuEmail) values ('曹操','s3t0915',34,'魏国',''); insert into stuInfo(stuName,stuNo,stuAge,stuAddress,stuEmail) values ('孙权','s1t1123',32,'东吴',''); insert into stuInfo(stuName,stuNo,stuAge,stuAddress,stuEmail) values ('董卓','s2t0507',35,'三国',''); insert into stuInfo(stuName,stuNo,stuAge,stuAddress,stuEmail) values

Oracle10.2并发条件下更新游标数据的研究

Oracle10.2并发条件下更新游标数据的研究 本文测试在PL/SQL编程中,更新游标数据的2种方式以及并发条件下各种方式的实际表现。2种方式的效率问题不在此文讨论之列! 一、环境准备 数据库:Oracle10.2.0.4 测试工具:PL/SQL Developer9 二、数据准备 我们使用oracle自带的演示用户scott登录数据库,为清楚看到数据变化,执行以下语句: 查询emp表: 结果如图1所示:

图1 Sal字段已经全部更新为1000 三、创建存储过程ps_cursor_for_update

四、测试ps_cursor_for_update PL/SQL Developer工具具有很强大的plsql调试功能,我们使用两个test窗口进行模拟并发执行的情况 在编辑存储过程的界面,在打开游标的代码行加入一个断点: 图2 在存储过程ps_cursor_for_update上点击右键,打开两个test窗口: 窗口1中,输入参数填写2000 窗口2中,输入参数填写3000,如图3、4所示: 图3 图4 两个窗口分别点击start bugger按钮,开始调试,并点击run按钮,分别运行到打开游标的一行,并在窗口2中进行单步调试,运行到如图5所示位置:

图5 此时窗口1中,开始单步调试,发现状态栏处于运行中(图7),但调试光标始终停在断点行(图6) 图6 图7 说明游标打开的数据已经被窗口2的进程锁定,所以窗口1的进程无法打开数据 下面把窗口2的断点去掉,并点击run按钮使此过程执行完毕,可以发现,此时窗口1中,代码已经执行到了原断点位置的下一行: 图8 结论:窗口2执行了commit语句,PL/SQL过程结束,并解锁操作的数据,使窗口1的过程得以打开游标。 查询emp表的数据:

Oracle 数据库中 游标实验报告

Oracle 数据库实验报告 系别:******* 班级:******* 姓名:******* 学号:******* 指导老师:****

一.实验名称 用带参数游标的FOR循环依此输出每一个部门名称,在部门名称的下面输出该部门的员工姓名和工资,按工资的升序排列。二.实验目的 通过本次实验,逐渐熟悉oracle数据库的应用及输出的格式,更加深刻的了解其输出的语法,变量的定义及赋值和操作环境以及循环结构,异常的捕获,定义,处理,Oracle数据库中表的创建,插入,及表中所需数据的提取,掌握游标的定义,使用。三.实验步骤 开始——运行输入cmd,出来oracle运行界面,代码如下: DECLARE --变量,游标的声明; CURSOR dept_cursor IS SELECT Dname,Deptno FROM DEPT; --游标的定义; CURSOR emp_cursor(v_dept CHAR) IS SELECT Ename,Salary FROM EMP WHERE deptno=v_dept ORDER BY Salary;--按工资升序排序格式输出; BEGIN FOR dept_record IN dept_cursor LOOP --for循环,查询的结果单独的输出; DBMS_OUTPUT.PUT_LINE('部门名称为:

'||dept_record.Dname||chr(10)||'部门编号:'||dept_record.Deptno); --输出语句; FOR emp_record IN emp_cursor(dept_record.Deptno) LOOP DBMS_OUTPUT.PUT_LINE('员工姓名为:'||emp_record.Ename||'员工工资为:'||emp_record.Salary); END LOOP; END LOOP; END; / 四.实验结果

Oracle数据库游标使用大全

Oracle数据库游标使用大全(1) SQL是用于访问ORACLE数据库的语言,PL/SQL扩展和加强了SQL的功能,它同时引入了更强的程序逻辑。PL/SQL支持DML命令和SQL的事务控制语句。本文我们将讨论各种用于访问ORACLE数据库的DDL和TCL 语句。 SQL是用于访问ORACLE数据库的语言,PL/SQL扩展和加强了SQL的功能,它同时引入了更强的程序逻辑。PL/SQL支持DML命令和SQL的事务控制语句。DDL在PL/SQL中不被支持,这就意味作在PL/SQL程序块中不能创建表或其他任何对象。较好的PL/SQL程序设计是在PL/SQL块中使用象DBMS_SQL这样的内建包或执行EXECUTE IMMEDIATE命令建立动态SQL来执行DDL命令,PL/SQL编译器保证对象引用以及用户的权限。下面我们将讨论各种用于访问ORACLE数据库的DDL和TCL语句。 查询 SELECT语句用于从数据库中查询数据,当在PL/SQL中使用SELECT语句时,要与INTO子句一起使用,查询的返回值被赋予INTO子句中的变量,变量的声明是在DELCARE中。SELECT INTO语法如下: PL/SQL中SELECT语句只返回一行数据。如果超过一行数据,那么就要使用显式游标(对游标的讨论我们将在后面进行),INTO子句中要有与SELECT子句中相同列数量的变量。INTO子句中也可以是记录变量。TYPE属性 在PL/SQL中可以将变量和常量声明为内建或用户定义的数据类型,以引用一个列名,同时继承他的数据类型和大小。这种动态赋值方法是非常有用的,比如变量引用的列的数据类型和大小改变了,如果使用了%TYPE,那么用户就不必修改代码,否则就必须修改代码。 例: 不但列名可以使用%TYPE,而且变量、游标、记录,或声明的常量都可以使用%TYPE。这对于定义相同数据类型的变量非常有用。

oracle for循环 用在 游标中

oracle for循环用在游标中 游标FOR循环 在大多数时候我们在设计程序的时候都遵循下面的步骤: 1、打开游标 2、开始循环 3、从游标中取值 4、检查那一行被返回 5、处理 6、关闭循环 7、关闭游标 可以简单的把这一类代码称为游标用于循环。但还有一种循环与这种类型不相同,这就是FOR循环,用于FOR循环的游标按照正常的声明方式声明,它的优点在于不需要显式的打开、关闭、取数据,测试数据的存在、定义存放数据的变量等等。游标FOR 循环的语法如下: --游标for循环(给所有的部门经理减薪1000)DECLARE CURSOR emp_cur IS SELECT empno,ename,sal FROM emp WHERE job='MANAGER' FOR UPDATE;

FOR emp_row IN emp_cur LOOP UPDATE emp SET sal=sal-1000 WHERE CURRENT OF emp_cur; END LOOP; COMMIT; END; --我们可以看到游标FOR循环确实很好的简化了游标的开发,我们不在需要open、fetch和close语句,不在需要用%FOUND属性检测是否到最后一条记录,这一切Oracle 隐式的帮我们完成了。 --给经理加薪5000,其他加薪1000 DECLARE CURSOR emp_cur IS SELECT * FROM emp FOR UPDATE; BEGIN FOR emp_row IN emp_cur LOOP IF emp_row.job='MANAGER' THEN UPDATE emp SET sal=sal+5000 WHERE CURRENT OF emp_cur;

Oracle 隐式游标

Oracle 隐式游标 在执行一个SQL语句时,Oracle会自动创建一个隐式游标。这个游标是内存中处理该语句的工作区域,在其中存储了执行SQL语句的结果。通过游标的属性可获知SQL语句的执行结果,以及游标的状态信息。 游标的主要属性如下: ●%FOUND 布尔型属性,如果SQL语句至少影响到一行数据,则该属性为TRUE, 否则为FALSE。 ●%NOTFOUND 布尔型属性,与%FOUND相反。 ●%ISOPEN 布尔型属性,当游标已经打开时返回TRUE,游标关闭时则为FALSE。 ●%ROWCOUNT 数字型属性,返回受SQL语句影响的行数。 如果执行了一个SELECT语句,则可以通过SQL%ROWCOUNT来检查受影响的行数,还可以通过SQL%FOUND属性值是否为TRUE,以检查SQL语句是否检索到了数据。当使用隐式游标的属性时,需要在属性前加上SQL。因为Oracle在创建隐式游标时,默认的游标名为SQL。 现在来看一个更新SCOTT模式中EMP表的示例。在该示例中,将更新一名员工的信息,并通过游标的属性查看被更新的记录数。 SQL> set serveroutput on SQL> begin 2 update emp 3 set sal=1200 4 where empno='7369'; 5 if sql%notfound then 6 dbms_output.put_line('未更新任何记录'); 7 else 8 dbms_output.put_line('更新' || sql%rowcount || '条记录'); 9 end if; 10 end; 11 / 更新1条记录 PL/SQL 过程已成功完成。 由于游标的属性信息总是反映最新的SQL语句处理结果,因此当在一个程序块中出现多个SQL语句时,需要及查检查属性值。例如,在下面的示例中,将添加一个SELECT语句查看两个SQL语句对游标的影响。 SQL> set serveroutput on SQL> declare 2 employee_row emp%rowtype; 3 begin 4 update emp 5 set sal=sal+200 6 where job='CLERK';

游标和异常处理 oracle

游标和异常处理 游标的概念 游标是SQL的一个内存工作区,由系统或用户以变量的形式定义。 游标的作用就是用于临时存储从数据库中提取的数据块。 在某些情况下,需要把数据从存放在磁盘的表中调到计算机内存中进行处理,最后将处理结果显示出来或最终写回数据库。这样数据处理的速度才会提高,否则频繁的磁盘数据交换会降低效率。 游标有两种类型:显式游标和隐式游标。 在前述程序中用到的SELECT...INTO...查询语句,一次只能从数据库中提取一行数据,对于这种形式的查询和DML操作,系统都会使用一个隐式游标。但是如果要提取多行数据,就要由程序员定义一个显式游标,并通过与游标有关的语句进行处理。 显式游标对应一个返回结果为多行多列的SELECT语句。 游标一旦打开,数据就从数据库中传送到游标变量中,然后应用程序再从游标变量中分解出需要的数据,并进行处理。

隐式游标 如前所述,DML操作和单行SELECT语句会使用隐式游标,它们是: * 插入操作:INSERT。 * 更新操作:UPDATE。 * 删除操作:DELETE。 * 单行查询操作:SELECT ... INTO ...。 当系统使用一个隐式游标时,可以通过隐式游标的属性来了解操作的状态和结果,进而控制程序的流程。隐式游标可以使用名字SQL来访问,但要注意,通过SQL游标名总是只能访问前一个DML操作或单行SELECT操作的游标属性。所以通常在刚刚执行完操作之后,立即使用SQL游标名来访问属性。游标的属性有四种,如下表所示。 范例:使用隐式游标的属性,判断对雇员工资的修改是否成功。

说明:本例中,通过SQL%FOUND属性判断修改是否成功,并给出相应信息。 显式游标 游标的定义和操作 游标的使用分成以下4个步骤。 1.声明游标 在DECLEAR部分按以下格式声明游标:

Oracle 游标FOR循环

Oracle 游标FOR 循环 从上面的示例中可以发现,游标通常是与循环联合使用。实际上,PL/SQL 还提供了一种将两者综合在一起的语句,即游标FOR 循环语句。游标FOR 循环是显式游标的一种快捷使用方式,它使用FOR 循环依次读取结果集中的数据。当FOR 循环开始时,游标会自动打开(不需要使用OPEN 方法),每循环一次系统自动读取游标当前行的数据(不需要使用FETCH ),当退出FOR 循环时,游标被自动关闭(不需要使用CLOSE )。 FOR 循环的语法如下: for cursor_record in cursor_name loop statements; end loop; 这个FOR 循环将不断地将行读入变量CURSOR_RECORD 中,在循环中也可以存取CURSOR_RECORD 中的字段。 例如,下面的示例使用游标FOR 循环实现查询EMP 表中的数据。 SQL> set serveroutput on SQL> declare 2 cursor emp_cursor is 3 select * from emp 4 where deptno=10; 5 begin 6 for r in emp_cursor loop 7 dbms_output.put(r.empno || ' '); 8 dbms_output.put(r.ename || ' '); 9 dbms_output.put(r.job || ' '); 10 dbms_output.put_line(r.sal); 11 end loop; 12 end; 13 / 7782 CLARK MANAGER 2450 7839 KING PRESIDENT 5000 7934 MILLER CLERK 1300 PL/SQL 过程已成功完成。 注 意 在使用游标FOR 循环时,一定不能使用OPEN 语句、FETCH 语句和CLOSE 语句,否则将产生错误。

Oracle数据库游标

Oracle数据库游标 SQL是用于访问ORACLE数据库的语言,PL/SQL扩展和加强了SQL的功能,它同时引入了更强的程序逻辑。PL/SQL支持DML命令和SQL的事务控制语句。DDL在PL/SQL 中不被支持,这就意味作在PL/SQL程序块中不能创建表或其他任何对象。较好的PL/SQL 程序设计是在PL/SQL块中使用象DBMS_SQL这样的内建包或执行EXECUTE IMMEDIATE命令建立动态SQL来执行DDL命令,PL/SQL编译器保证对象引用以及用户的权限。 下面我们将讨论各种用于访问ORACLE数据库的DDL和TCL语句。 查询 SELECT语句用于从数据库中查询数据,当在PL/SQL中使用SELECT语句时,要与INTO子句一起使用,查询的返回值被赋予INTO子句中的变量,变量的声明是在DELCARE 中。SELECT INTO语法如下: PL/SQL中SELECT语句只返回一行数据。如果超过一行数据,那么就要使用显式游标(对游标的讨论我们将在后面进行),INTO子句中要有与SELECT子句中相同列数量的变量。INTO子句中也可以是记录变量。 %TYPE属性 在PL/SQL中可以将变量和常量声明为内建或用户定义的数据类型,以引用一个列名,同时继承他的数据类型和大小。这种动态赋值方法是非常有用的,比如变量引用的列的数据类型和大小改变了,如果使用了%TYPE,那么用户就不必修改代码,否则就必须修改代码。 例: 不但列名可以使用%TYPE,而且变量、游标、记录,或声明的常量都可以使用%TYPE。这对于定义相同数据类型的变量非常有用。

其他DML语句 其它操作数据的DML语句是:INSERT、UPDATE、DELETE和LOCK TABLE,这些语句在PL/SQL中的语法与在SQL中的语法相同。我们在前面已经讨论过DML语句的使用这里就不再重复了。在DML语句中可以使用任何在DECLARE部分声明的变量,如果是嵌套块,那么要注意变量的作用范围。 例: CREATE OR REPLACE OCEDURE FIRE_EMPLOYEE (pempno in number) AS v_ename EMP.ENAME%TYPE; BEGIN SELECT ename INTO v_ename FROM emp WHERE empno=p_empno; INSERT INTO FORMER_EMP(EMPNO,ENAME) VALUES (p_empno,v_ename); DELETE FROM emp WHERE empno=p_empno; UPDATE former_emp SET date_deleted=SYSDATE WHERE empno=p_empno; EXCEPTION WHEN NO_DATA_FOUND THEN DBMS_OUTPUT.PUT_LINE('Employee Number Not Found!'); END

oracle存储过程返回多个游标实例 - 浪迹天涯 - BlogJava

oracle存储过程返回多个游标实例- 浪迹天涯- BlogJava oracle 存储过程返回多个游标实例 定义两个包(package) CREATE OR REPLACE PACKAGE pro_package_test_001 AS TYPE Test_CURSOR01 IS REF CURSOR; end pro_package_test_001; CREATE OR REPLACE PACKAGE pro_package_test_002 AS TYPE Test_CURSOR02 IS REF CURSOR; end pro_package_test_002; 定义存储过程 CREATE OR REPLACE PROCEDURE pro_query_001 ( --参数IN表示输入参数,OUT表示输入参数,类型可以使用任意Oracle中的合

法类型。 in_lx IN Varchar2, p_cus_01 OUT pro_package_test_001.Test_CURSOR01, p_cus_02 OUT pro_package_test_002.Test_CURSOR02 ) AS --定义变量 vs_lx VARCHAR2(1); --变量 vs_test1_id VARCHAR2(100); --变量 vs_test1_mc VARCHAR2(100); --变量 vs_test2_id VARCHAR2(100); --变量 vs_test2_mc VARCHAR2(100); --变量 --default_c SYS_REFCURSOR; BEGIN --用输入参数给变量赋初值。 vs_lx:= in_lx; --插入test1表。 OPEN p_cus_01 FOR Select a.id As id1, a.mc As mc1, b.id As id2, b.mc As mc2

oracle 动态游标

ORACLE上机练习 理论部分: 1.动态游标的使用方法 前面所讲都是在变量声明部分定义的游标,它是静态的。不能在程序运行过程中修改。通过采用动态游标,可以在程序运行阶段,随时生成一个查询语句作为游标。 使用动态游标步骤: 定义游标类型: TYPE 游标类型名 REF CURSOR; 声明游标变量: 游标变量名游标类型名; 生成查询语句作为游标: OPEN 游标变量名 FOR 查询语句字符串; 【例】利用游标显示每个部门的工资总和和每个职位的平均工资。 提示:动态生成两个游标 declare bm number; zw varchar2(10); tt number; str varchar2(50); type cur_type is ref cursor; --定义游标类型 cur cur_type; --定义游标变量 begin str:= 'select deptno,sum(sal) from emp group by deptno'; --查询字符串 open cur for str; dbms_output.put_line('每个部门的工资总和:'); u while cur%found loop dbms_output.put_line(bm||’‘||tt); fetch cur into bm,tt; end loop; str:= 'select job,avg(sal) from emp group by job’; --查询字符串 open cur for str; dbms_output.put_line('每个职位的工资总和:'); fetch cur into zw,tt; while cur%found loop dbms_output.put_line(zw||’‘||tt); fetch cur into zw,tt; end loop; end;

Oracle数据库开发之游标基础实战视频课程

江西省南昌市2015-2016学年度第一学期期末试卷 (江西师大附中使用)高三理科数学分析 一、整体解读 试卷紧扣教材和考试说明,从考生熟悉的基础知识入手,多角度、多层次地考查了学生的数学理性思维能力及对数学本质的理解能力,立足基础,先易后难,难易适中,强调应用,不偏不怪,达到了“考基础、考能力、考素质”的目标。试卷所涉及的知识内容都在考试大纲的范围内,几乎覆盖了高中所学知识的全部重要内容,体现了“重点知识重点考查”的原则。 1.回归教材,注重基础 试卷遵循了考查基础知识为主体的原则,尤其是考试说明中的大部分知识点均有涉及,其中应用题与抗战胜利70周年为背景,把爱国主义教育渗透到试题当中,使学生感受到了数学的育才价值,所有这些题目的设计都回归教材和中学教学实际,操作性强。 2.适当设置题目难度与区分度 选择题第12题和填空题第16题以及解答题的第21题,都是综合性问题,难度较大,学生不仅要有较强的分析问题和解决问题的能力,以及扎实深厚的数学基本功,而且还要掌握必须的数学思想与方法,否则在有限的时间内,很难完成。 3.布局合理,考查全面,着重数学方法和数学思想的考察 在选择题,填空题,解答题和三选一问题中,试卷均对高中数学中的重点内容进行了反复考查。包括函数,三角函数,数列、立体几何、概率统计、解析几何、导数等几大版块问题。这些问题都是以知识为载体,立意于能力,让数学思想方法和数学思维方式贯穿于整个试题的解答过程之中。 二、亮点试题分析 1.【试卷原题】11.已知,,A B C 是单位圆上互不相同的三点,且满足AB AC → → =,则A BA C →→ ?的最小值为( ) A .1 4- B .12- C .34- D .1-

ORACLE中一般游标和ref游标

ORACLE中一般游标和ref游标 游标标是构建在PL/SQL中,用来查询数据,获取记录集的指针。它让开发者一次访问结果集中一行记录。在oracle中提供了两种游标: 1 静态游标 2 ref游标 静态游标:静态游标是在编译的时候就被确定。然后把结果集复制到内存中静态游标又分为两种:隐式游标和显示游标。 ref游标:ref游标是在运行的时候加载结果集 先来看看静态游标中的隐式游标在PL/SQL中为所有的SQL数据操纵语句(包括返回一行的select)隐式声明游标称为隐式游标。主要原因是用户不能直接命名和控制此类游标。当用户在PL/SQL 中使用数据操纵语句(DML)时,oracle 预先定义一个名称为SQL的隐式游标,通过检查隐式游标的属性获取与最近执行的SQL语句相关信息。在执行DML语句之后,隐式游标属性返回信息。隐式游标属性包括:%found %notfound %rowcount %isopen 1 %found只有DML语句影响一行或多行时,%found属性才返回true 返回值的类型为布尔型,值为TRUE代表插入删除更新或单行查询操作成功。

declare num number; begin update emp set empno=123 where empno=111; if sql%found then dbms_output.put_line('存在记录'); else dbms_output.put_line('不存在记录'); end if; end; 2 %notfound %notfound属性作用正好跟%found属性相反。如果DML语句没有影响任何行数,则%notfound属性返回true. 返回值为布尔型,判断游标所在的行是否有效,如果有效,则%FOUNDD等于true,否则等于false,即与%FOUND属性返回值相反。 declare begin delete from emp where empno=111; if sql%notfound then dbms_output.put_line('删除失败'); end if; end; 3 %rowcount %rowcount属性返回DML语句影响的行数。如果DML语句没有影响任何行数,则%rowcount属性将返回0。 返回值类型为整型,返回当前位置为止游标读取的记录行数,即成功执行的数据行数 declare num number; begin update emp set empno=123 where empno=111; if sql%rowcount=0 then dbms_output.put_line('不存在记录'); else dbms_output.put_line('存在记录');

相关文档
相关文档 最新文档