Как передать значение процедуры для выбора оператора в oracle? - PullRequest
0 голосов
/ 30 октября 2019

У меня есть процедура, в которой я вызываю процедуру, используя

exec ot.selector('regions');

Но в этой строке я получаю сообщение об ошибке:

 select * from ot."||p_table_name||";

Итак, процедура, которую я пытался выполнить, была:

 create or replace procedure ot.selector(p_table_name varchar2)
    is
    cursor cur is
    select * from ot."||p_table_name||";
    begin
    for i in cur
    loop
    dbms_output.put_line(i.region_name);
    end loop;
    end;

Я получил ошибку:

Error at line 1
ORA-06550: line 1, column 10:
PLS-00905: object OT.SELECTOR is invalid
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored

Ошибка, которую я получил после выполнения процедуры:

[Warning] ORA-24344: success with compilation error
4/19    PL/SQL: ORA-00903: invalid table name
4/1     PL/SQL: SQL Statement ignored
 (1: 0): Warning: compiled but with compilation errors

Ответы [ 3 ]

2 голосов
/ 30 октября 2019

Вот альтернатива , работающая ;посмотрим, поможет ли это.

Поскольку вы не предоставили тестовый пример, я создаю таблицу REGIONS из DEPT Скотта.

SQL> create table regions as
  2    select deptno, loc as region_name from dept;

Table created.

Функция:

SQL> create or replace procedure selector(p_table_name in varchar2) as
  2    l_str varchar2(200);
  3    rc    sys_refcursor;
  4    l_rc  regions%rowtype;
  5  begin
  6    l_str := 'select * from ' || dbms_assert.sql_object_name(p_table_name);
  7
  8    open rc for l_str;
  9    loop
 10      fetch rc into l_rc;
 11      exit when rc%notfound;
 12      dbms_output.put_line(l_rc.region_name);
 13    end loop;
 14    close rc;
 15  end;
 16  /

Procedure created.

Тестирование:

SQL> set serveroutput on
SQL> exec selector('regions');
NEW YORK
DALLAS
CHICAGO
BOSTON

PL/SQL procedure successfully completed.

SQL>

Если вам интересно, для чего используется DBMS_ASSERT, он здесь для предотвращения внедрения SQL (как упоминалось в комментариях). Если вы передадите что-то недопустимое, вы получите

SQL> exec selector('nonexistent_table');
BEGIN selector('nonexistent_table'); END;

*
ERROR at line 1:
ORA-44002: invalid object name
ORA-06512: at "SYS.DBMS_ASSERT", line 316
ORA-06512: at "SCOTT.SELECTOR", line 6
ORA-06512: at line 1


SQL>
0 голосов
/ 30 октября 2019

Вам нужно использовать dynamic sql для курсора.

create or replace procedure ot.selector(p_table_name varchar2)
    is
    cur sys_refcursor;
    V_sql varchar2(4000);
    v_rec SOME_TABLE%ROWTYPE; -- add variable table name here
    begin
    V_sql := 'select * from ot.'|| p_table_name;
    Open cur for v_sql;
    LOOP
  FETCH CUR INTO v_rec;
   dbms_output.put_line(v_rec.region_name);
  EXIT WHEN v_rec%NOTFOUND;
END LOOP;
    Close cur;
    end;
    end selector;
    /

Ура !!

0 голосов
/ 30 октября 2019

Ваша строка:

 select * from ot."||p_table_name||";

должна выглядеть так:

 select * from ot. || p_table_name;

This ||является объединенным знаком.

Надеюсь, что это поможет ...

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