ORA-00932: противоречивые типы данных: ожидается - получил - - PullRequest
8 голосов
/ 04 января 2011

Я использую Oracle (10g.2) в качестве программиста PHP почти 3 года, но когда я дал задание, я впервые попытался использовать ref-курсоры и типы коллекций. И я Я искал в Интернете, когда столкнулся с проблемами, и эта ошибка ora-00932 действительно поразила меня. Мне нужна помощь от старой руки.

Вот то, с чем я столкнулся, Я хочу выбрать строки из таблицы и поместить их в указатель ссылки, а затем, используя тип записи, собрать их в ассоциативный массив. И снова из этого ассоциативного массива создайте курсор ref. Не спрашивайте меня, почему, я пишу такой сложный код, потому что он мне нужен для более сложного назначения. Возможно, я вас смущаю, поэтому позвольте показать вам мои коды.

У меня есть 2 типа, определенных на вкладке типов в жабе. Одним из них является тип объекта:

CREATE OR REPLACE
TYPE R_TYPE AS OBJECT(sqn number,firstname VARCHAR2(30), lastname VARCHAR2(30));

Другим типом коллекции является тип объекта, созданный выше:

CREATE OR REPLACE
TYPE tr_type AS TABLE OF r_type;

Затем я создаю пакет:

CREATE OR REPLACE PACKAGE MYPACK_PKG IS
TYPE MY_REF_CURSOR IS REF CURSOR;
PROCEDURE MY_PROC(r_cursor OUT MY_REF_CURSOR);
END MYPACK_PKG;

Корпус:

CREATE OR REPLACE PACKAGE BODY MYPACK_PKG AS
 PROCEDURE MY_PROC(r_cursor OUT MY_REF_CURSOR) AS
  rcur MYPACK_PKG.MY_REF_CURSOR;
  sql_stmt VARCHAR2(1000);
  l_rarray   tr_type := tr_type();
                l_rec r_type;

 BEGIN
     sql_stmt :=  'SELECT 1,e.first_name,e.last_name  FROM hr.employees e ';
     OPEN rcur FOR sql_stmt;
     LOOP
       fetch rcur into l_rec;
                  exit when rcur%notfound;
     l_rarray := tr_type( l_rec );
     END LOOP;
   CLOSE rcur;
    --OPEN r_cursor FOR SELECT * FROM TABLE(cast(l_rarray as tr_type) );


END MY_PROC;
END MYPACK_PKG;

Я закомментировал последнюю строку, в которой я открываю реф курсор. Потому что это вызывает другую ошибку, когда я запускаю процедуру в редакторе SQL Toad, и это второй вопрос, который я задам. И, наконец, я запускаю код в жабе:

variable r refcursor
declare
r_out MYPACK_PKG.MY_REF_CURSOR;
begin
MYPACK_PKG.MY_PROC(r_out);
:r := r_out;
end;
print :r

Там я получаю ошибку ora-00932.

1 Ответ

6 голосов
/ 04 января 2011

То, как вы используете REF CURSOR, необычно. Это будет стандартный способ их использования:

SQL> CREATE OR REPLACE PACKAGE BODY MYPACK_PKG AS
  2     PROCEDURE MY_PROC(r_cursor OUT MY_REF_CURSOR) AS
  3     BEGIN
  4        OPEN r_cursor FOR SELECT e.empno,e.ENAME,null  FROM scott.emp e;
  5     END MY_PROC;
  6  END MYPACK_PKG;
  7  /

Corps de package crÚÚ.

SQL> VARIABLE r REFCURSOR
SQL> BEGIN
  2     MYPACK_PKG.MY_PROC(:r);
  3  END;
  4  /

ProcÚdure PL/SQL terminÚe avec succÞs.

SQL> PRINT :r

     EMPNO ENAME      N
---------- ---------- -
      7369 SMITH
      7499 ALLEN
      7521 WARD
      7566 JONES
      7654 MARTIN
      [...]

14 ligne(s) sÚlectionnÚe(s).

Я не уверен, что вы пытаетесь выполнить здесь: вы извлекаете курсор ref внутри процедуры, а затем возвращаете другой курсор ref, который будет иметь те же данные. Я не думаю, что вообще нужно извлекать курсор в процедуре. Пусть вызывающее приложение выполняет выборку (здесь выборка выполняется print).

Обновление: почему вы получаете бесполезное сообщение об ошибке?

Вы используете динамически открытый курсор, и я думаю, что это одна из причин, по которой вы получаете бесполезное сообщение об ошибке. Если мы используем фиксированный SQL, сообщение об ошибке будет другим:

SQL> CREATE OR REPLACE PACKAGE BODY MYPACK_PKG AS
  2     PROCEDURE MY_PROC(r_cursor OUT MY_REF_CURSOR) AS
  3        TYPE type_rec IS RECORD (qn number,
  4                                 firstname VARCHAR2(30),
  5                                 lastname VARCHAR2(30));
  6        lt_record type_rec; /* Record type */
  7        lt_object r_type; /* SQL Object type */
  8     BEGIN
  9        OPEN r_cursor FOR SELECT e.empno,e.ENAME,null  FROM scott.emp e;
 10        FETCH r_cursor INTO lt_record; /* This will work */
 11        FETCH r_cursor INTO lt_object; /* This won't work in 10.2 */
 12     END MY_PROC;
 13  END MYPACK_PKG;
 14  /

Package body created

SQL> VARIABLE r REFCURSOR
SQL> BEGIN
  2     MYPACK_PKG.MY_PROC(:r);
  3  END;
  4  /
BEGIN
*
ERREUR Ó la ligne 1 :
ORA-06504: PL/SQL: Return types of Result Set variables or query do not match
ORA-06512: at "APPS.MYPACK_PKG", line 11
ORA-06512: at line 2

Я описал, что в настоящее время в 10.2 вы можете извлечь курсор в запись PLSQL, но не в объекте SQL.

Обновление: относительно PLS-00306: неверное число или типы аргументов

l_rarray - это NESTED TABLE, его нужно инициализировать, а затем расширить, чтобы иметь возможность хранить элементы. Например:

SQL> CREATE OR REPLACE PACKAGE BODY MYPACK_PKG AS
  2     PROCEDURE MY_PROC(r_cursor OUT MY_REF_CURSOR) AS
  3        lr_array tr_type := tr_type(); /* SQL Array */
  4     BEGIN
  5        FOR cc IN (SELECT e.empno, e.ENAME, NULL lastname
  6                     FROM scott.emp e) LOOP
  7           lr_array.extend;
  8           lr_array(lr_array.count) := r_type(cc.empno,
  9                                              cc.ename,
 10                                              cc.lastname);
 11           /* Here you can do additional procedural work on lr_array */
 12        END LOOP;
 13        /* then return the result set */
 14        OPEN r_cursor FOR SELECT * FROM TABLE (lr_array);
 15     END MY_PROC;
 16  END MYPACK_PKG;
 17  /

Corps de package crÚÚ.

SQL> print r

       SQN FIRSTNAME                      LASTNAME
---------- ------------------------------ -----------
      7369 SMITH                          
      7499 ALLEN                          
      7521 WARD                           
      [...]

14 ligne(s) sÚlectionnÚe(s).

Для дальнейшего чтения вы можете просмотреть документацию для PL / SQL коллекций и записей .

...