1 ---PLSQL 调试授权 2 GRANT debug any procedure, debug connect session TO scott; 3 --定义变量 4 declare 5 part_number number(6); --SQL类型 6 part_name varchar2(20); --SQL类型 7 in_stock boolean; --plsql类型 8 part_price pls_integer; --plsql类型 9 part_description varchar2(50); 10 hours_worked integer:=40; 11 employee_count integer not null:=0; 12 hire_date date default sysdate; --使用DEFAULT设置初始值 13 begin 14 part_number:=38; 15 part_name:='水管'; 16 in_stock:=True; 17 hours_worked:=50; 18 part_price:=100/part_number; 19 part_description:='镀银软管'; 20 DBMS_OUTPUT.put_line(part_number||CHR(13)||part_name||chr(13)||hire_date||' '||hours_worked); 21 end; 22 23 --使用select into 语句为变量赋值 24 declare 25 v_sal emp.sal%type; 26 v_empno emp.empno%type; 27 v_deptno emp.deptno%type; 28 begin 29 select empno,sal,deptno 30 into v_sal, v_empno, v_deptno 31 from emp 32 where empno =7369; 33 dbms_output.put_line(v_sal ||' '||v_empno ||' '||v_deptno); 34 exception 35 when too_many_rows then 36 dbms_output.put_line('返回了多行数据'); 37 end; 38 39 40 --定义常量 41 declare 42 credit_limit constant real:=5000.00; --指定信用额度 43 begin 44 dbms_output.put_line('信用额度'||credit_limit ); 45 end; 46 47 --if ..elseif 48 declare 49 v_sal number; 50 v_comm number; 51 v_ename varchar2(20) :='SCOTT'; 52 begin 53 select sal,comm into v_sal,v_comm from emp 54 where ename = v_ename; 55 if v_sal+v_comm <3000 then 56 update emp set sal=sal*1.12 where ename =v_ename; 57 elsif v_sal+v_comm>3000 and v_sal+v_comm<4000 then 58 update emp set sal=sal*1.1 where ename =v_ename; 59 elsif v_sal+v_comm>4000 and v_sal+v_comm<5000 then 60 update emp set sal=sal*1.05 where ename =v_ename; 61 end if; 62 exception 63 when no_data_found then 64 dbms_output.put_line('对史密斯调薪的操作失败,错误信息为:'||SQLERRM); 65 end; 66 67 68 69 --case选择器的用例 70 declare 71 grade char(1); 72 begin 73 grade :='0'; 74 case grade 75 when 'A' then 76 dbms_output.put_line('优秀'); 77 when 'B' then 78 dbms_output.put_line('良好'); 79 when 'C' then 80 dbms_output.put_line('好'); 81 when 'D' then 82 dbms_output.put_line('一般'); 83 else 84 dbms_output.put_line('无此等级'); 85 end case; 86 end; 87 88 select mod(100,13) from dual; 89 --1简单循环 90 declare 91 x number:=0; 92 y number:=100; 93 begin 94 loop 95 dbms_output.put_line('循环中变量的值:x='|| to_char(x)); 96 x:=x+1; 97 if x>20 then --如果x的值大于20, 则使用Exit退出循环 98 exit; 99 end if; 100 exit when y mod x>5; --y除以x的余数大于5,则退出循环 101 dbms_output.put_line('结果'|| y mod x); 102 end loop; 103 dbms_output.put_line('循环结束变量的值:x='||to_char(x)); 104 end; 105 106 --2 continue when使用实例 107 declare 108 x number:=0; 109 begin 110 loop 111 dbms_output.put_line('循环计数变量:x='||to_char(x)); 112 x:=x+1; 113 continue when x=4; 114 dbms_output.put_line('循环计数变量,在continue之后'); 115 exit when x=5; 116 dbms_output.put_line('退出本循环变量的值:x='||to_char(x)); 117 end loop; 118 end; 119 120 --简单的数字式For循环使用示例 121 create table books(bookid number(10),bname varchar2(40),price number(4)); 122 alter table books modify bname varchar2(40); 123 begin 124 for i in 1..3 loop 125 insert into books values(1020+i,'矛盾文学第'||to_char(i)||'册',3); 126 dbms_output.put_line('插入了矛盾文学第'||to_char(i)||'册'); 127 end loop; 128 end; 129 select * from books; 130 131 --反向for循环 132 begin 133 for i in reverse 1..5 loop 134 dbms_output.put_line('循环计数器为'||to_char(i)); 135 end loop; 136 end; 137 138 --wile loop循环 139 declare 140 v_count pls_integer:=1; 141 begin 142 while v_count<=10 loop 143 dbms_output.put_line('当前循环计数器的值为:'||v_count); 144 v_count:=v_count+1; 145 end loop; 146 end; 147 148 select round(sqrt(37)) from dual; 149 150 declare 151 p varchar2(30); 152 n pls_integer:=37; 153 begin 154 for j in 2..round(sqrt(n)) loop 155 if n mod j=0 then 156 p:='不是一个素数'; 157 goto print_now; 158 end if; 159 end loop; 160 p:='是一个素数'; 161 <<print_now>> 162 dbms_output.put_line(to_char(n)||p); 163 end; 164 165 1.goto语句不能跳转到嵌套块内部的命名标记位置 166 2.不能在if子句的内部使用goto语句跳转到另一个if,case和loop语句内部 167 的命名标签 168 3.不能从一个exception块中使用goto跳转到块的其他区域 169 4.不能在exception外部使用goto语句跳转到exception内部; 170 171 --null 表示创建一个什么也不做的 172 declare 173 done boolean:=true; 174 begin 175 for i in 1..50 loop 176 if done then 177 goto end_loop; 178 end if; 179 <<end_loop>> 180 null; 181 end loop; 182 end; 183 184 185 --集合 186 --定义关联数组 187 declare 188 --雇佣日期索引集合 189 type hiredate_idxt is table of date index by pls_integer; 190 --部门编号集合 191 type deotno_idsxt is table of dept.deptno%type not null 192 index by pls_integer; 193 --记录类型的索引表, 这个结构允许在PL/SQL程序中创建一个本地副本 194 type emp_idxt is table of emp%rowtype 195 index by natural; 196 type deptname_idxt is table of dept%rowtype 197 index by dept.dname%type; 198 199 type private_collection_tt is table of deptname_idxt 200 index by varchar2(100); 201 begin 202 null; 203 end; 204 --定义与使用关联数组 205 Declare 206 --定义关联数组,元素类型varchar2(12),下标为PLS_INTEGER 207 type idx_table is table of varchar2(12) 208 index by pls_integer; 209 v_emp idx_table; --定义关联数组变量 210 v_idx PLS_INTEGER; 211 begin 212 v_emp (1):='史密斯'; 213 v_emp (20):='克拉克'; 214 v_emp (-10):='杰瑞'; 215 v_idx:=v_emp.first; --获取关联数组中第一个元素的下标 216 while v_idx is not null 217 loop 218 dbms_output.put_line('关联数组'|| v_idx||'所在的值是'||v_emp(v_idx)); 219 v_idx:=v_emp.next(v_idx); 220 end loop; 221 end; 222 223 --使用字符串下标的关联数组 224 declare 225 --定义以varchar2作为索引键的关联数组 226 type idx_empsal_table is table of number(8) 227 index by varchar2(20); 228 v_empsal idx_empsal_table; 229 begin 230 v_empsal('史密斯'):=5000; 231 v_empsal('李维二'):=8000; 232 v_empsal('张大千'):=3000; 233 dbms_output.put_line('工资为:'|| v_empsal('李维二')); 234 end; 235 236 237 嵌套表是对关联数组的扩展, 238 1 可以在方案级别创建,可以直接 存储在数据库表中作为表的一个字段 239 2 需要调用构造函数进行初始化 240 241 --使用嵌套表 242 declare 243 type emp_name_table is table of varchar2 (20); 244 type deptno_table is table of number(2); 245 deptno_info deptno_table; 246 emp_name_info emp_name_table:=emp_name_table('张老三','李斯特'); 247 begin 248 dbms_output.put_line('员工1:'||emp_name_info(1)); 249 dbms_output.put_line('员工2:'||emp_name_info(2)); 250 if deptno_info is null 251 then 252 deptno_info:=deptno_table(); 253 end if; 254 deptno_info.extend(5); --扩充元素的个数 255 for i in 1..5 --循环遍历元素个数 256 loop 257 deptno_info(i):=i*10; 258 end loop; 259 dbms_output.put_line('部门个数:'||deptno_info.count); 260 end; 261 262 263 --定义一个方案级别的嵌套表 264 create or replace type t_deptno_type is table of number; 265 / 266 create or replace procedure print_deptno(nt t_deptno_type) 267 is i number; 268 begin 269 i:=nt.first; --获取第1个元素的下标,如果不存在则返回null 270 if i is null then 271 dbms_output.put_line('嵌套表中未分配任何元素'); 272 else 273 while i is not null loop 274 dbms_output.put('下标.('||i||')的部门编号是:'); 275 dbms_output.put_line(nt(i)); 276 i:=nt.next(i); 277 end loop; 278 end if; 279 dbms_output.put_line('---'); 280 end print_deptno; 281 / 282 declare 283 nt t_deptno_type:=t_deptno_type(); --初始化一个空的嵌套表 284 begin 285 print_deptno(nt); --输出嵌套表的信息 286 nt:=t_deptno_type(90,9,29,58); --重新初始化嵌套表,使之具有4个元素 287 print_deptno(nt); 288 nt.delete(1); --删除嵌套表中下标为1的元素 289 --dbms_output.put_line(nt(1)); --01403异常 290 nt(1):=10; 291 end; 292 293 select * from dept_add_emp 294 --创建嵌套表列 295 create or replace type tbl_emp_name as table of varchar2(20); 296 create table dept_add_emp( 297 deptno number(2) primary key, 298 dname varchar2(14), 299 loc varchar2(13), 300 emp tbl_emp_name --object 301 ) 302 nested table emp store as emps_nt; --嵌套表存储位置 303 304 305 --对包含嵌套表列的表执行DML语句 306 declare 307 emp_list tbl_emp_name 308 :=tbl_emp_name('史密斯','杰克','马丁','斯大林','邓小平'); 309 begin 310 insert into dept_add_emp 311 values (10,'行政部','北京',emp_list); 312 insert into dept_add_emp 313 values(20,'财务部','上海',tbl_emp_name('李林','张杰','蔡文')); 314 --对嵌套表进行更新,然后使用update语句将嵌套表更新回数据库 315 emp_list(1):='张三'; 316 emp_list(2):='李四'; 317 emp_list(3):='王五'; 318 update dept_add_emp set emp=emp_list 319 where deptno=10; 320 --从数据库表中查询出嵌套表的实例 321 select emp into emp_list from dept_add_emp where deptno=10; 322 for v_index in 1..emp_list.count loop 323 dbms_output.put_line(emp_list(v_index)); 324 end loop; 325 dbms_output.put_line('演示如何从其他表中插入嵌套表列的值'); 326 --清除表中的数据 327 delete from dept_add_emp; 328 --使用inert select语句,将插入dept表中所有的记录,使用cast和multiset强转 329 --把emp表中的ename作为嵌套表的元素 330 insert into dept_add_emp 331 select dept.*,cast(multiset 332 (select ename from emp where emp.deptno=dept.deptno) 333 as tbl_emp_name) from dept; 334 select emp into emp_list from dept_add_emp where deptno=10; 335 336 for v_index in 1..emp_list.count loop 337 dbms_output.put_line(emp_list(v_index)); 338 end loop; 339 end; 340 341 select * from dept_add_emp where deptno=20; 342 343 --取消集合嵌套,把它当做一个表来处理 344 select d.deptno,d.dname,emp.* from dept_add_emp d, 345 table(d.emp) emp where d.deptno=10; 346 347 --操作变长数组 348 declare 349 --定义变长数组类型 350 type t_dept_name is varray(10) of varchar2(20); 351 type t_dept_no is varray(8) of number; 352 --声明变长数组类型 353 varray_deptname_tab t_dept_name:=t_dept_name('行政部','管理部'); 354 varray_deptno_tab t_dept_no; 355 begin 356 if varray_deptno_tab is null then 357 varray_deptno_tab:=t_dept_no(10,20,30,null,null,null); 358 end if; 359 varray_deptname_tab.extend(3); --在原有的基础上扩充三个元素 360 dbms_output.put_line('当前varray_deptname_tab个数:'||varray_deptname_tab.count); 361 varray_deptname_tab.trim; --删除一个 362 dbms_output.put_line('当前varray_deptname_tab个数:'||varray_deptname_tab.count); 363 364 varray_deptname_tab.extend; 365 varray_deptname_tab(5):='发展部'; 366 dbms_output.put_line(varray_deptname_tab(5)); 367 --这行代码超过了变长数组最大长度,抛出06533异常 368 --varray_deptno_tab.extend(5) 369 end; 370 371 372 --数据库中的变长数组 373 create or replace type empname_varray_type is varray (10) of varchar2 (20); 374 create table dept_varray( 375 deptno number(2), 376 dname varchar2(20), 377 emplist empname_varray_type 378 ); 379 380 declare 381 emp_list empname_varray_type:= 382 empname_varray_type('诸葛亮','司马懿','郭嘉','庞统','许攸'); 383 begin 384 insert into dept_varray 385 values(20,'军师',emp_list); 386 insert into dept_varray 387 values(30,'武将', 388 empname_varray_type('关羽','张飞','赵云','魏延','黄忠')); 389 --从表中取出变长数组的数据 390 select emplist into emp_list from dept_varray where deptno=20; 391 emp_list(1):='姜维'; 392 update dept_varray 393 set emplist=emp_list 394 where deptno =20; 395 --删除记录同时删除变长数组 396 --delete from dept_varray where deptno=30; 397 end; 398 399 select * from dept_varray; 400 401 402 --布尔类型使用示例 403 declare 404 v_condition boolean; 405 begin 406 v_condition:=true; 407 if v_condition then 408 dbms_output.put_line('值为True'); 409 else 410 dbms_output.put_line('值为false'); 411 end if; 412 end; 413 --子类型定义,数值检查 414 declare 415 type empnamelist is table of varchar2(20); 416 subtype namelist is empnamelist; --定义表类型的子类型 417 type emprec is record( 418 empno number(4), 419 ename varchar(20) 420 ); 421 subtype emprecord is emprec; --定义员工记录子类型 422 subtype numtype is number(1,0); 423 x_value numtype; 424 y_value numtype; 425 begin 426 x_value:=3; 427 y_value:=9; 428 end; 429 --数据类型转换 430 --显示转换示例 431 declare 432 v_startdate date; 433 v_enddate date; 434 v_resultdate number; 435 begin 436 v_startdate :=to_date('2007-10-11','yyyy-mm-dd'); 437 v_enddate:=trunc(sysdate); 438 v_resultdate:=v_enddate-v_startdate; 439 dbms_output.put_line( ' 起始'||v_startdate||'日期: '|| 440 to_char(v_startdate,'yyyy-mm-dd') 441 ||chr(13)||chr(10)||'结束'||v_enddate||'日期: '|| 442 to_char(v_enddate,'yyyy-MM-dd') 443 ||chr(13) 444 ||chr(10) 445 ||' 相差天数: ' 446 || to_char(v_resultdate)); 447 end; 448 449 --隐式转换示例 450 declare 451 v_startdate char(10); 452 v_enddate char(10); 453 v_result number(5); 454 begin 455 select min(hiredate) into v_startdate from emp; 456 select trunc(sysdate) into v_enddate from dual; 457 dbms_output.put_line( ' 起始日期: ' 458 || v_startdate||chr(13)||chr(10) ---chr(10)换行chr(13)回车 459 ||' 结束日期: '||v_enddate ); 460 461 dbms_output.put('chr'||chr(13)); 462 v_startdate:='200'; 463 v_enddate:='400'; 464 v_result:=v_enddate-v_startdate; 465 end; 466 467 468 469 470 --检索case语句 471 declare 472 v_sal number(10,2); 473 v_empno number(10) :=&empno; 474 begin 475 select sal into v_sal from emp 476 where empno=v_empno; 477 case 478 when v_sal between 1000 and 1500 479 then 480 dbms_output.put_line('员工级别:初级职员'); 481 when v_sal between 1500 and 3000 482 then 483 dbms_output.put_line('员工级别:中级管理'); 484 when v_sal between 3000 and 5000 485 then 486 dbms_output.put_line('员工级别:高级管理'); 487 else 488 dbms_output.put_line('不在级别范围之内'); 489 end case; 490 end; 491 492 --case语句后面的值是可选的 True和 False ,默认值为True 493 --使用continue重新开始循环 494 declare 495 x number:=0; 496 begin 497 loop 498 dbms_output.put_line('内部循环值:x+'||to_char(x)); 499 x:=x+1; 500 if x<3 501 then 502 continue; 503 end if; 504 dbms_output.put_line('countiue之后的值:x='|| to_char(x)); 505 exit when x=5; 506 end loop; 507 dbms_output.put_line('循环体结束后的值:x='||to_char(x)); 508 end; 509 510 loop-end-loop循环有一个特色, 无论循环退出条件是否满足 511 先进入循环体,再执行代码,直到遇上exit或exit when子句才 512 判断并退出循环 代码至少有机会被执行一次称为 513 出口值守循环, 见图1 514 while-loop循环在执行体中代码之前先判断一个条件,如果 515 一开始就为假, 那么一次也不执行代码,这种类型的循环称为 516 入口值守循环 517 518 循环的功能特性与使用时机 图2 519 520 --GOTO语句模拟循环语句 521 declare 522 v_counter int:=0; 523 begin 524 <<outer>> 525 DBMS_OUTPUT.put_line('循环计数器:'|| v_counter); 526 if v_counter<5 527 then 528 v_counter:=v_counter+1; 529 goto outer; --向上跳转到标签位置 530 end if; 531 end; 532 533 --NULL 语句 534 declare 535 v_counter INT:=&counter; 536 begin 537 if v_counter>5 538 then 539 dbms_output.put_line('v_counter>5'); 540 else 541 null; 542 end if; 543 end; 544 545 --在异常语句块中使用null 546 declare 547 v_result int:=0; 548 begin 549 v_result :=16/0; 550 dbms_output.put_line('现在时间是:'|| 551 to_char(sysdate,'yyyy-MM-dd HH24:MI:SS')); 552 exception 553 when others 554 then 555 null; 556 end; 557 558 1 有时候希望代码在遇到异常时继续执行, 559 并不处理异常,此时可以使用NUll语句 560 2 使用NULL来创建存根代码,有需要的时候再使用 561 创建一个存根过程,不包含任何程序代码,以便处理程序调试 562 create or replace procedure getleveledbom(bomlevel INT) 563 AS 564 BEGIN 565 NULL; 566 END; 567 568 569 --count方法示例 570 declare 571 type emp_name_table is table of varchar2(20); 572 type deptno_table is table of number(2); 573 deptno_info deptno_table; 574 emp_name_info emp_name_table :=emp_name_table('张三','李斯特'); 575 begin 576 deptno_info:=deptno_table(); 577 deptno_info.extend(5); --扩充5个元素 578 dbms_output.put_line('deptno_info的元素个数为:'||deptno_info.count); 579 dbms_output.put_line('emp_name_info的元素个数为:'||emp_name_info.count); 580 end; 581 --LIMIT方法示例 582 declare 583 type projectlist is varray(50) of varchar2(16); 584 project_list projectlist:=projectlist('网站','ERP','CRM','CMS'); 585 begin 586 dbms_output.put_line('变长数组的上限值为:' || project_list.LIMIT); 587 project_list.extend(8); 588 dbms_output.put_line('变长数组的当前个数为:' || project_list.count); 589 end; 590 591 --first和last示例 592 declare 593 type projectlist is varray (50) of varchar2(16); 594 project_list projectlist :=projectlist('网站','ERP','CRM','CMS'); 595 begin 596 dbms_output.put_line('project_list的第一个元素:'||project_list.first); 597 project_list.extend(8); 598 dbms_output.put_line('project_list的最后一个元素的下标:'||project_list.last); 599 end; 600 601 --prior和next示例 602 declare 603 type idx_table is table of varchar(12) index by pls_integer; 604 v_emp idx_table; 605 i pls_integer; 606 begin 607 v_emp(1) :='史密斯1'; 608 v_emp(20) :='克拉克2'; 609 v_emp(40):='史瑞克3'; 610 v_emp(-10):='杰瑞4'; 611 dbms_output.put_line('第-10个元素的下一个值:'||v_emp(v_emp.next(-10))); 612 dbms_output.put_line('第40个元素的上一个值:'||v_emp(v_emp.PRiOR(40))); 613 i :=v_emp.FIRST; 614 while i is not null 615 loop 616 dbms_output.put_line('v_emp('||i||')='||v_emp(i)); 617 i :=v_emp.next(i); --遍历 618 end loop; 619 end; 620 621 --extend使用示例 622 declare 623 type courselist is table of varchar2(10); 624 courses courselist; 625 i pls_integer; 626 begin 627 courses:= courselist('生物','物理','化学'); 628 courses.delete(3); --删除第三个元素 629 courses.extend; --追加一个空元素 630 courses(4):='英语'; 631 courses.extend(5,1); --把第一个元素复制5份加到末尾 632 i:=courses.First; 633 while i is not null loop 634 dbms_output.put_line('courses('||i||')=' ||courses(i)); 635 i:=courses.next(i); 636 end loop; 637 end; 638 --TRIM示例 639 declare 640 type courselist is table of varchar2(10); 641 courses courselist; 642 i PLS_INTEGER; 643 begin 644 courses := courselist('生物','物理','化学','音乐','数学','地理'); 645 courses.trim(2); --删除集合末尾的两个元素 646 dbms_output.put_line('当前的元素个数:'||courses.count); 647 courses.extend; 648 courses(courses.count):='语文'; 649 courses.trim;--删除最后一个 (语文) 650 i:=courses.first; 651 while i is not null loop 652 dbms_output.put_line('courses('||i||')='||courses(i)); 653 i:=courses.next(i); 654 end loop; 655 end; 656 657 --delete使用示例 658 declare 659 type courselist is table of varchar2(10); 660 courses courselist; 661 i pls_integer; 662 begin 663 courses :=courselist('生物','物理','化学','音乐','数学','地理'); 664 courses.delete(2); --删除第二个元素 665 dbms_output.put_line('当前的元素个数:'||courses.count); 666 courses.extend; 667 dbms_output.put_line('当前的元素个数:'||courses.count); 668 courses(courses.last):='语文'; --为最后一个元素赋值 669 courses.delete(4); 670 i:=courses.FIRST; 671 while i is not null loop 672 dbms_output.put_line('courses('||i||')='||courses(i)); 673 i:=courses.next(i); 674 end loop; 675 end; 676 677 使用批量绑定 678 编写PLSQL代码,PLSQL引擎与SQL引擎频繁交互会大大降低效率 679 --forall语句示例 680 --将集合中所有元素批量地绑定,以便一次性将多个绑定到SQL语句的变量发给SQL引擎 681 一次性发送给SQL引擎. 682 declare 683 type dept_type is varray (20) of number; 684 depts dept_type :=dept_type(10,30,70); 685 begin 686 forall i in depts.first..depts.last 687 delete from emp where deptno=depts(i); 688 for i in 1..depts.count loop 689 dbms_output.put_line('部门编号'||depts(i) 690 ||'的删除操作受影响的行: '||sql%bulk_rowcount(i)); 691 end loop; 692 end; 693 694 -bulk collect关键字可以批量从SQL引擎中批量接受数据到一个集合 695 declare 696 type numtab is table of emp.empno%type; 697 type nametab is table of emp.ename%type; 698 nums numtab; 699 names nametab; 700 begin 701 select empno,ename 702 bulk collect into nums,names from emp; 703 for i in 1..nums.count 704 loop 705 dbms_output.put('num('||i||')='||nums(i)||' '); 706 dbms_output.put_line('names('||i||')='||names(i)); 707 end loop; 708 end; 709 --使用游标的属性isopen 710 declare 711 cursor emp_cursor(p_deptno in number) 712 is select * from emp where deptno =p_deptno; 713 begin 714 if not emp_cursor%isopen then 715 open emp_cursor (20); 716 end if; 717 if emp_cursor%isopen then 718 dbms_output.put_line('游标已经被打开!'); 719 else 720 dbms_output.put_line('游标还没有被打开!'); 721 end if; 722 close emp_cursor; 723 end; 724 725 --%not found 726 declare 727 emp_row emp%rowtype; 728 cursor emp_cursor(p_deptno in number) 729 is select * from emp where deptno=p_deptno; 730 begin 731 open emp_cursor(20);--给一个游标传递参数 732 if emp_cursor%notfound is null 733 then 734 dbms_output.put_line('%notfound属性为null'); 735 end if; 736 loop 737 fetch emp_cursor 738 into emp_row; 739 --每循环一次判断%found属性值,如果该值为False,表示提取完成将退出循环 740 exit when emp_cursor%notfound; 741 end loop; 742 close emp_cursor; 743 end; 744 745 --%rowcount 属性 746 declare 747 emp_row emp%rowtype; 748 cursor emp_cursor(p_deptno in number) 749 is select * from emp where deptno=p_deptno; 750 begin 751 open emp_cursor(20); 752 loop 753 fetch emp_cursor into emp_row; 754 exit when emp_cursor%notfound; 755 dbms_output.put_line('当前提取的的行数为: '||emp_cursor%rowcount 756 ||'行!'); 757 end loop; 758 end;