Получение неверного идентификатора ORA-00904 с помощью цикла pl / sql - PullRequest
0 голосов
/ 02 апреля 2019

При попытке использовать список таблиц в качестве имен сегментов для запроса к dba_segments я получаю ORA-00904: invalid identifier error.

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

declare
v_sql_c1 varchar2 (1000);
V_dblink varchar2(100) := 'DB1';

begin

for c1 in (select * from TABLE_LIST)
       loop
execute immediate' select /*+parallel*/ bytes from dba_extents '|| '@' ||V_dblink ||' a '
||' where segment_name ='||
c1.table_name
into v_sql_c1;
dbms_output.put_line(v_sql_c1);
end loop;
end;
/

В идеале я хотел бы сообщить об этом значении 'bytes' в каждой строке в столбце table_name table_list, что совпадает со столбцом segment_nam e в dba_segments.

Может кто-нибудь помочь?

1 Ответ

1 голос
/ 02 апреля 2019

Вот что у вас есть:

SQL> CREATE TABLE table_list (table_name VARCHAR2 (20));

Table created.

SQL> INSERT INTO table_list  VALUES ('EMP');

1 row created.

SQL> set serveroutput on;
SQL> DECLARE
  2     v_sql_c1  VARCHAR2 (1000);
  3     V_dblink  VARCHAR2 (100) := 'DB1';
  4     v_sql     VARCHAR2 (1000);
  5  BEGIN
  6     FOR c1 IN (SELECT * FROM TABLE_LIST)
  7     LOOP
  8        v_sql :=
  9              ' select /*+parallel*/ bytes from dba_extents '
 10           || '@'
 11           || V_dblink
 12           || ' a '
 13           || ' where segment_name ='
 14           || c1.table_name;
 15
 16        DBMS_OUTPUT.put_line (v_sql);
 17
 18  --      EXECUTE IMMEDIATE v_sql INTO v_sql_c1;
 19
 20        DBMS_OUTPUT.put_line (v_sql_c1);
 21     END LOOP;
 22  END;
 23  /
select /*+parallel*/ bytes from dba_extents @DB1 a  where segment_name =EMP

PL/SQL procedure successfully completed.

SQL>

См? Недопустимый оператор SELECT.

Но, если вы

  • удалить пробел перед именем ссылки на базу данных
  • применить одинарные кавычки к сегменту_имя

вы получите что-то, что может работать:

SQL> DECLARE
  2     v_sql_c1  VARCHAR2 (1000);
  3     V_dblink  VARCHAR2 (100) := 'DB1';
  4     v_sql     VARCHAR2 (1000);
  5  BEGIN
  6     FOR c1 IN (SELECT * FROM TABLE_LIST)
  7     LOOP
  8        v_sql :=
  9              ' select /*+parallel*/ bytes from dba_extents'
 10           || '@'
 11           || V_dblink
 12           || ' a '
 13           || ' where segment_name ='
 14           || CHR (39)
 15           || c1.table_name
 16           || CHR (39);
 17
 18        DBMS_OUTPUT.put_line (v_sql);
 19
 20        --      EXECUTE IMMEDIATE v_sql INTO v_sql_c1;
 21
 22        DBMS_OUTPUT.put_line (v_sql_c1);
 23     END LOOP;
 24  END;
 25  /
select /*+parallel*/ bytes from dba_extents@DB1 a  where segment_name ='EMP'

PL/SQL procedure successfully completed.

SQL>

По сути, вы должны всегда отображать оператор, который будет работать как динамический SQL, убедиться, что он правильный, а затем на самом деле EXECUTE IMMEDIATE его.

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