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
Related
//Program to generate a patient details report based on the input given by the //user
CREATE or REPLACE procedure XX_TEAM18_PROc2
(Admit_date in date,
Bill_amt in number,
action in varchar2)
is
cursor c
is
SELECT P.Patient_name,ph.Symptom_issue Symptom,ph.Consulted_dr Doctor,ph.Diagnosis,ph.Bill_Amount
FROM
XX_Patient_Master_Team18 P,XX_Patient_History_Team18 ph
WHERE
p.Patient_Id=ph.Patient_id
AND
bill_amount action bill_amount;
rec c%rowtype;
cursor c1
is
SELECT P.Patient_name,ph.Symptom_issue Symptom,ph.Consulted_dr Doctor,ph.Diagnosis,ph.Admitted_date Admitted_date
FROM
XX_Patient_Master_Team18 P,XX_Patient_History_Team18 ph
WHERE
p.Patient_Id=ph.Patient_id
AND
Admitted_date action admit_date ;
rec1 c1%rowtype;
begin
open c;
dbms_output.put_line(' records belongs to '||Bill_Amt);
fetch c into rec ;
loop
exit when c%notfound;
dbms_output.put_line(rec.Symptom||' '||rec. Doctor||' '||rec.Diagnosis||' '||rec.bill_Amount);
end loop;
close c;
open c1;
dbms_output.put_line(' records belongs to given '||Admit_date);
fetch c1 into rec1 ;
loop
exit when c1%notfound;
dbms_output.put_line(rec1.Symptom||' '||rec1.Doctor||' '||rec1.Diagnosis||' '||rec1.Admitted_date);
end loop;
close c1;
end ;
You must use dynamic SQL as parameter action cannot be used in a fixed SQL statement within PL/SQL. Parameters can only be used as substitution values, not as column names or operators unless you are using dynamic SQL.
You will need to create a varchar2 variable to hold the SQL statement, then use the DBMS_SQL package to create the cursor. DBMS_SQL has pretty good documentation within it, don't forget to close the cursor when you are done using it.
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;
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
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.
I have 2 tables, Driver and Mechanic and in both table they have a same column Employee#
How do i check both tables using PL/SQL so that an employee in Driver table cannot appear in the Mechanic table by comparing the employee#. And if it happens, it would display a message "Employee# cant be both driver and mechanic!"
I do know that i could simply just compare both table using:
SELECT Employee#
FROM Driver
INTERSECT
SELECT Employee#
FROM Mechanic
But its a requirement for me to use PL/SQL.
I've tried using cursor but i cant seem to make it run through the entire column. Here are my code:
declare
cursor c1 is select employee# from driver;
cursor c2 is select employee# from mechanic;
driverenum number(30);
mechanicenum number(30);
begin
open c1;
fetch c1 into driverenum;
close c1;
open c2;
fetch c2 into mechanicenum;
close c2;
if driverenum in (mechanicenum) then
dbms_output.put_line(driverenum);
end if;
end;
/
If the only requirement is that you use PL/SQL
DECLARE
TYPE emp_nt IS TABLE OF driver.employee#%type;
l_drivers emp_nt;
l_mechanics emp_nt;
l_both emp_nt;
BEGIN
SELECT employee#
BULK COLLECT INTO l_drivers
FROM driver;
SELECT employee#
BULK COLLECT INTO l_mechanics
FROM mechanic;
l_both := l_drivers MULTISET INTERSECT l_mechanics;
FOR i IN 1 .. l_both.count
LOOP
dbms_output.put_line( 'Employee ' || l_both(i) ||
' is employed as both a driver and a mechanic' );
END LOOP;
END;
This approach would potentially occupy quite a bit of space in the PGA if there are a large number of rows in either table. But normally it would be almost as efficient as the SQL solution.