Reputation: 633
Suppose I have three schemas: A
, B
and C
. According this Oracle documentation Syntax for Schema Objects and Parts in SQL Statements the general syntax for referring to an object is:
schema.object
for example:
hr.departments
where hr
is schema (owner) and departments
is object (ie. table).
I need to use different schema names in the SQL query inside PL/SQL block. In other words, I need run exactly the same SQL query, but for different schemas (owners).
I have following PL/SQL code so far:
set serveroutput on size unlimited
set head off
set feedback off
set echo off
DECLARE
i_schema VARCHAR2(100);
BEGIN
FOR r IN (SELECT username FROM dba_users where username in ('A', 'B', 'C') order by 1)
LOOP
i_schema := r.owner || '.' || 'TABLE_NAME';
dbms_output.put_line(chr(10) || 'SCHEMA ===> ' || i_schema );
FOR t IN (SELECT * FROM i_schema order by 2)
LOOP
dbms_output.put_line(RPAD(t.COLUMN1,75) || '|' || t.COLUMN2);
END LOOP;
END LOOP;
END;
/
In the 14th line I tried also different notation:
FOR t IN (SELECT * FROM "r.username".TABLE_NAME ORDER BY 2)
but in the both cases I got below error:
PL/SQL: ORA-00942: table or view does not exist
Thanks in advance for any help received.
Upvotes: 2
Views: 2477
Reputation: 49122
FOR r IN (SELECT username FROM dba_users where username in ('A', 'B', 'C') order by 1)
LOOP
i_schema := r.owner || '.' || 'TABLE_NAME';
dbms_output.put_line(chr(10) || 'SCHEMA ===> ' || i_schema );
FOR t IN (SELECT * FROM i_schema order by 2)
LOOP
dbms_output.put_line(RPAD(t.COLUMN1,75) || '|' || t.COLUMN2);
END LOOP;
END LOOP;
You cannot do that since SQL doesn't allow dynamic table_name, it must be static. In order to achieve the task, you need to (ab)use EXECUTE IMMEDIATE in your PL/SQL block.
Declare a string type variable, prepare the dynamic query and assign it to the string variable.
However, looking at what you are further doing, I don't see any reason to (ab)use EXECUTE IMMEDIATE. Simple use a REFCURSOR.
But I see all this is pointless as you are anyway hardcoding the schema name, so what's the point in writing the PL/SQL code when you could do it in simply 3 SQL queries in pure SQL. It would hardly take less than a minute using a good text editor to replace the schema name in 3 SQLs.
Use UNION ALL:
SELECT RPAD(t.COLUMN1,75) || '|' || t.COLUMN2 FROM A.tablle_name t
UNION ALL
SELECT RPAD(t.COLUMN1,75) || '|' || t.COLUMN2 FROM B.tablle_name t
UNION ALL
SELECT RPAD(t.COLUMN1,75) || '|' || t.COLUMN2 FROM C.tablle_name t
Upvotes: 1