游标概述学习

游标分为静态游标和动态游标,其中静态游标又分为隐式游标和显示游标,动态游标分为强类型,弱类型。

显示游标的使用步骤和语法

显示游标通常与查询语句结合使用,用于循环获取结果集。

1.声明游标

  CURSOR<游标名>IS SELECT<语句>;

2.打开游标

  OPEN<游标名>;

3.提取游标

  FETCH<游标名>INTO<变量列表>;

4.关闭游标

  CLOSE<游标名>;

示例:

DECLARE
v_name emp.ename%TYPE;--声明变量
v_empno emp.empno%TYPE;--声明变量
CURSOR emp_cur IS --定义游标
SELECT ename,empno FROM emp;--查询语句
BEGIN
OPEN emp_cur;--打开游标
LOOP
FETCH emp_cur INTO v_name,v_empno;--提取游标
EXIT WHEN emp_cur%NOTFOUND;
dbms_output.put_line(emp_cur%ROWCOUNT||' '||v_empno||' '||v_name);
END LOOP;
CLOSE emp_cur;--关闭游标
END;

 

游标的属性:

%ISOPEN 游标是否打开,返回布尔值;

%FOUND 游标是否指向有效行,返回布尔值;

%NOTFOUND 游标是否没有指向有效行,返回布尔值;

%ROWCOUNT 游标抽取的行数,DML语句影响行的情况返回1否则返回0;

使用方法:游标名%属性名

循环游标

其中"类型"循环游标自动创建%ROWTYPE类型的变量并将此变量用作记录索引。

FOR<类型>IN<游标名>LOOP...;

--数据操作--

END LOOP;

示例


DECLARE
emp_row emp%ROWTYPE;--员工 信息表行类型
dept_row dept%ROWTYPE;--部门 信息表行类型
CURSOR emp_cur IS --声明游标
SELECT e.empno,e.ename FROM emp e,dept d--自定义记录类型的变量
WHERE e.deptno=d.deptno;
BEGIN
FOR emp_record IN emp_cur LOOP
dbms_output.put_line('第'||emp_cur%ROWCOUNT||'个雇员,编号为'||
emp_record.empno||'姓名为'||emp_record.ename);
END LOOP;
END;

 

 隐式游标

隐式游标通常拿来判断DML的执行是否成功,也就是对表的增,删,改。

隐式游标与显示游标的区别:

1.不用声明游标

2.不用打开和关闭游标

3.SELECT语句必须使用INTO子句,结果只能是一条

隐式游标与显示游标的相同点:都有相同的属性,is%OPEN,%FOUND,%NOTFOUNT,%ROWCOUNT。

示例

DECLARE
  EMP_ROW EMP%ROWTYPE; --声明数据行
BEGIN
  SELECT EMPNO, ENAME, SAL
    INTO EMP_ROW.EMPNO, EMP_ROW.ENAME, EMP_ROW.SAL --使用INTO子句
    FROM EMP
   WHERE EMPNO = 7788;
  IF SQL%FOUND THEN
    DBMS_OUTPUT.PUT_LINE(SQL%ROWCOUNT || '   ' || EMP_ROW.EMPNO || '  ' ||
                         EMP_ROW.ENAME || '   ' || EMP_ROW.SAL);
  END IF;
END;

示例

declare 
emp_row emp%ROWTYPE;
begin
      UPDATE emp SET ename='Lucy' WHERE empo=7756;
      IF  SQL%ROWCOUNT >0 THEN 
        dbms_output.put_line('更新成功');
       ELSE
        dbms_output.put_lind('更新失败');
       END IF;
end;

 

REF动态游标

动态游标往往结合存储过程使用,如查询需要动态改变,就使用它。

注意:强类型REF动态游标只能为查询结果与return类型相同的查询打开。

示例:

--强类型REF动态游标
DECLARE
  TYPE REF_EMP_TYPE IS REF CURSOR RETURN EMP%ROWTYPE; --声明ref游标
  REF_EMP REF_EMP_TYPE; --游标类型变量
  EMP_ROW EMP%ROWTYPE; --
BEGIN
  OPEN REF_EMP FOR  --打开游标
    SELECT * FROM EMP;
  LOOP
    FETCH REF_EMP  
      INTO EMP_ROW;--提取游标
    EXIT WHEN REF_EMP%NOTFOUND;
    DBMS_OUTPUT.PUT_LINE(REF_EMP%ROWCOUNT || ' ' || EMP_ROW.EMPNO || ' ' ||
                         EMP_ROW.ENAME);
  END LOOP;
  CLOSE REF_EMP;--关闭游标
END;

弱类型REF游标

注意:弱类型REF游标比较灵活适用于对用户动态输入动态查询表单。

--根据用户输入动态获取信息
DECLARE
TYPE ref_type IS REF CURSOR;--声明REF游标
ref_sec ref_type;--声明游标类型变量
v_id NUMBER;
v_name VARCHAR2(50);
flag VARCHAR2(1):=UPPER(SUBSTR('&tab',1,1));
BEGIN
  IF flag='E' THEN
    OPEN ref_sec FOR SELECT empno,ename  FROM emp;--打开emp游标
    dbms_output.put_line('======员工信息表======');
    ELSIF flag='D' THEN
    OPEN ref_sec FOR SELECT deptno,dname FROM dept;
    dbms_output.put_line('======部门信息表======');--打开dept游标
    ELSE 
    dbms_output.put_line('请输入员工信息表(E)或部门信息表(D)');
    RETURN;
    END IF;
    FETCH ref_sec INTO v_id,v_name; --提取游标
    WHILE ref_sec%FOUND LOOP--while 循环语句
    dbms_output.put_line('#'||v_id||':'||v_name);
    FETCH ref_sec INTO v_id,v_name;     --提取第二条记录
    END LOOP;
    CLOSE ref_sec;
END;

 

静态SQL

静态SQL是在编写PL/SQL程序时,SQL语句已经编写好了(DML语句和事务控制语句),但是DDL以及会话控制语句不能在PL/SQL中直接使用,但是可以通过动态SQL来解决这个问题。

动态SQL

不编译,执行时动态 确定

根据用户输入参数等才能确定的SQL语句

解决PL/SQL中不支持DDL语句的问题

语法:

EXECUTE IMMEDIATE '动态SQL语句字符串';

[INTO]子句用于接收SELECT语句选择的记录值。

[USING]子句用于绑定输入参数变量。

示例:

BEGIN
  EXECUTE IMMEDIATE 'create table text (id number,name varchar2(30))';
END;

DECLARE
  V_ID       NUMBER := &VID;
  V_NAME     VARCHAR(30) := '&vname';
  INSERT_SQL VARCHAR(200) := 'insert into text values(:1,:2)';--(:1,:2)为占位符代表值不能是关键字,这里:1指的是v_id
BEGIN
  EXECUTE IMMEDIATE INSERT_SQL
    USING V_ID, V_NAME;
END;
DECLARE
sql_stmt VARCHAR2(200);
emp_id NUMBER:=&emp_id;
emp_rec emp%ROWTYPE;
BEGIN
  sql_stmt:='select * from emp  where empno=:id';--这里的:id指的是动态输入的ID也就是emp_id
  EXECUTE  IMMEDIATE sql_stmt INTO emp_rec  USING emp_id;
  dbms_output.put_line(emp_rec.sal);
END;

 

带参数的游标

--带参数的游标
DECLARE
  CURSOR CUR_EMP(DNO NUMBER) IS
    SELECT * FROM EMP WHERE DEPTNO = DNO;
  EMP_ROW EMP%ROWTYPE;
BEGIN
  OPEN CUR_EMP(30);
  LOOP
    FETCH CUR_EMP
      INTO EMP_ROW; --3、提取游标
    EXIT WHEN CUR_EMP%NOTFOUND;
    DBMS_OUTPUT.PUT_LINE(CUR_EMP%ROWCOUNT || '   ' || EMP_ROW.EMPNO || '  ' ||
                         EMP_ROW.ENAME || '   ' || EMP_ROW.SAL);
  END LOOP;
  CLOSE CUR_EMP;
END;

 

posted @ 2015-01-09 23:25  justlgx  阅读(157)  评论(0编辑  收藏  举报