Image I have the following queries in a package:
SELECT col1 FROM table WHERE id=5;
SELECT otherCol FROM otherTable WHERE id=78;
I want to return one record with two columns containing the values 'col1' and 'otherCol'.
In my case, I'd have lots of subqueries and DECODE statements so for readability I want to split it up into different queries something ala:
var result = {}; -- Unfortunately PL/SQL doesn't cope very well with JavaScript.
SELECT col1 INTO someVar FROM table WHERE id=5;
IF someVar = 1 THEN
result.X = SomeQuery();
ELSE
result.X = SomeEntirelyDifferentQuery();
END IF;
SELECT col INTO result.Z FROM tab1;
SELECT coz INTO result.Q FROM tab2;
IF result.Z IS NULL THEN
result.B = Query1();
ELSE
result.B = Query2();
END IF;
... and so on.
RETURN result;
So basically I want to create an "empty record" and then based on some conditions assign different values to columns in that record
This could be solved with DECODE but the resulting query is both not very readable nor very performant.
You have to define an object type the function can return.
CREATE OR REPLACE TYPE fancy_function_result_row as object
(
X number,
Y number,
Q date,
Z varchar2(30)
);
create or replace function fancy_function(...)
return fancy_function_result_row
as
my_record fancy_function_result_row := fancy_function_result_row();
begin
my_record.X := 1;
etc...
end;
If you want to insert the record into a table, it might be a lot easier simply defining a rowtype of that table.
declare
row_my_table my_table%rowtype;
begin
row_my_table.X := etc..
insert into my_table values row_my_table;
end;
--To concat the values 'col1' and 'otherCol':
with r1 as (select col1 from table where id=5),
r2 as (select otherCol from otherTable WHERE id=78),
select r1.col1 || ' concat with ' || r2.othercol from r1, r2
--To do this condition using DECODE:
SELECT DECODE (col1,
1,
(SELECT 1 FROM query1),
(SELECT 1 FROM DifferentQuery)
)
FROM TABLE
Related
I'm trying to recover a bunch of data in the form of a table
I created the type as follows
create or replace type Structure_type AS OBJECT
(
SWID Integer,
structure_TYPESid Integer,
MAIN_BRANCHid Integer,
Organizational_structureid Integer,
Administrative_structureid Integer,
structure_tree NVarchar2(1000),
structure_NO NVarchar2(500),
Structure_level Integer
)
and create table of type
create or replace type Structure_table_type as table of Structure_type;
Then I created a data retrieval function like the following
create or replace function Get_Who_Runs_Stores
(OoA char) return Structure_table_type is
FunctionResult Structure_table_type;
begin
FunctionResult :=Structure_table_type();
CASE UPPER(OoA)
WHEN 'A' then
FOR x_Structure IN (select b.administrative_tree
from warehouse w join branches_costcenter b on (w.w_branch=b.swid))
LOOP
select
b.swid SWID,
b.costcenter_type_id structure_TYPESid ,
b.main_branch_id MAIN_BRANCHid,
b.direct_branch_cost_center_id Organizational_structureid,
b.direct_adminstration_parent_id Administrative_structureid,
b.administrative_tree structure_tree,
b.administrative_no structure_NO,
b.administrative_level Structure_level
into FunctionResult
from branches_costcenter b
where
x_Structure.Administrative_Tree like '%-' || b.swid || '-%';
end loop;
WHEN 'O' then
FOR x_Structure IN (select b.organizationa_tree
from warehouse w join branches_costcenter b on (w.w_branch=b.swid))
LOOP
select b.swid SWID,b.costcenter_type_id structure_TYPESid ,
b.main_branch_id MAIN_BRANCHid, b.direct_branch_cost_center_id Organizational_structureid,
b.direct_adminstration_parent_id Administrative_structureid,b.organizationa_tree structure_tree,
b.organizationa_no structure_NO ,b.organizationa_level Structure_level into FunctionResult
from branches_costcenter b
where
x_Structure.Organizationa_Tree like '%-' || b.swid || '-%';
end loop;
else
return null;
end case ;
return(FunctionResult);
end Get_Who_Runs_Stores;
Error: PL/SQL: ORA-00947: not enough values
Line: 45
Text: from branches_costcenter b
I tried the SQL sentence and it works correctly
select
b.swid SWID,
b.costcenter_type_id structure_TYPESid ,
b.main_branch_id MAIN_BRANCHid,
b.direct_branch_cost_center_id Organizational_structureid,
b.direct_adminstration_parent_id Administrative_structureid,
b.administrative_tree structure_tree,
b.administrative_no structure_NO,
b.administrative_level Structure_level
from branches_costcenter b
where
'-1-2-3-12-24-' like '%-' || b.swid || '-%';
How can I get the required data and what is the best way to do so?
Do I have to define all that I want to retrieve data from the function in the form of a table?
Sorry, my English is bad
Your function will be horrible slow. Apart from that the issue is following: If you run
FOR x_Structure IN (select ...) LOOP
SELECT ...
INTO FunctionResult
FROM ...;
END LOOP;
RETURN FunctionResult;
then you insert row by row into FunctionResult. At the end you return only the last row from your select, all other rows have been overwritten.
Try
SELECT ...
BULK COLLECT INTO FunctionResult
FROM ...;
You could also insert row by row, but this is much slower:
FOR x_Structure IN (select ...) LOOP
FunctionResult.Extend();
SELECT ...
INTO FunctionResult(FunctionResult.LAST)
FROM ...;
END LOOP;
You cannot select into FunctionResult directly. The statement must be like this:
SELECT Structure_type(b.swid, b.costcenter_type_id, ..., b.administrative_level)
BULK COLLECT INTO FunctionResult
FROM ...
Update
Depending on your client it might be easier and better to return a RefCursor. Would be like this:
create or replace function Get_Who_Runs_Stores(OoA char) return SYS_REFCURSOR is
res SYS_REFCURSOR;
begin
OPEN res FOR
SELECT b.swid SWID,b.costcenter_type_id structure_TYPESid, ...
FROM ...
WHERE ...;
RETURN res;
end;
You don't have to create any TABLE or OBJECT type, just return the RefCursor.
I have 2000 numbers (Uniq Primary Key). I want to get contact information of numbers. My database is Oracle.
I use IN(bla,bla) in my query. It works slow because of this.
Example My Query:
SELECT p.*,t.*
FROM PERSONEL p
LEFT OUTER JOIN CODE_TITLE t ON t.Id = p.TitleId
WHERE ID IN(1,2,....,2000)
When the query runs, it takes about 10-12 seconds.
Is there a method to use instead of IN(bla, bla)? Can you explain with an example ?
Put your numbers (or whatever they really are) in a table. Let's call it LIST_TABLE. Then
SELECT p.*,t.*
FROM PERSONEL p
LEFT OUTER JOIN CODE_TITLE t ON t.Id = p.TitleId
WHERE ID IN(select list_id from list_table)
The type of table for LIST_TABLE (normal, GTT, external) will depend on where the values come from and your best mechanism for loading them.
You can use xmltable('1 to 2000') as a derived table in order to generate integer set starting form 1 upto 2000, incrementing by 1 :
SELECT p.*,t.*
FROM PERSONEL p
LEFT JOIN CODE_TITLE t ON t.Id = p.TitleId
WHERE Id IN ( SELECT TO_NUMBER(column_value) FROM xmltable('1 to 2000') )
P.S. indeed using WHERE ID BETWEEN 1 AND 2000 would suffice with index created on CODE_TITLE.ID in order to increase the query performance.
create or replace type myTcType as table of number(16,0);
create or replace function in_list(p_string in varchar2) return myTcType
as
l_data myTcType := myTcType();
l_string long default p_string || ',';
l_n number;
begin
loop
exit when l_string is null;
l_data.extend;
l_n := instr(l_string, ',');
l_data(l_data.count) := substr(l_string,1,l_n-1);
l_string := substr(l_string,l_n+1);
end loop;
return l_data;
end;
select * from table(cast(in_list('1,2,3,4,5') as myTcType));
I need to update exactly same columns of two tables How do update both through single query, currently I am doing like below;
Update Table1 set col1=val1, col2=val2, col3=val3 where Id in=
(select tt.cId from anotherTable at inner join thirdTable tt on at.id = tt.id)
Update Table2 set col1=val1, col2=val2, col3=val3 where Id in=
(select tt.cId from anotherTable at inner join thirdTable tt on at.id = tt.id)
only change is Table name is different.
P.S. Above is the sample query, original query has several lines of code. I have to minimize the text due to column size, I cannot change the existing size of column
How do I perform this at once or in single query in oracle, both tables are exactly same and also update values are same.
Is there anything like this;
update Table1 t1, Table2 t2 set t1.col1 = val1, t2.col1 = val1, t1.col2 = val2, t2.col2 = val2...
I don't think it is possible in Oracle to update two different target tables in a single statement. But, you can do both updates within a single logical transaction:
START TRANSACTION;
UPDATE 1...
UPDATE 2...
COMMIT;
We cannot update two table in simultaneously so in this case, we can use PL SQL
varchar2 data type to hold the value of update as in pl sql varchar is limit is 32,767 bytes.Hold updated value in a variable and use that varibale to update tables.
A sample code.
desc temp;
Name Null? Type
----------- ----- --------------
ID NUMBER
MDATE DATE
ITEM CHAR(3)
DESCRIPTION VARCHAR2(4000)
set SERVEROUTPUT ON
DECLARE
v_text_update VARCHAR2(32767);
v_query1 VARCHAR2(32767);
v_query2 VARCHAR2(32767);
v_query3 VARCHAR2(32767);
BEGIN
v_query1 := 'update temp set description=' || chr(39);
v_text_update := 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
;
v_query2 := chr(39)
|| ' where id=11';
v_query3 := v_query1
|| v_text_update
|| v_query2;
dbms_output.put_line(v_query3);
EXECUTE IMMEDIATE v_query3; -- OR
EXECUTE IMMEDIATE v_query1
|| v_text_update
|| v_query2; ----instead of storing value in v_query3 you can use
concatenation directly.
END;
/
I hope it helps and let me know if I miss something.
In my stored procedure I want if the value of col1 & col2 match with employee then insert the unique record of the employee. If not found then match the value of col1, col2 & col3 with employee match then insert the value. If also not found while match all these column then insert the record by using another column.
Also one more thing that I want find list of values like emp_id by passing the another column value and if a single record can not match then make emp_id as NULL.
Also I want to insert one record at a time after match with txt along with others table having data like emp.
create or replace procedure sp_ex
as
cursor c1 is select * from txt%rowtype;
v_col1 tbl1.col1%type;
type record is table of txt%rowtype; --Staging table
v_rc record := record();
begin
open c1;
loop
fetch c1 bulk collect into v_rc limit 1000;
loop
for i in 1..v_rc.count loop
select col1 into v_col1 from tbl1
where exists (select col1 from tbl1 where tbl1.col1 = emp.col1);
insert
when txt.col1 = emp.col1 and txt.col2 = stud.col2 then
into main_table(columns) values(v_rc(i).col1, ...)
when txt.col1 = emp.col1 and txt.col2 = stud.col2 and txt.col3 = stud.col3 then
into main_table(columns) values(v_rc(i).col1, ...)
else
insert into main_table(columns) values(v_rc(i).col1, ...)
select * from txt;
end loop;
exit when v_rc.count < limit;
end loop;
close c1;
end sp_ex;
While emp, stud are the different tables where i have to match with txt.
In that Stored Proc I want to load data from txt into main_table in batch processing mode. The data would be match one by one record then after if matching condition match then load into the main table. How can i create the stored proc so that the Data will load by above logic one by one in batch processing. Could you please help me to share your idea. Thanks
The syntax seems to be rather mixed up.
Multi-table insert is like this:
insert all -- alternatively, "insert first"
when dummy = 'X' then
into demo (id) values (1)
when dummy = 'Y' then
into demo (id) values (2)
else
into demo (id) values (3)
select * from dual;
Or perhaps you wanted a PL/SQL case statement:
case
when dummy = 'X' then
insert into demo (id) values (1);
when dummy = 'Y' then
insert into demo (id) values (2);
else
insert into demo (id) values (3);
end case;
Instead there seems to be a mixture of the two.
Also there is a missing end loop, and an implicit cursor (select col1 from tbl1) with no into clause.
I have created one Stored Procedure. In that Stored Proc I want if the value of col1 & col2 match with employee then insert the unique record of the employee. If not found then match the value of col1, col2 & col3 with employee match then insert the value. If also not found while match all these column then insert the record by using another column.
Also one more thing that i want find list of values like emp_id by passing the another column value and if a single record can not match then make emp_id as NULL.
create or replace procedure sp_ex
AS
empID_in varchar2(10);
fname_in varchar2(20);
lname_in varchar2(30);
---------
type record is ref cursor return txt%rowtype; --Staging table
v_rc record;
rc rc%rowtype;
begin
open v_rc for select * from txt;
loop
fetch v_rc into rc;
exit when v_rc%notfound;
loop
select col1 from tbl1
Where EXISTS (select col1 from tbl1 where tbl1.col1 = rc.col1);
IF txt.col1 = rc.col1 AND txt.col2 = rc.col2 THEN
insert into main_table select distinct * from txt where txt.col2 = rc.col2;
ELSIF txt.col1 = rc.col1 AND txt.col2 = rc.col2 AND txt.col3 = rc.col3 THEN
insert into main_table select distinct * from txt where txt.col2 = rc.col2;
ELSE
insert into main_table select * from txt where txt.col4 = rc.col4;
end if;
end loop;
close v_rc;
end sp_ex;
I found an error while compile this Store Procedure PLS-00357: Table,View Or Sequence reference not allowed in this context. How to resolve this issue and how to insert value from staging to main table while using CASE or IF ELSIF statement. Could you please help me so that i can compile the Stored Proc.
Since I don't have your database to work with it's difficult to be 100% certain, but to my eye the line which reads
rc rc%rowtype;
should say
rc txt%rowtype;
You've defined the cursor v_rc as returning txt%rowtype, and your SQL statement used with this cursor is select * from txt, but that data type is at odds with the definition of rc. Thus, it appears you need to change rc as shown.
It also looks like the LOOP statement which comes immediately after exit when v_rc%notfound; should be removed, as there's nothing after that which would terminate that loop.
In addition, you have many references to columns in the txt table, e.g. IF txt.col1 = rc.col1. You can't refer to values in a table in this manner. I'm not quite sure what you're trying to do here so I can't really suggest anything.
Also, the statement
select col1 from tbl1
Where EXISTS (select col1 from tbl1 where tbl1.col1 = rc.col1);
is selecting a column from the database, but isn't putting it anywhere. This should be either a singleton SELECT (SELECT..INTO) or a cursor.
One more thing: you can't use distinct *. You need to use a column list with distinct.
Perhaps the following would be close to what you're trying to do:
create or replace procedure sp_ex
AS
begin
FOR rc IN (SELECT * FROM TXT)
LOOP
FOR t1 IN (SELECT *
FROM TBL1
WHERE TBL1.COL1 = rc.COL1)
LOOP
IF t1.COL1 = rc.COL1 AND
t1.COL2 = rc.COL2
THEN
insert into main_table
select *
from txt
where txt.col2 = rc.col2;
ELSIF t1.col1 = rc.col1 AND
t1.col2 = rc.col2 AND
t1.col3 = rc.col3
THEN
insert into main_table
select *
from txt
where txt.col2 = rc.col2;
ELSE
insert into main_table
select *
from txt
where txt.col4 = rc.col4;
END IF;
END LOOP; -- t1
END LOOP; -- rc
end sp_ex;
Best of luck.