How to use two cursors for writing in single file? - plsql

Suppose In my procedure, there are two cursors and I have a requirement of writing from both the cursors, 1st line from 1st cursor and 2nd line from 2nd cursor and so on..
How do i achieve it??? I know how to fetch from single curs
or.
Or there is some other way.
Thanks in Advance,
Nitika

You could use two for loop statements, like this:
CREATE OR REPLACE procedure aProc(filter IN number) IS
cursor c1 is select something, something_else from myTable where something = filter;
cursor c2 is select something2, something_else2 from myTable2;
begin
for alias1 in c1 loop
for alias2 in c2 loop
if(alias1.something = 1) then
insert into myTable3 (value1,value2,value3)
values (alias1.something_else,
alias2.something2,
alias2.something_else2);
end if;
end loop;
end loop;
end;
The for loop statement will close the open cursors when no more data is found.

Related

FOR UPDATE CURSOR in teradata?

This is sql block i'm using in Oracle,
Now I need to do the same way in Teradata, Is possible? I want the syntax FOR UPDATE CURSOR in Teradata!
Can you please guide me?
declare
cursor c1 is select * from Employees FOR UPDATE;
a number :=0 ;
begin
for x in c1 loop
a := a +1 ;
update employees set salary = a where current of c1;
end loop;
end;
Updateable cursors are allowed in ANSI-mode sessions only.
The syntax is quite similar:
declare c1 cursor for
select * from Employees FOR UPDATE;
a number :=0 ;
begin
for x in c1 loop
a := a +1 ;
update employees set salary = a where current of c1;
end loop;
end;
But cursors perform really bad in a parallel DBMS like Teradata as they're processed serially, one row after the other.
In almost every case cursors on data can be rewritten set-based (e.g. your example is a simple ROW_NUMBER) and then they perform several orders of magnitude faster.
Maybe you could use this instead?
UPDATE employees
FROM (
SELECT csum(1,1) new_salary, emp_id
FROM employees
) src
set salary=src.new_salary
where employees.emp_id=src.emp_id;

PL/SQL How to iterate and update from an query inside a loop

I don't know how to iterate and update from a query result inside the loop. Is it possible to loop again from the query inside my first loop? Here is my code:
CREATE OR REPLACE PROCEDURE "myTEST" (sp_type in char)
IS
CURSOR c1 IS
SELECT SP_ID FROM CI_SP
WHERE SP_TYPE_CD = sp_type;
sp_id char(10);
item_id_eq CI_SP_EQ.ITEM_ID_EQ%type;
BEGIN
FOR sp_rec in c1
LOOP
DBMS_OUTPUT.PUT_LINE(sp_rec.sp_id);
SELECT ITEM_ID_EQ INTO item_id_eq FROM CI_SP_EQ
WHERE SP_ID = sp_rec.sp_id;
DBMS_OUTPUT.PUT_LINE('item id eq :' || item_id_eq);
-- iterate here for each item_id_eq
-- execute update for each item_id_eq also
END LOOP;
END myTEST;
Instead of looping twice you could just do a join between CI_SP & CI_SP_EQ and get it done in one shot:
CREATE OR REPLACE PROCEDURE "myTEST"(sp_type IN CHAR) IS
BEGIN
FOR item IN (SELECT item_id_eq
FROM ci_sp_eq JOIN ci_sp USING (sp_id)
WHERE sp_type_cd = sp_type) LOOP
-- do your stuff.
NULL;
END LOOP;
END mytest;
I think you wouldn't even need a PL/SQL block, just a simple UPDATE will do, but I don't exactly know what you're trying to do.
Some other comments:
Don't create objects enclosed in "quotes", the object name is now case sensitive. In your case, the compilation will fail because you've created procedure name as "myTEST" and end it with mytest, which Oracle will treat it as "MYTEST" and you'll get compile error because of syntax check fail
Use VARCHAR2 instead of CHAR, CHAR will pad spaces if the input doesn't match the length specifier and will lead to further problems

how to use Trunc(mydate) in a cursor loop

I am new to PL/SQL, and am working on cursor today and got a scenario where I need to get the duplicate transaction type based on the date+amount+cust_id+txn_tpye. Once I get the duplicates I have to use another cursor or just normal loop using the select columns values (date+amount+cust_id+txn_tpye) as a where clause.
Before that I'm just trying to print them if I am getting a value or not, when I tried to print a mydate value getting error. Requesting help from you folks.
SET SERVEROUTPUT ON
declare
CURSOR dup_check
IS
SELECT cust_id,amount,trunc(mydate),transaction_type,COUNT(1)
FROM table_X WHERE trunc(mydate)>='10-OCT-2015'
GROUP BY cust_id,amount,trunc(mydate),transaction_type
HAVING COUNT(1)>1 ;
BEGIN
FOR UP_REC IN dup_check
LOOP
DBMS_OUTPUT.put_line(UP_REC.cust_id||' '||UP_REC.amount||UP_REC.trnasaction_type||**trunc(mydate))**;
END LOOP;
END;
**PLS-00302: component 'mydate' must be declared**
add alias for trunc(mydate) field as below and put the UP_REC.mydate in your dbms_output
SET SERVEROUTPUT ON
declare
CURSOR dup_check
IS
SELECT cust_id,
amount,
trunc(mydate) mydate, /* add an alias here */
transaction_type,
COUNT(1)
FROM table_X WHERE trunc(mydate) >= '10-OCT-2015'
GROUP BY cust_id,amount,trunc(mydate),transaction_type HAVING COUNT(1)>1 ;
BEGIN
FOR UP_REC IN dup_check
LOOP
DBMS_OUTPUT.put_line(UP_REC.cust_id||' '||UP_REC.amount||UP_REC.trnasaction_type||UP_REC.mydate));
END LOOP;
END;

Print Oracle Pl/sql Cursor

Can I directly open and print cursor in begin end block without using loops?
or without reading each column and printing it individually for each row.
If you want to display one record there is no need for looping in your cursor.
If multiple then you need looping in cursor.
Eg In **Test_Project** Table has two column:-
projectid projectname
p2 Programming
p1 Search Engine
p3 Testing
--Below is the code to display one record without using loop
Declare
cprojname varchar2(2000) ;
CURSOR c1
IS
select project_name from test_project WHERE projectid='p1';
BEGIN
OPEN c1;
FETCH c1 INTO cprojname;
if c1%notfound then
cprojname := 'no data';
else
dbms_output.put_line(cprojname);
end if;
CLOSE c1;
END;
o/p:- Search Engine

Reversed cursor for loop plsql

Is there a way to iterate a cursor in a descending order using plsql?
I tried this:
FOR item IN REVERSE items
LOOP
-- do stuff
END LOOP;
but it seems to ignore the reverse key word.
Any suggestions?
It is the SQL clause that determines the order in which the data is traversed, so just apply an appropriate ORDER BY in the query.
DECLARE
cursor c1 is Select * FROM table_1
where (something)
order by (id..whatever you want) DESC; --decrement
v_variable.table%rowtype;
BEGIN
open c1;
fetch c1 into variable; -- will fetch first row...but it will be DESC
close c1;
END;
something like that...
OR
FOR i1 IN c1
LOOP
i1.id...
something...
END LOOP;
OR
FOR i2 IN (Select * FROM table_1
where (something)
order by (id..whatever you want) DESC)
LOOP
--something
END LOOP;
Since you don't have any column to order by, try using order by rownum

Resources