【问题标题】:How do I write this PL/SQL anonymous block so that the output is in reverse order?如何编写此 PL/SQL 匿名块以使输出顺序相反?
【发布时间】:2017-11-27 07:23:05
【问题描述】:
SET SERVEROUTPUT ON
DECLARE
ENAME     VARCHAR2(10);
SAL       NUMBER(7,2);
CURSOR    C1 IS SELECT ENAME, SAL
          FROM EMP
          WHERE ROWNUM < 11;
BEGIN
     OPEN C1;
     LOOP
          FETCH C1 INTO ENAME, SAL;
          EXIT WHEN C1%NOTFOUND;
          DBMS_OUTPUT.PUT_LINE(ENAME ||' '|| SAL);
     END LOOP;
END;
/

这是输出

KING 5000
BLAKE 2850
CLARK 2450
JONES 2975
MARTIN 1250
ALLEN 1600
TURNER 1500
JAMES 950
WARD 1250
FORD 3000

我无法以相反的顺序显示输出。

作为参考,这是向我提出的问题:

编写一个 PL/SQL 匿名块来处理存储在“emp”表中的记录。该程序必须执行以下任务。

  1. 声明存储员工姓名和工资信息所需的类型和变量。

  2. 使用循环检索“emp”表中记录的前 10 个“ename”和“sal”值,存储在两个包含 10 个元素的变量数组中。

  3. 使用另一个循环以相反的顺序显示“ename”和“sal”值。

如前所述,我对第三个任务有疑问。

提前感谢您的帮助。

【问题讨论】:

  • 您需要一个数组并向其追加元素,然后从最高索引迭代到最低索引。
  • 您的老师(或您的教科书)所说的“前 10 个”值是什么意思?桌子上的行就像篮子里的球:它们没有顺序。如果没有某种标记(例如“按 HIRE_DATE 顺序排列的前 10 个”),则该要求毫无意义。如果我教过一门 SQL 入门课,你的老师(或你的教科书)不会通过我的入门课。
  • @mathguy 这是我老师写的。他补充说使用伪列“ROWNUM”来限制薪水的数量,选择10个,不分先后。表中有 14 条记录,我假设他只想要前 10 条。
  • 好的,明白了 - 缺少附加指令,而且我们经常看到实际上不存在该说明的要求。老师让你创建“需要的类型和变量”;他或她可能希望您创建一个记录类型来保存姓名和员工编号(一起在单个记录中),并声明此类记录的数组,如 Kamil G 建议的那样,然后在循环中打印元素数组,索引从 10 到 1。
  • @mathguy 好的,这是有道理的——我想确保语法正确,因为我对 PL/SQL 还很陌生。对于 VARRAY,它会是 TYPE ename IS VARRAY(10) OF VARCHAR2(10);

标签: sql oracle plsql


【解决方案1】:

使用隐式游标并将记录分配给关联数组

声明一个关联数组(也就是按表索引)并分配 emp 记录 https://docs.oracle.com/database/121/LNPLS/composites.htm#LNPLS99969

当我点击 10 条记录时,我有一个 if then 语句,它以相反的顺序打印这个关联数组的 10 条记录。

我包括名义上的错误处理。

   SCOTT@dev>DECLARE
  2      TYPE emp_rec_typ IS RECORD (
  3          ename     emp.ename%TYPE,
  4          sal       emp.sal%TYPE
  5      );
  6      TYPE emp_tab_typ IS
  7          TABLE OF emp_rec_typ INDEX BY BINARY_INTEGER;
  8      n         BINARY_INTEGER;
  9      emp_tab   emp_tab_typ;
 10  BEGIN
 11      n := 0;
 12      FOR emp_rec IN (
 13          SELECT
 14              ename,
 15              sal
 16          FROM
 17              emp
 18          FETCH FIRST 10 ROWS ONLY
 19      ) LOOP
 20          BEGIN
 21              n := n + 1;
 22              emp_tab(n) := emp_rec;
 23              dbms_output.put_line(emp_rec.ename
 24               || ' '
 25               || TO_CHAR(emp_rec.sal) );
 26  
 27              IF
 28                  n = 10
 29              THEN
 30                  dbms_output.put_line('-------------');
 31                  dbms_output.put_line('reverse order');
 32                  dbms_output.put_line('-------------');
 33                  FOR n IN REVERSE 1..10 LOOP
 34                      dbms_output.put_line(emp_tab(n).ename
 35                       || ' '
 36                       || TO_CHAR(emp_tab(n).sal) );
 37                  END LOOP;
 38  
 39              END IF;
 40  
 41          EXCEPTION
 42              WHEN OTHERS THEN
 43                  dbms_output.put(sqlcode || ' ' || sqlerrm);
 44          END;
 45      END LOOP;
 46  
 47  END;
 48  /
SMITH 800
ALLEN 1600
WARD 1250
JONES 2975
MARTIN 1250
BLAKE 2850
CLARK 2450
SCOTT 3000
KING 5000
TURNER 1500
-------------
reverse order
-------------
TURNER 1500
KING 5000
SCOTT 3000
CLARK 2450
BLAKE 2850
MARTIN 1250
JONES 2975
WARD 1250
ALLEN 1600
SMITH 800


PL/SQL procedure successfully completed.

附录

-我想我应该使用两个可变数组而不是关联数组(要求 #2)。就写作而言,那会更简单。

-根据 cmets,我想我可以使用 ROWNUM,但我更喜欢行限制子句。

【讨论】:

    猜你喜欢
    • 2014-09-30
    • 1970-01-01
    • 2017-09-02
    • 2013-11-07
    • 1970-01-01
    • 2018-09-07
    • 1970-01-01
    • 2017-01-29
    • 1970-01-01
    相关资源
    最近更新 更多