• Oracle_集合


    游标遍历select语句

    set serveroutput on;
    
    declare type sp_test1_cursor is ref cursor;
            test1_cursor sp_test1_cursor;
            v_name user_tables.TABLE_NAME%type;
            v_count number;
            strsql varchar2(100);
    begin
      open test1_cursor for select table_name from user_tables;
      loop
        fetch test1_cursor into v_name;
        if v_name is not null then
          strsql:='select count(*) from ' || v_name;
          execute immediate strsql into v_count;
         end if;
         exit when test1_cursor%notfound;
         dbms_output.put_line(v_name||'          '||v_count);
      end loop;
      close test1_cursor;
    end;

    全信息

    declare 
       cursor mysor is select * from emp;
     begin
        for i in mysor
          loop
             dbms_output.put_line(i.ename||e.deptno);
          end loop; 
     end;
     create or replace procedure test_procedure_job
    
    as
    v1 varchar2(50);
    v2 varchar2(50);
    v3 varchar2(50);
    begin
       for v1 in
       (select t.id
              from test_table t) 
       loop
           select t.username,t.password into v2,v3 from sshtest t where t.id = v1.id;
           
           dbms_output.put_line(v1.id || ',' || v2 || ',' || v3);
         
       end loop;
       
    end test_procedure_job;

    一维数组

    SET SERVEROUT ON SIZE 100000
    
    DECLARE
    
      TYPE T_VARRAY IS VARRAY(3) OF VARCHAR2(20);
    
      V_VAR T_VARRAY := T_VARRAY('I', 'LOVE', 'STUDY');
    
    BEGIN
    
      FOR I IN 1 .. V_VAR.COUNT LOOP
    
        DBMS_OUTPUT.PUT_LINE(V_VAR(I));
    
      END LOOP;
    
    END;
    
     

     For 循环

       PL/SQL中有两种类型的FOR循环:数字型FOR循环和游标型FOR循环。数值型FOR循环式传统的大家熟悉的“计数”循环,这种FOR循环的迭代次数在循环开始的时候就知道了。如果在FOR循环的范围处没有设置循环索引的递进方向从低到高或者从高到低(reverse将范围条件置反)。语法如下:
    
    FOR loopIndex    IN [REVERSE] lowest_number..heighest_number 
    
    LOOP
    
        . . . 可以执行的语句
    
    END LOOP;
    
    使用这种循环的原因:
    
        如果只想有限次的执行一段代码,又不想过早的结束循环,就可以使用数值型的FOR循环。
    
    【如】输出从satrtIndex开始到endIndex的数字
    
    PROCEDURE display_number(
    
        startIndex    IN    INTEGER,
    
        endIndex     IN    INTEGER
    
    )AS
    
    BEGIN
    
    FOR currentIndex IN startIndex.. endIndex
    
        LOOP
    
            DBMS_OUTPUT.PUT_LINE(currentIndex );
    
    END LOOP;
    
    END;
    
    FOR info IN (SELECT * FROM student)
    
    LOOP
    
        . . . info.C_NAME
    
    END LOOP;
    
    使用数字型FOR循环的规则:
    
    a、不要声明循环索引,PL/SQL会自动、隐式的用一个INTEGER类型的局部变量作为循环索引。作用范围就是该循环本省,不能在循环之外使用
    
    b、在范围部分使用的表达式会在循环开始时被求值一次。范围部分不会随着循环的反复执行而被重复求值,如果在循环体内部改变范围表达式使用的变量,这种改变对范围边界没有任何作用
    
    c、在循环体内部不要改变索引值或者范围边界值。
    
    d、使用reverse关键字可以迫使循环从上边界到下边界递减进行,但是你必须保证上边界大于下边界
    
    处理非平滑增长:
    
        PL/SQL并没有提供可以指定特殊的累进步幅得“进步”语法。在PL/SQL中数值型的FOR循环的各种变体中,递进步幅总是为1为单位进步。如果让循环只有当遇到1到100之间的偶数时才执行?你可以使用MOD函数。如:
    
    FOR loop_index IN 1..100 LOOP
    
        IF MOD (loop_index, 2) = 0 THEN
    
           calc_values(loop_index);
    
        END IF;
    
    END LOOP;
    
    或者
    
    FOR loop_index IN 1..50 LOOP
    
        calc_values(loop_index*2);
    
    END LOOP;
    
    游标型FOR循环:
    
        游标型FOR循环是和一个现实游标或者直接放在循环边界中的SELECT语句关联在一起的循环。如果你需要取出游标的每条记录依次处理,就可以使用游标FOR循环,而这种也是游标的主要用法。语法如下:
    
    FOR record IN {cursor_name | select statement}
    
    LOOP
    
        executable statements
    
    END LOOP;
    
    其中record是一个记录,这个记录是PL/SQL根据cursor_name这个游标%ROWTYPE属性隐式声明出来的。注意:不要现实的声明一个与循环索引(record)同名的记录,会导致逻辑错误。直接在循环中嵌套SELECT语句。
    
    FOR student INSELECT * FROM students)
    
    LOOP
    
        DBMS_OUTPUT.PUT_LINE( student.N_USERNAME );
    
    END LOOP;
    
    然而,应该避免使用这种方式,因为SELECT出现在了不该出现的地方,维护难以理解。
    
    如:我们将更新所有员工的薪水。
    
    方式一:
    
    DECLARE
    
        CURSOR student_cursor IS
    
            SELECT id, name, salaray FROM employers;
    
        student    student_cursor%ROWTYPE;
    
    BEGIN
    
        OPEN student_cursor;
    
        LOOP
    
            FETCH student_cursor INTO student;
    
            EXIT WHEN student_cursor%NOTFOUND;
    
            UPDATE students SET salary= student .salary*0.3 WHERE id=student.id;    
    
        END LOOP;
    
        CLOSE student_cursor;
    
    END;
    
    方式二:
    
    DECLARE
    
        CURSOR student_cursor IS
    
            SELECT id, name, salaray FROM employers;
    
    BEGIN
    
        LOOP student IN student_cursor 
    
            UPDATE students SET salary= student .salary*0.3 WHERE id=student.id;    
    
        END LOOP;
    
    END;

     游标

    SET SERVEROUTPUT ON;
    
    DECLARE
      v_empno emp.empno%TYPE;
      v_ename emp.ename%TYPE;
      
      CURSOR emp_cursor IS
      SELECT empno,ename from emp where empno<>1000;
      
    BEGIN
    
    LOOP
    
      IF NOT emp_cursor%ISOPEN  THEN
         OPEN emp_cursor;
      END IF; 
      
      FETCH emp_cursor INTO  v_empno,v_ename; 
      EXIT WHEN emp_cursor%NOTFOUND;
     
      dbms_output.put_line('empno is:' || v_empno || ' emp name is:' || v_ename);
        
    END LOOP;
    
    END;
    /

    运行结果

    anonymous block completed
    empno is:7369 emp name is:SMITH
    empno is:7499 emp name is:ALLEN
    empno is:7521 emp name is:WARD
    empno is:7566 emp name is:JONES
    empno is:7654 emp name is:MARTIN
    empno is:7698 emp name is:BLAKE
    empno is:7782 emp name is:CLARK
    empno is:7788 emp name is:SCOTT
    empno is:7839 emp name is:KING
    empno is:7844 emp name is:TURNER
    empno is:7876 emp name is:ADAMS
    empno is:7900 emp name is:JAMES
    empno is:7902 emp name is:FORD
    empno is:7934 emp name is:MILLER
    要注意的一点:FETCH 后,马上进行EXIT 比较好。这是因为如果不是这样,在循环中还有来一次,此时可能有干了一些操作,这回导致出现问题。
    
    还有一点,由于 第一次FETCH之前,%NOTFOUND 的值为空。
    
    所以如果 FETCH 从来没有真的成功过,那么 EXIT WHEN emp_cusor%NOTFOUND 有可能一直为NULL,这样就一直在循环里无法退出。所以,更好的写法是:
    
    EXIT WHEN emp_cursor%NOTFOUND OR emp_cursor%NOTFOUND IS NULL
    
    结束 
  • 相关阅读:
    LeetCode-079-单词搜索
    awk学习笔记
    Python实现排列组合算法
    python模拟登录人人
    Python的SQLite数据库使用方法
    C语言排序算法——插入排序算法
    C语言排序算法——简单选择排序算法
    C语言排序算法——冒泡排序算法
    Python学习——python的函数参数传递
    Python学习——实现secure copy功能
  • 原文地址:https://www.cnblogs.com/MarchThree/p/4934824.html
Copyright © 2020-2023  润新知