Reputation: 53
I am trying to create a query which is fetching all the project/schema with same table name with UNION ALL. But i am getting the output with UNION ALL in all PROJECT / Schema. i am expecting result which should remove the union all from the last project / schema.
Current Output :
select 'ProjectA' AS "PRJ_ID", EVENT, email,modified_by,modified from ProjectA.event UNION ALL
select 'ProjectB' AS "PRJ_ID", EVENT, email,modified_by,modified from ProjectB.event UNION ALL
select 'ProjectC' AS "PRJ_ID", EVENT, email,modified_by,modified from ProjectC.event UNION ALL
select 'ProjectD' AS "PRJ_ID", EVENT, email,modified_by,modified from ProjectD.event UNION ALL
Expected Output :
select 'ProjectA' AS "PRJ_ID", EVENT, email,modified_by,modified from ProjectA.event UNION ALL
select 'ProjectB' AS "PRJ_ID", EVENT, email,modified_by,modified from ProjectB.event UNION ALL
select 'ProjectC' AS "PRJ_ID", EVENT, email,modified_by,modified from ProjectC.event UNION ALL
select 'ProjectD' AS "PRJ_ID", EVENT, email,modified_by,modified from ProjectD.event ;
Query :
SET SERVEROUTPUT ON
Declare
v_sql varchar2(500);
v_sql2 varchar2(500);
v_prj_id varchar2(4000):='ProjectA,ProjectB,ProjectC,ProjectD';
BEGIN
Dbms_Output.Put_Line('v_prj_id='||v_prj_id);
--
FOR i IN (SELECT trim(regexp_substr(v_prj_id, '[^,]+', 1, LEVEL)) l
FROM dual
CONNECT BY LEVEL <= regexp_count(v_prj_id, ',') + 1
) LOOP
v_sql := 'select '''|| i.l ||''' AS "PRJ_ID", EVENT, email,modified_by,modified from ' || i.l ||
'.Table UNION ALL';
Dbms_Output.Put_Line (v_sql);
--
END LOOP;
EXECUTE IMMEDIATE v_sql ;
v_sql2 := RTRIM (v_sql, 'UNION ALL');
EXECUTE IMMEDIATE v_sql2 ;
Dbms_Output.Put_Line (v_sql2);
END;
/
Upvotes: 1
Views: 772
Reputation: 272446
RTRIM
is not the correct function. It removes all characters from right present in the whitelist so it will trim more than just UNION ALL
.
You could use SUBSTR
and INSTR
:
SELECT str
, RTRIM(str, ' UNION ALL') AS bad
, SUBSTR(str, 1, INSTR(str, ' UNION ALL', -1) - 1) AS good
FROM (
SELECT 'SELECT * FROM FOO.LLANOINU UNION ALL' AS str FROM dual
) x
Upvotes: 1
Reputation: 9083
The code you had is already doing the trim of your string in v_sql
But if you want to execute it all at the same time then you will have to do this:
begin
Declare
v_sql varchar2(500);
v_sql2 varchar2(500);
v_prj_id varchar2(4000):='ProjectA,ProjectB,ProjectC,ProjectD';
BEGIN
FOR i IN (SELECT trim(regexp_substr(v_prj_id, '[^,]+', 1, LEVEL)) l
FROM dual
CONNECT BY LEVEL <= regexp_count(v_prj_id, ',') + 1
) LOOP
v_sql := v_sql || 'select '''|| i.l ||''' AS "PRJ_ID", EVENT, email,modified_by,modified from ' || i.l || '.Table UNION ALL ' || chr(10) ;
END LOOP;
v_sql2 := RTRIM(v_sql, 'UNION ALL ' || chr(10) ) || ';';
Dbms_Output.Put_Line (v_sql2);
END;
end;
/
The v_sql2
will now have the entire desired code.
Here is the DEMO
Upvotes: 0
Reputation: 95101
You'd usually use string manipulation functions, e.g.
v_sql := substr(v_sql, 1, length(v_sql) - length('UNION ALL'));
Upvotes: 0