PL / SQL Programming (lower)

cursor

Operation of the cursor

  1. step
  2. Define a cursor
定义游标
语法
    CURSOR cursor_name IS select_statement ;
说明
游标必须在PL/SQL块的声明部分进行定义;
游标定义时可以引用PL/SQL变量,但变量必须在游标定义之前定义;
定义游标时并没有生成数据,只是将定义信息保存到数据字典中;
游标定义后,可以使用cursor_name%ROWTYPE定义游标类型变量。
  1. Open the cursor
打开游标
语法
   OPEN cursor_name; 
说明
检查变量的值
执行游标定义时对应的SELECT语句,将查询结果检索到工作区中。
游标指针指向第一个元组。
一旦游标打开,就无法再次打开,除非先关闭。
如果游标定义中的变量值发生变化,则只能在下次打开游标时才起作用。
  1. Retrieving cursor
检索游标
语法格式
   FETCH cursor_name INTO variable_list|record_variable; 
说明
在使用FETCH语句之前必须先打开游标
对游标第一次使用FETCH语句时,游标指针指向第一条记录,因此操作的对象是第一条记录,使用后,游标指针指向下一条记录。
游标指针只能向下移动,不能回退。
INTO子句中的变量个数、顺序、数据类型必须与工作区中每行记录的字段数、顺序以及数据类型一一对应。
  1. Close the cursor
关闭游标
语法格式
    CLOSE cursor_name; 
说明
游标所对应的内存工作区变为无效,释放与游标相关的系统资源

Declare a cursor emp table of employee information retrieval, and then open the cursor, and specify the retrieval position is 'MANAGER' employee information, then use fetch ... into statement and the while loop reads all employee information in the cursor, read the final output employee information.

DECLARE
Cursor cur_emp(var_job in varchar2:=‘SALESMAN’)
Is select empno,ename,sal
From emp
Where job=var_job;
Type record_emp is record
(var_empno emp.empno%type,
var_ename emp.ename%type,
var_sal emp.sal%type);
Emp_row record_emp;
BEGIN
  open cur_emp(‘MANAGER’);
Fetch cur_emp into emp_row;
While cur_emp%found loop
Dbms_output.put_line(emp_row.var_ename||’的编号是’||
emp_row.var_empno||’,工资是’||emp_row.var_sal);
Fetch cur_emp into emp_row;                                
  END LOOP; 
  CLOSE c_emp;
END; 

Explicit cursor attributes

%ISOPEN
布尔型。如果游标已经打开,返回TRUE,否则为FALSE。
%FOUND
布尔型,如果最近一次使用FETCH语句,有返回结果则为TRUE,否则为FALSE;
%NOTFOUND
布尔型,如果最近一次使用FETCH语句,没有返回结果则为TRUE,否则为FALSE;
%ROWCOUNT
数值型,返回到目前为止从游标缓冲区检索的元组数。
%BULK_ROWCOUNT(i)
数值型,用于取得FORALL语句执行批绑定操作时第i个元素所影响的行数。
声明一个游标,用于检索指定员工编号的雇员信息,然后使用游标的%found属性来判断是否检索到指定员工编号的雇员信息。
DECLARE
Var_ename varchar2(50);
Var_job varchar2(50);
Cursor cur_emp
Is select ename,job
From emp
Where empno=7499;
BEGIN
  open cur_emp;
Fetch cur_emp into var_ename,var_job;
If cur_emp%found then
Dbms_output.put_line(‘编号是7499的雇员名称为:’||var_ename||’,
职务是:’||var_job);
Else
Dbms_output.put_line(‘无数据记录’);
End if;
END; 

** ** implicit cursor

概念
所有的SQL语句都有一个执行的缓冲区,隐式游标就是指向该缓冲区的指针,由系统隐含地打开、处理和关闭。隐式游标又称为SQL游标。
隐式游标主要用于处理INSERT、UPDATE,DELETE以及单行的SELECT…INTO语句,没有OPEN,FETCH,CLOSE等操作命令。

Modify the number of employees wages 1000, wages will increase by 100. If the employee does not exist, is inserted into the emp table for the employee number 1000, wages of 1,600 employees.

 BEGIN
    UPDATE emp SET sal=sal+100 WHERE empno=1000;
    IF SQL%NOTFOUND THEN
      INSERT INTO emp(empno,sal) VALUES(1000,1600);
    END IF;
  END;
  BEGIN
    UPDATE emp SET sal=sal+100 WHERE empno=1000;
    IF SQL%ROWCOUNT=0 THEN
      INSERT INTO emp(empno,sal) VALUES(1000,1600);
    END IF;
  END;

By cursor for loop

语法格式:
For var_auto_record in cur_name loop
Plsqlsentence;
End loop;
例:使用显式游标和for语句检索出部门编号是30
的雇员信息并输出。

SQL>set serveroutput on
SQL>declare
    cursor cur_emp is
    select * from emp
    where deptno=30;
    begin
    for emp_record in cur_emp
    loop
      dbms_output.put(‘雇员编号:’||emp_record.empno);
      dbms_output.put(‘:雇员名称:’||emp_record.ename);
      dbms_output.put_line(‘:雇员职务:’||emp_record.job);
     end loop;
    end;
    /
例:使用隐式游标和for语句检索出职务是销售员
的雇员信息并输出。

SQL>set serveroutput on
SQL>begin
    for emp_record in(select empno,ename,sal from emp
    where job=‘SALESMAN’)
    loop
      dbms_output.put(‘雇员编号:’||emp_record.empno);
      dbms_output.put(‘:雇员名称:’||emp_record.ename);
      dbms_output.put_line(‘:雇员工资:’||emp_record.sal);
     end loop;
    end;
    /

Predefined exception

例:使用select into语句检索emp表中部门编号为10的雇员记录信息,
然后使用“too_many_rows”预定义异常捕获错误信息并输出。

DECLARE
  Var_empno number;
  Var_ename varchar2(50);
Begin
  Select empno,ename into var_empno,var_ename
  From emp
  Where deptno=10;
  If sql%found then
  Dbms_output.put_line(‘雇员编号:’||var_empno||’;雇员名称’
||var_ename);
 End if;
Exception
 When too_many_rows then
 Dbms_output.put_line(‘返回记录超过一行’);
 When no_data_found then
 Dbms_output.put_line(‘无数据记录’);
End;

Custom exception

声明一个异常名称
e_integrity EXCEPTION;
将异常与一个Oracle错误号相绑定
PRAGMA EXCEPTION-INIT(e_integrity.-2291)
示例

DECLARE
  e_deptno_fk EXCEPTION;
  PRAGMA EXCEPTION_INIT(e_deptno_fk,-2292);
BEGIN
……
EXCEPTION
……
END;

Exception handling process

异常处理分3个步骤进行:
在声明部分为错误定义异常,包括非预定义异常和用户定义异常。
在执行过程中当错误产生时抛出与错误对应的异常。
在异常处理部分通过异常处理器捕获异常,并进行异常处理。

Abnormal capture and processing

例如,查询名为SMITH的员工工资,如果该员工不存在,则输出“There is not such an employee!”;如果存在多个同名的员工,则输出其员工号和工资。

DECLARE
  v_sal emp.sal%type;
BEGIN
  SELECT sal INTO v_sal FROM emp WHERE ename='SMITH';
  DBMS_OUTPUT.PUT_LINE(v_sal);
EXCEPTION
  WHEN NO_DATA_FOUND THEN 
    DBMS_OUTPUT.PUT_LINE('There is not such an emplyee!');
  WHEN TOO_MANY_ROWS THEN
    FOR v_emp IN (SELECT * FROM emp WHERE ename='SMITH')    
    LOOP
       DBMS_OUTPUT.PUT_LINE(v_emp.empno||' '||v_emp.sal);
    END LOOP;
END;
Published 36 original articles · won praise 26 · views 7581

Guess you like

Origin blog.csdn.net/weixin_43566977/article/details/103657497