Вот что у вас есть:
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
его.