Неправильные # / типы аргументов в параметризованных для Loop Cursor - PullRequest
0 голосов
/ 26 ноября 2018

Я пытаюсь отобразить курсор, введя его во временную таблицу и используя динамический sql.

Моя проблема заключается в вызове фактического курсора в цикле for.Я попытался просто сделать базовое открытие, и это тоже не работает.

Я дважды проверил, что все вызываемые имеют одинаковые типы данных, и вставляю то же количество элементов, которое существует в определении курсора.

SQL> -- /* Given a CallNum
SQL> -- Loop through table waiting and grab all records where pCallnum = callnum
SQL> -- Assign a rank sorted by requested time */
SQL> 
SQL> describe students;
 Name                                                                                                              Null?    Type
 ----------------------------------------------------------------------------------------------------------------- -------- ----------------------------------------------------------------------------
 SNUM                                                                                                              NOT NULL VARCHAR2(3)
 SNAME                                                                                                                      VARCHAR2(10)
 STANDING                                                                                                                   NUMBER(1)
 MAJOR                                                                                                                      VARCHAR2(3)
 GPA                                                                                                                        NUMBER(2,1)
 MAJOR_GPA                                                                                                                  NUMBER(2,1)

SQL> describe waiting;
 Name                                                                                                              Null?    Type
 ----------------------------------------------------------------------------------------------------------------- -------- ----------------------------------------------------------------------------
 SNUM                                                                                                              NOT NULL VARCHAR2(3)
 CALLNUM                                                                                                           NOT NULL NUMBER(5)
 REQUESTEDTIME                                                                                                              DATE

SQL> 
SQL> select * from students;

SNU SNAME        STANDING MAJ        GPA  MAJOR_GPA                                                                                                                                                     
--- ---------- ---------- --- ---------- ----------                                                                                                                                                     
101 Andy                3 IS         2.8        3.2                                                                                                                                                     
102 Betty               2            3.2                                                                                                                                                                
103 Cindy               3 IS         2.5        3.5                                                                                                                                                     
104 David               2 FIN        3.3          3                                                                                                                                                     
105 Ellen               1            2.8                                                                                                                                                                
106 Frank               3 MKT          3          2                                                                                                                                                     
107 John                2 IS           4        2.9                                                                                                                                                     
108 Jacob               1 MKT        3.6        2.9                                                                                                                                                     
109 Heimer              3 MKT        3.1        2.9                                                                                                                                                     
110 Smith               3 IS         3.1        2.9                                                                                                                                                     
111 Jaden               2 MKT          2          1                                                                                                                                                     

SNU SNAME        STANDING MAJ        GPA  MAJOR_GPA                                                                                                                                                     
--- ---------- ---------- --- ---------- ----------                                                                                                                                                     
112 Will                3 MKT        3.7        2.1                                                                                                                                                     
113 Ethan               2 MKT        3.5        3.1                                                                                                                                                     
114 Julia               1 MKT        3.8        3.5                                                                                                                                                     
115 Revy                1 IS         2.5        1.6                                                                                                                                                     
116 Goku                1 MKT        3.7        2.9                                                                                                                                                     
117 Ken                 3            3.1                                                                                                                                                                
118 Natsu               2            3.1                                                                                                                                                                
119 Gerry               2 IS         3.1        2.9                                                                                                                                                     
120 Terry               2 MKT        3.1        2.9                                                                                                                                                     
121 Dee                 3 MKT        3.1        2.9                                                                                                                                                     
SQL> select * from waiting;

SNU    CALLNUM REQUESTED                                                                                                                                                                                
--- ---------- ---------                                                                                                                                                                                
113      10165 05-AUG-13                                                                                                                                                                                
114      10165 06-AUG-13                                                                                                                                                                                
115      10165 07-AUG-13                                                                                                                                                                                
115      10110 07-AUG-13                                                                                                                                                                                
SQL> 
SQL> Create or replace procedure p_Get_Waiting (
  2          p_CallNum number) as
  3  
  4          CURSOR c_Get_Waiting (p_CallNum number)
  5          IS
  6              select
  7              waiting.snum as snum,
  8              sname,
  9              callnum,
 10              requestedtime
 11              from waiting, students
 12              where callnum= p_CallNum and waiting.snum = students.snum;
 13  begin
 14  
 15          -- Create temporary table
 16          EXECUTE IMMEDIATE 'create table waitlistquery (
 17              snum varchar2(3),
 18              sname varchar2(10),
 19              callnum number(5),
 20              requestedtime date)';
 21  
 22          -- For every student in cursor, insert record into temp table
 23          for eachstudent in c_Get_Waiting
 24          LOOP
 25              insert into waitlistquery values (eachstudent.snum, eachstudent.sname, eachstudent.callnum, eachstudent.requestedtime);
 26          end loop;
 27  
 28          -- Display contents of temp table
 29          EXECUTE IMMEDIATE
 30              'select RANK() OVER (PARTITION BY callnum ORDER BY requestedtime) as Rank,
 31              snum,
 32              sname,
 33              callnum,
 34              to_char(requestedtime, ''mm/dd/yyyy hh12am'') as RequestedTime
 35              from waitlistquery';
 36  
 37          -- Drop temp table
 38          EXECUTE IMMEDIATE 'drop table waitlistquery';
 39  
 40  end;
 41  /

Warning: Procedure created with compilation errors.

SQL> 
SQL> 
SQL> 
SQL> show err
Errors for PROCEDURE P_GET_WAITING:

LINE/COL ERROR                                                                                                                                                                                          
-------- -----------------------------------------------------------------                                                                                                                              
23/2     PL/SQL: Statement ignored                                                                                                                                                                      
23/21    PLS-00306: wrong number or types of arguments in call to                                                                                                                                       
         'C_GET_WAITING'  

Моя цель - отобразить результаты, подобные этим:

Ranking SNUM SName RequestedTime
--------------------------------
1       107  John  1/1/2010 10am
2       108  Jake  1/2/2012 12pm

Ответы [ 3 ]

0 голосов
/ 26 ноября 2018

Три вещи:

  1. Когда вы открываете курсор, вам нужно передать параметры, например, for eachstudent in c_Get_Waiting(p_CallNum => p_CallNum)
  2. Если вы динамически создаете таблицу waitlistquery как частьпроцедуры, оператор вставки также должен быть динамическим, а не статическим, как в настоящее время.(Компиляция процедуры не удастся из-за того, что таблица waitlistquery не существует.)
  3. Ваш оператор execute immediate select rank()... ничего не сделает, так как вы не указали никаких переменных для результатов оператора, который будет сохранен.

По второму и третьему пунктам я предполагаю, что это всего лишь учебное упражнение?Потому что если нет, то нет смысла делать то, что ты делаешь;Вы могли бы просто открыть курсор ref, чтобы сделать работу.

Если бы я делал это, я написал бы функцию, которая возвращала курсор ref, например,

CREATE OR REPLACE FUNCTION f_get_waiting(p_callnum NUMBER) RETURN SYS_REFCURSOR IS
  get_waiting_rcur SYS_REFCURSOR;
BEGIN
  OPEN get_waiting_rcur FOR
    SELECT rank() over(PARTITION BY callnum ORDER BY requestedtime) AS rank,
         waiting.snum,
         sname,
         callnum,
         to_char(requestedtime, 'mm/dd/yyyy hh12am') AS requestedtime
    FROM   waiting
    INNER  JOIN students
    ON     waiting.snum = students.snum;

  RETURN get_waiting_rcur;
END f_get_waiting;
/

, помня, что кодвызов этой функции должен обрабатывать закрытие курсора, как только он сделает свое дело.

Это предполагает, что данные будут передаваться за пределы базы данных (например, передаваться в вызывающий модуль C #, записываться вфайл и т. д.);если вы собираетесь использовать данные для выполнения каких-либо действий, таких как вставка или обновление таблицы, я постараюсь выполнить эту работу в одном выражении DML, если это возможно.

0 голосов
/ 26 ноября 2018

Как только вы упростите вашу процедуру с помощью курсора с одним оператором, используя правильные объединения, вы можете отобразить вывод, используя переменную связывания REFCURSOR и команду печати SQL * Plus.

Модифицированная процедура

CREATE OR replace PROCEDURE p_get_waiting (
     p_callnum NUMBER,
     c_get_waiting OUT SYS_REFCURSOR
) AS 
BEGIN
 OPEN c_get_waiting FOR
   SELECT RANK() OVER(
     PARTITION BY w.callnum
     ORDER BY requestedtime
   ) AS rank,
       s.snum,
       s.sname,
       w.callnum,
       TO_CHAR(w.requestedtime,'mm/dd/yyyy hh12am') AS requestedtime
  FROM waiting w
  JOIN students s ON w.snum = s.snum
 WHERE w.callnum = p_callnum;

END;
/

Выполнение

VARIABLE get_waiting REFCURSOR
EXEC p_get_waiting ( 10165,:get_waiting)

PRINT get_waiting

Результат

PL/SQL procedure successfully completed.



      RANK       SNUM SNAME     CALLNUM REQUESTEDTIME  
---------- ---------- ------ ---------- ---------------
         1        113 Ethan       10165 08/05/2013 12AM
         2        114 Julia       10165 08/06/2013 12AM
         3        115 Revy        10165 08/07/2013 12AM
0 голосов
/ 26 ноября 2018

вам нужно объявить переменную для каждого столбца, так как вы не можете использовать tablename%ROWTYPE для каждого студента, поскольку он объединяет две таблицы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...