Oracle PLSQL refcursor% ROWTYPE объявление типа этого выражения неполное или некорректное - PullRequest
1 голос
/ 17 июня 2019

Я хочу назначить переменную курсора в коде PL / SQL и затем извлечь строку из этого. Когда я объявил курсор явно, он работает.

DECLARE
cursor c1 is SELECT * from acme;
row1 c1%ROWTYPE;

но когда я использую код для назначения курсора, например, Oracle PLSQL устанавливает курсор из переменной так:

  c1 sys_refcursor;
  r1 c1%ROWTYPE;

Я получаю ошибку

объявление типа этого выражения неполное или уродливы

запись только r1 %ROWTYPE также приводит к ошибке.

В соответствии с общим использованием переменных, объясненных, например, здесь Как объявить переменную и использовать ее в том же сценарии Oracle SQL? Я пробовал:

SET SERVEROUTPUT ON
DECLARE
  c1 sys_refcursor;
BEGIN
    open c1 for 'SELECT * FROM foo';
    declare r1 c1%ROWTYPE;
    begin
        fetch c1 into r1; 
    end;
    DBMS_OUTPUT.PUT_LINE('FOO');    
    close c1;
END;

и снова получил the declaration of the type of this expression is incomplete or malformed

Как мне объявить переменную типа строки в моем случае? Oracle 11g.
Постскриптум Обходной путь может быть к fetch c1 into v_empno, v_ename, ect объявлению нескольких переменных, но есть ли способ использовать тип строки один?

Ответы [ 2 ]

1 голос
/ 17 июня 2019

Если вы хотите отобразить результат любого запроса, вы можете использовать эту стандартную процедуру, аналогичную описанной в этой статье AskTOM

create or replace procedure return_result( l_query varchar2 )
   is
       l_theCursor     integer default dbms_sql.open_cursor;
       l_columnValue   varchar2(4000);
       l_status        integer;
       l_colCnt        number := 0;
       l_separator     varchar2(1);
       l_descTbl       dbms_sql.desc_tab;
   begin
       dbms_sql.parse(  l_theCursor,  l_query, dbms_sql.native );

       dbms_sql.describe_columns( l_theCursor, l_colCnt, l_descTbl );


           l_separator := '';
           for i in 1 .. l_colCnt loop
               dbms_output.put( l_separator || l_descTbl(i).col_name );
               l_separator := ',';
           end loop;
           dbms_output.put_line('');

        for i in 1 .. l_colCnt loop
           dbms_sql.define_column( l_theCursor, i, l_columnValue, 4000 );
       end loop;
       l_status := dbms_sql.execute(l_theCursor);

       while ( dbms_sql.fetch_rows(l_theCursor) > 0 ) loop
           l_separator := '';
           for i in 1 .. l_colCnt loop
               dbms_sql.column_value( l_theCursor, i, l_columnValue );
               dbms_output.put( l_separator || l_columnValue );
               l_separator := ',';
           end loop;
           dbms_output.new_line;
       end loop;
       dbms_sql.close_cursor(l_theCursor);
   end;
 /

Передайте любой запрос этой процедуре, чтобы получить результат.

set serveroutput on
set feedback off
set sqlformat ansiconsole
set pages 0
BEGIN
return_result('select e.employee_id,e.first_name,e.salary,
          d.department_name from 
          employees e join 
  departments d on e.department_id= d.department_id');
END;
/

Результат

EMPLOYEE_ID,FIRST_NAME,SALARY,DEPARTMENT_NAME
200,Jennifer,4400,Administration
201,Michael,13000,Marketing
202,Pat,6000,Marketing
114,Den,11000,Purchasing

Примечание : Oracle 12c предоставляет DBMS_SQL.RETURN_RESULT, с помощью которого эта процедура может быть легко реализована.

0 голосов
/ 17 июня 2019

Как то так?

SQL> set serveroutput on
SQL>
SQL> declare
  2    c1 sys_refcursor;
  3    r1 dept%rowtype;                      --> this
  4  begin
  5    open c1 for 'select * from dept';
  6    fetch c1 into r1;
  7    dbms_output.put_line(r1.dname);
  8  end;
  9  /
ACCOUNTING

PL/SQL procedure successfully completed.

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