• oracle的新发现for语句


    今天为了解决一个查询结果想两次遍历的方法,去ORACLE官网文档中心 https://docs.oracle.com/en/database/oracle/,意外发现这个有意思的for语句。还是官方资料给力啊

    遍历一个游标

    DECLARE
      CURSOR c1 IS
        SELECT last_name, job_id FROM employees
        WHERE job_id LIKE '%CLERK%' AND manager_id > 120
        ORDER BY last_name;
    BEGIN
      FOR item IN c1
      LOOP
        DBMS_OUTPUT.PUT_LINE
          ('Name = ' || item.last_name || ', Job = ' || item.job_id);
      END LOOP;
    END;
    /

    遍历一个子查询

    BEGIN
      FOR item IN (
        SELECT first_name || ' ' || last_name AS full_name,
               salary * 10                    AS dream_salary 
        FROM employees
        WHERE ROWNUM <= 5
        ORDER BY dream_salary DESC, last_name ASC
      ) LOOP
        DBMS_OUTPUT.PUT_LINE
          (item.full_name || ' dreams of making ' || item.dream_salary);
      END LOOP;
    END;
    /

    遍历列的列表

    DECLARE
      TYPE empcurtyp IS REF CURSOR;
      TYPE namelist IS TABLE OF employees.last_name%TYPE;
      TYPE sallist IS TABLE OF employees.salary%TYPE;
      emp_cv  empcurtyp;
      names   namelist;
      sals    sallist;
    BEGIN
      OPEN emp_cv FOR
        SELECT last_name, salary FROM employees
        WHERE job_id = 'SA_REP'
        ORDER BY salary DESC;
    
      FETCH emp_cv BULK COLLECT INTO names, sals;
      CLOSE emp_cv;
      -- loop through the names and sals collections
      FOR i IN names.FIRST .. names.LAST
      LOOP
        DBMS_OUTPUT.PUT_LINE
          ('Name = ' || names(i) || ', salary = ' || sals(i));
      END LOOP;
    END;
    /

    FOR循环使用关键字REVERSE倒着来

    BEGIN
      DBMS_OUTPUT.PUT_LINE ('upper_bound > lower_bound');
     
      FOR i IN REVERSE 1..3 LOOP
        DBMS_OUTPUT.PUT_LINE (i);
      END LOOP;
     
      DBMS_OUTPUT.PUT_LINE ('upper_bound = lower_bound');
     
      FOR i IN REVERSE 2..2 LOOP
        DBMS_OUTPUT.PUT_LINE (i);
      END LOOP;
     
      DBMS_OUTPUT.PUT_LINE ('upper_bound < lower_bound');
     
      FOR i IN REVERSE 3..1 LOOP
        DBMS_OUTPUT.PUT_LINE (i);
      END LOOP;
    END;
    /
     

    更有意思的游标里可以包含游标对象

    DECLARE
      TYPE emp_cur_typ IS REF CURSOR;
     
      emp_cur    emp_cur_typ;
      dept_name  departments.department_name%TYPE;
      emp_name   employees.last_name%TYPE;
     
      CURSOR c1 IS
        SELECT department_name,
          CURSOR ( SELECT e.last_name
                    FROM employees e
                    WHERE e.department_id = d.department_id
                    ORDER BY e.last_name
                  ) employees
        FROM departments d
        WHERE department_name LIKE 'A%'
        ORDER BY department_name;
    BEGIN
      OPEN c1;
      LOOP  -- Process each row of query result set
        FETCH c1 INTO dept_name, emp_cur;
        EXIT WHEN c1%NOTFOUND;
        DBMS_OUTPUT.PUT_LINE('Department: ' || dept_name);
     
        LOOP -- Process each row of subquery result set
          FETCH emp_cur INTO emp_name;
          EXIT WHEN emp_cur%NOTFOUND;
          DBMS_OUTPUT.PUT_LINE('-- Employee: ' || emp_name);
        END LOOP;
      END LOOP;
      CLOSE c1;
    END;
    /

    Exit还可以这样用

    DECLARE
      s  PLS_INTEGER := 0;
      i  PLS_INTEGER := 0;
      j  PLS_INTEGER;
    BEGIN
      <<outer_loop>>
      LOOP
        i := i + 1;
        j := 0;
        <<inner_loop>>
        LOOP
          j := j + 1;
          s := s + i * j; -- Sum several products
          EXIT inner_loop WHEN (j > 5);
          EXIT outer_loop WHEN ((i * j) > 15);
        END LOOP inner_loop;
      END LOOP outer_loop;
      DBMS_OUTPUT.PUT_LINE
        ('The sum of products equals: ' || TO_CHAR(s));
    END;
    /
     

    continue也可以使用when

    DECLARE
      x NUMBER := 0;
    BEGIN
      LOOP -- After CONTINUE statement, control resumes here
        DBMS_OUTPUT.PUT_LINE ('Inside loop:  x = ' || TO_CHAR(x));
        x := x + 1;
        CONTINUE WHEN x < 3;
        DBMS_OUTPUT.PUT_LINE
          ('Inside loop, after CONTINUE:  x = ' || TO_CHAR(x));
        EXIT WHEN x = 5;
      END LOOP;
      DBMS_OUTPUT.PUT_LINE (' After loop:  x = ' || TO_CHAR(x));
    END;
    /
     

    FOR循环中变量可以重名

    BEGIN
      <<outer_loop>>
      FOR i IN 1..3 LOOP
        <<inner_loop>>
        FOR i IN 1..3 LOOP
          IF outer_loop.i = 2 THEN
            DBMS_OUTPUT.PUT_LINE
              ('outer: ' || TO_CHAR(outer_loop.i) || ' inner: '
               || TO_CHAR(inner_loop.i));
          END IF;
        END LOOP inner_loop;
      END LOOP outer_loop;
    END;
    /

    跳转语句GOTO的使用

    DECLARE
      p  VARCHAR2(30);
      n  PLS_INTEGER := 37;
    BEGIN
      FOR j in 2..ROUND(SQRT(n)) LOOP
        IF n MOD j = 0 THEN
          p := ' is not a prime number';
          GOTO print_now;
        END IF;
      END LOOP;
    
      p := ' is a prime number';
     
      <<print_now>>
      DBMS_OUTPUT.PUT_LINE(TO_CHAR(n) || p);
    END;
    /
     
    DECLARE
      v_last_name  VARCHAR2(25);
      v_emp_id     NUMBER(6) := 120;
    BEGIN
      <<get_name>>
      SELECT last_name INTO v_last_name
      FROM employees
      WHERE employee_id = v_emp_id;
      
      BEGIN
        DBMS_OUTPUT.PUT_LINE (v_last_name);
        v_emp_id := v_emp_id + 5;
     
        IF v_emp_id < 120 THEN
          GOTO get_name;
        END IF;
      END;
    END;
    /
     

    创建可以传参的游标

    DECLARE
      CURSOR c1 (job VARCHAR2, max_wage NUMBER) IS
        SELECT * FROM employees
        WHERE job_id = job
        AND salary > max_wage;
    BEGIN
      FOR person IN c1('ST_CLERK', 3000)
      LOOP
         -- process data record
        DBMS_OUTPUT.PUT_LINE (
          'Name = ' || person.last_name || ', salary = ' ||
          person.salary || ', Job Id = ' || person.job_id
        );
      END LOOP;
    END;
    /

    两次遍历一个结果的最终解法♠♠♠

    declare
      cursor c1 is
          select stockInfo from T_stock ORDER BY id;
    BEGIN
      FOR item IN c1
      LOOP
        DBMS_OUTPUT.PUT_LINE
          ('首次输出 = ' || item.stockInfo);
      END LOOP;
      FOR item IN c1
      LOOP
        DBMS_OUTPUT.PUT_LINE
          ('二次访问 = ' || item.stockInfo);
      END LOOP;
    END;
    凡哥,别他妈吹牛逼了
  • 相关阅读:
    Scala 学习 (八) 高级语法
    Scala 学习 (七) 并发编程模型Akka
    Scala 学习 (六) 面向对象
    Scala 学习(五) Set和HashSet
    Scala 学习(四) 集合之List
    Scala 学习(三) 集合之数组
    Scala 学习(二) 方法和函数
    datatable动态添加,及填充数据
    因为数据库正在使用,所以无法获得对数据库的独占访问权
    win2003超过最大连接数
  • 原文地址:https://www.cnblogs.com/sdlz/p/15354039.html
Copyright © 2020-2023  润新知