zoukankan      html  css  js  c++  java
  • 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;
    凡哥,别他妈吹牛逼了
  • 相关阅读:
    转载:有关推挽输出、开漏输出、复用开漏输出、复用推挽输出以及上拉输入、下拉输入、浮空输入、模拟输入区别
    生活该是什么样子
    怎么处理问题
    jquery.validate 1.7版本(remote方法)bug修复方法(一)
    jquery.ui.dialog 1.81在IE8中出现滚动条bug解决方法
    javascript 懒加载技术(lazyload)简单实现
    jquery.validate 1.7版本(remote方法)bug修复方法(二)
    发布一款JavaScript焦点图组件
    发布一款轻量级的JSON转换代码
    android_intent和intent_action大全 .
  • 原文地址:https://www.cnblogs.com/sdlz/p/15354039.html
Copyright © 2011-2022 走看看