通过PL / SQL循环获取ORA-00904无效标识符

时间:2019-04-02 06:07:34

标签: sql oracle plsql

当尝试使用表列表作为针对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的值,该值与dba_segments的segment_nam e列相同。 / p>

有人可以帮忙吗?

1 个答案:

答案 0 :(得分:1)

这是您当前拥有的:

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语句。

但是,如果您

  • 删除数据库链接名称前面的空间
  • 将单引号应用于segment_name

您会得到一些可行的方法:

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