|
? 说明:可以看到该循环形式非常简单,隐含了记录变量的定义、游标的打开、提取和关闭过程。Emp_record为隐含定义的记录变量,循环的执行次数与游标取得的数据的行数相一致。? 【训练2】? 另一种形式的游标循环。?
Sql代码?
- SET?SERVEROUTPUT?ON? ??
- BEGIN??
- ?FOR?re?IN?(SELECT?ename?FROM?EMP)??LOOP ??
- ??DBMS_OUTPUT.PUT_LINE(re.ename) ??
- ?END?LOOP; ??
- END;??
执行结果为:?
Sql代码?
- SMITH ??
- ALLEN ??
- WARD ??
- JONES??
??? 说明:该种形式更为简单,省略了游标的定义,游标的SELECT查询语句在循环中直接出现。? 显式游标属性? 虽然可以使用前面的形式获得游标数据,但是在游标定义以后使用它的一些属性来进行结构控制是一种更为灵活的方法。显式游标的属性如下所示。?
Sql代码?
- 游标的属性???返回值类型???意????义 ??
- %ROWCOUNT???整型??获得FETCH语句返回的数据行数 ??
- %FOUND??布尔型?最近的FETCH语句返回一行数据则为真,否则为假 ??
- %NOTFOUND???布尔型?与%FOUND属性返回值相反 ??
- %ISOPEN?布尔型?游标已经打开时值为真,否则为假??
可按照以下形式取得游标的属性:? 游标名%属性? 要判断游标emp_cursor是否处于打开状态,可以使用属性emp_cursor%ISOPEN。如果游标已经打开,则返回值为“真”,否则为“假”。具体可参照以下的训练。? 【训练1】? 使用游标的属性练习。?
Sql代码?
- SET?SERVEROUTPUT?ON??
- DECLARE??
- ??V_ename?VARCHAR2(10); ??
- ??CURSOR?emp_cursor?IS? ??
- ??SELECT?ename?FROM?emp; ??
- BEGIN??
- ?OPEN?emp_cursor; ??
- ?IF?emp_cursor%ISOPEN?THEN??
- LOOP ??
- ???FETCH?emp_cursor?INTO?v_ename; ??
- ???EXIT?WHEN?emp_cursor%NOTFOUND; ??
- ???DBMS_OUTPUT.PUT_LINE(to_char(emp_cursor%ROWCOUNT)||‘-‘||v_ename); ??
- ??END?LOOP; ??
- ?ELSE??
- ??DBMS_OUTPUT.PUT_LINE(‘用户信息:游标没有打开!‘); ??
- ?END?IF; ??
- ?CLOSE??emp_cursor; ??
- END;??
执行结果为:?
Sql代码?
- 1-SMITH ??
- 2-ALLEN ??
- 3-WARD ??
- ?PL/SQL?过程已成功完成。??
? ? 说明:本例使用emp_cursor%ISOPEN判断游标是否打开;使用emp_cursor%ROWCOUNT获得到目前为止FETCH语句返回的数据行数并输出;使用循环来获取数据,在循环体中使用FETCH语句;使用emp_cursor%NOTFOUND判断FETCH语句是否成功执行,当FETCH语句失败时说明数据已经取完,退出循环。? 【练习1】去掉OPEN emp_cursor;语句,重新执行以上程序。? 游标参数的传递? ?【训练1】? 带参数的游标。?
Sql代码?
- SET?SERVEROUTPUT?ON??
- ????????DECLARE??
- ????????????V_empno?NUMBER(5); ??
- ????????????V_ename?VARCHAR2(10); ??
- ????????????CURSOR??emp_cursor(p_deptno?NUMBER,?????p_job?VARCHAR2)?IS??
- ????????????SELECT??empno,?ename?FROM?emp ??
- ????????????WHERE???deptno?=?p_deptno?AND?job?=?p_job; ??
- BEGIN??
- ?????OPEN?emp_cursor(10,?‘CLERK‘); ??
- ????LOOP ??
- ?????FETCH?emp_cursor?INTO?v_empno,v_ename; ??
- ?????EXIT?WHEN?emp_cursor%NOTFOUND; ??
- ?????DBMS_OUTPUT.PUT_LINE(v_empno||‘,‘||v_ename); ??
- ??????END?LOOP; ??
- ????END;??
执行结果为:?
Sql代码?
- 7934,MILLER ??
- ????????PL/SQL?过程已成功完成。??
说明:游标emp_cursor定义了两个参数:p_deptno代表部门编号,p_job代表职务。语句OPEN emp_cursor(10,‘CLERK‘)传递了两个参数值给游标,即部门为10、职务为CLERK,所以游标查询的内容是部门10的职务为CLERK的雇员。循环部分用于显示查询的内容。? 【练习1】修改Open语句的参数:部门号为20、职务为ANALYST,并重新执行。? 也可以通过变量向游标传递参数,但变量需要先于游标定义,并在游标打开之前赋值。对以上例子重新改动如下:? ? 【训练2】? 通过变量传递参数给游标。?
Sql代码?
- SET?SERVEROUTPUT?ON??
- ????????DECLARE??
- ????????v_empno?NUMBER(5); ??
- ????????v_ename?VARCHAR2(10); ??
- ????????v_deptno?NUMBER(5); ??
- v_job?VARCHAR2(10); ??
- ?????????CURSOR?emp_cursor?IS??
- ????????????SELECT?empno,?ename?FROM?emp ??
- ????????????WHERE???deptno?=?v_deptno?AND?job?=?v_job; ??
- ????????BEGIN??
- ?????????v_deptno:=10; ??
- ?????????v_job:=‘CLERK‘; ??
- ?????????OPEN?emp_cursor; ??
- ????????LOOP ??
- ?????????FETCH?emp_cursor?INTO?v_empno,v_ename; ??
- ???????????EXIT?WHEN?emp_cursor%NOTFOUND; ??
- DBMS_OUTPUT.PUT_LINE(v_empno||‘,‘||v_ename); ??
- ?????????END?LOOP; ??
- ????????END;??
执行结果为:?
Sql代码?
- 7934,MILLER ??
- ????????PL/SQL?过程已成功完成。??
说明:该程序与前一程序实现相同的功能。? 动态SELECT语句和动态游标的用法? Oracle支持动态SELECT语句和动态游标,动态的方法大大扩展了程序设计的能力。? 对于查询结果为一行的SELECT语句,可以用动态生成查询语句字符串的方法,在程序执行阶段临时地生成并执行,语法是:? execute immediate 查询语句字符串 into 变量1[,变量2...];? 以下是一个动态生成SELECT语句的例子。? 【训练1】? 动态SELECT查询。?
Sql代码?
- SET?SERVEROUTPUT?ON? ??
- ????????DECLARE? ??
- ????????str?varchar2(100); ??
- ????????v_ename?varchar2(10); ??
- ????????begin??
- ????????str:=‘select?ename?from?scott.emp?where?empno=7788‘; ??
- ????????execute?immediate?str?into?v_ename;? ??
- ????????dbms_output.put_line(v_ename); ??
- ????????END;???
执行结果为:?
Sql代码?
- SCOTT ??
- ????????PL/SQL?过程已成功完成。??
说明:SELECT...INTO...语句存放在STR字符串中,通过EXECUTE语句执行。? 在变量声明部分定义的游标是静态的,不能在程序运行过程中修改。虽然可以通过参数传递来取得不同的数据,但还是有很大的局限性。通过采用动态游标,可以在程序运行阶段随时生成一个查询语句作为游标。要使用动态游标需要先定义一个游标类型,然后声明一个游标变量,游标对应的查询语句可以在程序的执行过程中动态地说明。? 定义游标类型的语句如下:? TYPE 游标类型名 REF CURSOR;? 声明游标变量的语句如下:? 游标变量名 游标类型名;? 在可执行部分可以如下形式打开一个动态游标:? OPEN 游标变量名 FOR 查询语句字符串;? 【训练2】? 按名字中包含的字母顺序分组显示雇员信息。? 输入并运行以下程序:?
Sql代码?
- declare? ??
- ?type?cur_type?is?ref?cursor; ??
- ?cur?cur_type; ??
- ?rec?scott.emp%rowtype; ??
- ?str?varchar2(50); ??
- ?letter?char:=?‘A‘; ??
- begin??
- ????????loop???????? ??
- ?????????str:=?‘select?ename?from?emp?where?ename?like?‘‘%‘||letter||‘%‘‘‘; ??
- ?????????open?cur?for?str; ??
- ?????????dbms_output.put_line(‘包含字母‘||letter||‘的名字:‘); ??
- ??????????loop ??
- ?????????fetch?cur?into?rec.ename; ??
- ?????????exit?when?cur%notfound; ??
- ????????dbms_output.put_line(rec.ename); ??
- end?loop; ??
- ??exit?when?letter=‘Z‘; ??
- ??letter:=chr(ascii(letter)+1); ??
- ?end?loop; ??
- end;??
运行结果为:?
Sql代码?
- 包含字母A的名字: ??
- ALLEN ??
- WARD ??
- MARTIN ??
- BLAKE ??
- CLARK ??
- ADAMS ??
- JAMES ??
- 包含字母B的名字: ??
- BLAKE ??
- 包含字母C的名字: ??
- CLARK ??
- SCOTT??
(编辑:安卓应用网_ASP源码网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|