如何在光标选择查询中编写立即执行

时间:2019-09-06 10:28:05

标签: sql oracle plsql

如何在光标中选择立即执行,选择查询。

CREATE OR REPLACE PROCEDURE biq_attendee_report (in_from_date IN DATE)
IS
   l_cur_query          VARCHAR2 (5000) := 'SELECT * from table X where c1='|| in_from_date;

   CURSOR cur_attendee_data
   IS
      EXECUTE IMMEDIATE  l_cur_query;

   TYPE rec_attendee_data IS TABLE OF cur_attendee_data%ROWTYPE
      INDEX BY PLS_INTEGER;

   l_cur_attendee_data  rec_attendee_data;
BEGIN
   OPEN cur_attendee_data;

   LOOP
      FETCH cur_attendee_data BULK COLLECT INTO l_cur_attendee_data;

      EXIT WHEN l_cur_attendee_data.COUNT = 0;
      DBMS_OUTPUT.put_line ('here in first insert');
      lrec := return_attendee_report ();
      out_attendee_tab :=
         return_attendee_arr_result (return_attendee_report ());
      out_attendee_tab.DELETE;

      FOR i IN 1 .. l_cur_attendee_data.COUNT
      LOOP
         BEGIN
            NULL;
         EXCEPTION
            WHEN OTHERS
            THEN
               DBMS_OUTPUT.put_line ('Error occurred : ' || SQLERRM);
         END;
      END LOOP;
   END LOOP;
EXCEPTION
   WHEN OTHERS
   THEN
      DBMS_OUTPUT.put_line ('HERE INSIIDE OTHERS' || SQLERRM);
END;

在这里我尝试在begin块之外使用初始化游标,但是它会引发异常,如何为游标编写动态查询,

cur_attendee_data is
EXECUTE IMMEDIATE  l_cur_query;
  

错误(113,8):PLS-00103:预期以下其中一项时遇到符号“ CUR_ATTENDEE_DATA”::=。 (@%;

3 个答案:

答案 0 :(得分:2)

如果您使用BULK COLLECT INTO ...获取所有行,则只需要一个循环,第二个循环就没有用了。

基本解决方案就是这样:

CREATE OR REPLACE PROCEDURE biq_attendee_report (in_from_date IN DATE) IS

    l_cur_query          VARCHAR2 (5000) := 'SELECT * from {table X} where c1=:d';

   cur_attendee_data SYS_REFCURSOR;    
   TYPE rec_attendee_data IS TABLE OF {table X}%ROWTYPE;
   l_cur_attendee_data  rec_attendee_data;

BEGIN

    OPEN cur_attendee_data FOR l_cur_query USING in_from_date;
    FETCH cur_attendee_data BULK COLLECT INTO l_cur_attendee_data;

    FOR i IN 1 .. l_cur_attendee_data.COUNT LOOP
        -- do whatever you like to do with l_cur_attendee_data(i)
    END LOOP;
    CLOSE cur_attendee_data;

END;

但是,我看不出有任何理由制作动态SQL。您可以简单地运行

CREATE OR REPLACE PROCEDURE biq_attendee_report (in_from_date IN DATE) IS    

   cur_attendee_data SYS_REFCURSOR;    
   TYPE rec_attendee_data IS TABLE OF {table X}%ROWTYPE;
   l_cur_attendee_data  rec_attendee_data;

BEGIN

    OPEN cur_attendee_data FOR SELECT * from {table X} where c1 = in_from_date;
    FETCH cur_attendee_data BULK COLLECT INTO l_cur_attendee_data;

    FOR i IN 1 .. l_cur_attendee_data.COUNT LOOP
        -- do whatever you like to do with l_cur_attendee_data(i)
    END LOOP;
    CLOSE cur_attendee_data;

END;

答案 1 :(得分:0)

您可以改用以下代码-

CREATE OR REPLACE PROCEDURE biq_attendee_report (in_from_date IN DATE)
IS
   l_cur_query          VARCHAR2 (100) := 'SELECT * from table X where c1=:in_from_date';

   TYPE t_cur IS REF CURSOR;
   cur_attendee_data t_cur

   TYPE rec_attendee_data IS TABLE OF cur_attendee_data%ROWTYPE
      INDEX BY PLS_INTEGER;

   l_cur_attendee_data  rec_attendee_data;
BEGIN
   OPEN cur_attendee_data FOR l_cur_query USING in_from_date;

   LOOP
      FETCH cur_attendee_data BULK COLLECT INTO l_cur_attendee_data;

      EXIT WHEN l_cur_attendee_data.COUNT = 0;
      DBMS_OUTPUT.put_line ('here in first insert');
      lrec := return_attendee_report ();
      out_attendee_tab :=
         return_attendee_arr_result (return_attendee_report ());
      out_attendee_tab.DELETE;

      FOR i IN 1 .. l_cur_attendee_data.COUNT
      LOOP
         BEGIN
            NULL;
         EXCEPTION
            WHEN OTHERS
            THEN
               DBMS_OUTPUT.put_line ('Error occurred : ' || SQLERRM);
         END;
      END LOOP;
   END LOOP;
EXCEPTION
   WHEN OTHERS
   THEN
      DBMS_OUTPUT.put_line ('HERE INSIIDE OTHERS' || SQLERRM);
END;

答案 2 :(得分:-1)

您需要对“”使用打开光标,如下所示:

CREATE OR REPLACE PROCEDURE biq_attendee_report (in_from_date IN DATE)
IS
   l_cur_query          VARCHAR2 (5000) := 'SELECT * from table X where c1='|| in_from_date;
   cur_attendee_data SYS_REFCURSOR; -- JUST DECLARED THE CURSOR
   --TYPE rec_attendee_data IS TABLE OF cur_attendee_data%ROWTYPE
   --   INDEX BY PLS_INTEGER; -- this declaration must be at schema level
   l_cur_attendee_data  rec_attendee_data;
BEGIN
   OPEN cur_attendee_data for l_cur_query; -- OPEN THE CURSOR WITH DYNAMIC QUERY
   ..
   .. -- YOUR CODE AS IT IS
   ..

干杯!