【问题标题】:View Results of SELECT * INTO statement within PL/SQL查看 PL/SQL 中 SELECT * INTO 语句的结果
【发布时间】:2016-12-21 16:15:53
【问题描述】:

我正在将数据推送到我在 PL/SQL 中创建的表中,我有两个问题。 我创建了一个过于简单的示例来说明使用位于以下链接中的 emp 表: https://apexplained.wordpress.com/2013/04/20/the-emp-and-dept-tables-in-oracle/

我在 fetch 语句中创建了两个查询(一个返回 6 行,一个返回 2 行)。

  1. 如何查看表格结果?
  2. 如何编写我的 PL/SQL 代码,以便将新数据推送到表末尾并且不会删除表中的所有内容。

开始 PL/SQL 代码

DECLARE
   TYPE EmpTabTyp IS TABLE OF EMP%ROWTYPE
   INDEX BY PLS_INTEGER;

   CURSOR FetchCursor1 is
    select * from emp where empno > 7800;

  CURSOR FetchCursor2 is
    select * from emp where empno < 7500;

   emp_tab EmpTabTyp;
BEGIN
   /* Retrieve employee record. */
   OPEN FetchCursor1;
   FETCH FetchCursor1
        bulk collect into Emp_Tab;
   DBMS_OUTPUT.PUT_LINE('Size of Emp_Tab is ' || EMP_TAB.COUNT);
   close FetchCursor1;
   for indx in 1 .. EMP_TAB.COUNT
   loop
    dbms_output.put_line(indx);
    --The row below is giving error.
    --dbms_output.put_line(EMP_TAB.EMPNO||chr(9)||chr(9)||EMP.ENAME);
   end loop;

   OPEN FetchCursor2;
   FETCH FetchCursor2
        bulk collect into Emp_Tab;
   DBMS_OUTPUT.PUT_LINE(EMP_TAB.COUNT);
   --DBMS_OUTPUT.PUT_LINE(||EMP_TAB.empno||);
   close FetchCursor2;

   DBMS_OUTPUT.PUT_LINE('Size of Emp_Tab is ' || EMP_TAB.COUNT);

   for indx in 1 .. EMP_TAB.COUNT
   loop
    dbms_output.put_line(indx);
    --dbms_output.put_line(EMP_TAB.EMPNO||chr(9)||chr(9)||EMP.ENAME);
   end loop;
END;

结束 PL/SQL 代码

当我尝试运行以下语句时:

DBMS_OUTPUT.PUT_LINE(||EMP_TAB.empno||);

我收到此错误:

错误报告:
ORA-06550:第 37 行,第 34 列:
PLS-00302:必须声明组件“EMPNO”
ORA-06550:第 37 行,第 5 列:
PL/SQL:语句被忽略
06550. 00000 - “第 %s 行,第 %s 列:\n%s”
*原因:通常是 PL/SQL 编译错误。
*行动:

这是成功运行时的输出代码:

匿名块完成
Emp_Tab 的大小为 6
1
2
3
4
5
6
2
Emp_Tab 的大小为 2
1
2

【问题讨论】:

  • EMP_TAB 是一个集合,它将具有行成员,每个行成员将具有列(属性),例如 EMPNOEMPName 等。要访问各个行,您必须使用 EMP_TAB(indx)要访问第一条记录的empno,您必须使用EMP_TAB(indx).EMPNO。更多示例请参考oracle-base.com/articles/9i/bulk-binds-and-record-processing-9i

标签: oracle plsql


【解决方案1】:

EMP_TAB 将是游标获取的行的集合。要引用单个行,您必须 EMP_TAB(n) 表示结果集中的第 n 条记录。要选择第n条记录的empno,正确的语法是EMP_TAB(n).EMPNO

所以在你的情况下正确的用法是

DBMS_OUTPUT.PUT_LINE(||EMP_TAB(indx).empno||); 

【讨论】:

  • 感谢您回答有关如何打印到 dbms 的问题!
  • 您好,上面的回复显示了如何使用 dbms_output.put_line 打印行。如果我想向现有的行集合添加新行怎么样。请注意,第一个查询返回 6 行,第二个查询返回 2 行。我希望行集合(emp_tab)在第二次提取后有 8 行
  • @PatStarks 您可以通过两种方式解决问题。一种方法是使用UNIONUNION ALL 运算符将两个查询组合在一起,并同时将批量提取结果集设置为集合。另一种解决方案是将第二个游标的结果提取到另一个集合中,然后使用 MULTISET UNION 组合两个集合。例如,请参阅oracle.com/technetwork/issue-archive/o53plsql-083350.html
  • 您也可以查看stackoverflow.com/questions/2328389/… 以获得更好的示例
【解决方案2】:

试试这个:

 DECLARE
       TYPE EmpTabTyp IS TABLE OF EMP%ROWTYPE
       INDEX BY PLS_INTEGER;

       CURSOR FetchCursor1 is
        select * from emp where empno > 7800;

      CURSOR FetchCursor2 is
        select * from emp where empno < 7500;

       emp_tab EmpTabTyp;
    BEGIN
       /* Retrieve employee record. */
       OPEN FetchCursor1;
       FETCH FetchCursor1
            bulk collect into Emp_Tab;
       DBMS_OUTPUT.PUT_LINE('Size of Emp_Tab is ' || EMP_TAB.COUNT);
       close FetchCursor1;
       for indx in 1 .. EMP_TAB.COUNT
       loop
        dbms_output.put_line(indx);
        --The row below is giving error.
        dbms_output.put_line(EMP_TAB(indx).EMPNO||chr(9)||chr(9)||EMP_TAB(indx).ENAME);
       end loop;

       OPEN FetchCursor2;
       FETCH FetchCursor2
            bulk collect into Emp_Tab;
       close FetchCursor2;

       DBMS_OUTPUT.PUT_LINE('Size of Emp_Tab is ' || EMP_TAB.COUNT);

       for indx in 1 .. EMP_TAB.COUNT
       loop
        dbms_output.put_line(indx);
        dbms_output.put_line(EMP_TAB(indx).EMPNO||chr(9)||chr(9)||EMP_TAB(indx).ENAME);
       end loop;
    END;

【讨论】:

    【解决方案3】:

    这里需要添加“DBMS_OUTPUT.PUT_LINE(||EMP_TAB(indx).empno||);”

    【讨论】:

      【解决方案4】:

      您好,上面的回复显示了如何使用打印行 dbms_output.put_line。如果我想向现有行添加新行怎么样 行的集合。请注意,第一个查询返回 6 行,第二个 查询返回 2 行。我想收集行(emp_tab)到 第二次提取后有 8 行

      您不能简单地将数据添加到集合中。 但是,您可以将 BULK COLLECT 放入一个单独的集合中,然后合并这些集合。您确实需要一个嵌套表而不是关联数组。请参见下面的示例:

      DECLARE
         TYPE EmpTabTyp IS TABLE OF EMPLOYEE%ROWTYPE ;
            --INDEX BY PLS_INTEGER;
      
         CURSOR FetchCursor1
         IS
            SELECT *
              FROM EMPLOYEE
             WHERE EMPLOYEE_id > 4;
      
         CURSOR FetchCursor2
         IS
            SELECT *
              FROM EMPLOYEE
             WHERE EMPLOYEE_id < 3;
      
         emp_tab   EmpTabTyp;
         emp_tab1   EmpTabTyp;
      BEGIN
         /* Retrieve employee record. */
         OPEN FetchCursor1;
      
         FETCH FetchCursor1 BULK COLLECT INTO Emp_Tab;
      
         CLOSE FetchCursor1;
      
      
         OPEN FetchCursor2;
      
           FETCH FetchCursor2 BULK COLLECT INTO emp_tab1;
      
         CLOSE FetchCursor2;  
         --Joining two collections
         Emp_Tab := Emp_Tab MULTISET UNION  Emp_Tab1;
      
         FOR indx IN 1 .. EMP_TAB.COUNT
         LOOP      
            dbms_output.put_line(EMP_TAB(indx).EMPloyee_id||chr(9)||chr(9)||EMP_TAB(indx).First_NAME);
         END LOOP;
      END;
      

      输出:

      sql > 
      9               XING
      1               Dan
      2               Helen
      
      PL/SQL procedure successfully completed.
      

      【讨论】:

      • 非常感谢!这就是我要找的。我在现实生活中的例子更复杂,因为我会将许多查询的结果连接到一个集合中。我将尝试使用我从这篇有用的帖子中学到的东西!
      猜你喜欢
      • 1970-01-01
      • 2019-06-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-19
      • 1970-01-01
      • 2019-05-24
      • 2012-10-18
      相关资源
      最近更新 更多