run a procedure in while loop - sql

I have this stored proc :
begin
Sp_Racf_Test;
end;
I don't want to edit anything inside this proc.
I want to run a loop statement where it should run the proc Sp_Racf_Test until
a column RACF_ID in table tem_joins is null. I mean the loop of running stored procedure should stop when there are no null values in the column RACF_ID of table tem_joins.
Please suggest a query

Try the below one:
declare
v_count number := 1;
begin
while v_count > 0 loop
Select count(*) into v_count from tem_joins
where racf_id is null;
if v_count > 0 then
Sp_Racf_Test;
else
exit;
end if;
end loop;
end;

Related

Cheking if an entry exists in another table using cursor

My task is to insert entries from one table to another by using parametrized cursor. Here's what I have tried
DECLARE
oldroll NUMBER;
newroll NUMBER;
oldname VARCHAR2(25);
newname VARCHAR2(25);
CURSOR c_orollcall (roll_no NUMBER,name VARCHAR2) IS SELECT * FROM o_rollcall;
PROCEDURE procedure_2;
PROCEDURE procedure_2 AS
BEGIN
OPEN c_orollcall;
LOOP
FETCH c_orollcall INTO oldroll ,oldname;
SET #count = 0;
SELECT roll_no INTO #count FROM n_rollcall WHERE EXISTS (oldroll);
IF #count>0 THEN
DBMS_OUTPUT.PUT_LINE('ENTRY ALREADY EXISTS');
ELSE
INSERT INTO n_rollcall VALUES (oldroll,oldname);
END IF;
EXIT WHEN c_orollcall%NOTFOUND;
END LOOP;
CLOSE c_orollcall;
END;
/
BEGIN
procedure_2;
END
/
I am getting a bunch of errors and dont' understand how to proceed further.I previously posted a question about this too but it generated more errors .
here's the problem statement:
Write a PL/SQL block of code using parameterized Cursor that will merge the data available in
the newly created table N_RollCall with the data available in the table O_RollCall. If the data in
the first table already exist in the second table then that data should be skipped.
I would suggest you to use an extra variable to store the result and check it in IF codition
SET count = 0;
SELECT COUNT(roll_no) INTO count FROM n_rollcall WHERE EXISTS (oldroll);
Updated code:
CREATE OR REPLACE PROCEDURE procedure_2 AS
DECLARE count INT default 0;
BEGIN
OPEN c_orollcall;
LOOP
FETCH c_orollcall INTO oldroll ,oldname;
SET count = 0;
SELECT roll_no INTO count FROM n_rollcall WHERE EXISTS (oldroll);
IF count>0 THEN
DBMS_OUTPUT.PUT_LINE('ENTRY ALREADY EXISTS');
ELSE
INSERT INTO n_rollcall VALUES (oldroll,oldname);
END IF;
EXIT WHEN c_orollcall%NOTFOUND;
END LOOP;
CLOSE c_orollcall;
END;
/

[PL/SQL]how to make a loop that runs multiple procedures

suppose I have a list of procedures p1,p2,p3..pn , each procedure has only one output number parameter, basically each procedure is a constant number. How could I create a loop that runs all these procedures and the results are displayed on the screen? I tried with EXECUTE IMMEDIATE something like:
DECLARE
i number;
n number:=5;
print number;
begin
for i in 1 .. n loop
EXECUTE IMMEDIATE 'BEGIN p'||i||'('||print||') END;' ;
dbms_output.put_line(print);
end loop;
end;
I also tried the form [EXECUTE IMMEDIATE sql_stmt INTO print USING i]
but I still haven't done anything
It's BEGIN myprocedure; END; - you're missing the ";" after the procedure call. It's unclear what you want the "print" to do, that is not declared anywhere so it will just print an empty value.
CREATE OR REPLACE procedure p1
AS
BEGIN
dbms_output.put_line('this is 1');
END;
/
CREATE OR REPLACE procedure p2
AS
BEGIN
dbms_output.put_line('this is 2');
END;
/
DECLARE
n number:=2;
begin
for i in 1 .. n loop
EXECUTE IMMEDIATE 'BEGIN p'||i||'; END;' ;
end loop;
end;
/
this is 1
this is 2

Oracle SQL dynamic nr of FOR LOOP iterations

I would like to run the FOR LOOP in Oracle based on a parameter that is dynamically populated. Please see, how the code could look like:
declare
idx number := (select max(field_name) from table_name);
begin
for i in 1..idx loop
dbms_output.put_line (i);
end loop;
end;
So basically if the select max(field_name) from table_name returns for example 10, the loop should be run 10 times (for i in 1..10 loop).
Assuming that field_name is an integer, you only need to fetch the max value in the right way:
declare
idx number;
begin
select max(field_name)
into idx
from table_name;
if idx is not null then -- to handle the case where the table is empty
for i in 1..idx loop
dbms_output.put_line (i);
end loop;
end if;
end;
or, without the IF:
declare
idx number;
begin
select nvl(max(field_name), 0)
into idx
from table_name;
for i in 1..idx loop
dbms_output.put_line (i);
end loop;
end;

Output multiple rows of data from cursor using if statement PL/SQL

I am trying to output multiple rows of data from a table called 'student' using pl/sql. I am able to output the first row of data but that is all. I am familiar with loop procedures in other programming languages but am new to pl/sql here is what I have:
DECLARE
variable_Score Number;
variable_LetterGrade Char(1);
name char(10);
cursor studentPtr is SELECT name, grade from STUDENT;
BEGIN
open studentPtr;
LOOP
fetch studentPtr into name, variable_Score;
IF variable_Score >= 90 THEN
variable_LetterGrade := 'A';
ELSIF variable_Score >= 80 THEN
variable_LetterGrade := 'B';
ELSIF variable_Score >= 70 THEN
variable_LetterGrade := 'C';
ELSIF variable_Score >= 60 THEN
variable_LetterGrade := 'D';
ELSE
variable_LetterGrade := 'F';
END IF;
DBMS_OUTPUT.PUT_LINE('Hello '||name||', you receive a '||variable_LetterGrade||' for the class');
EXIT;
END LOOP;
END;
/
The output is :
Hello Joe , you receive a B for the class
This is just the first row from the student table though, there is three more rows of data I would like to output.
Problem is with the EXIT statement. A bare exit statement skips the loop and comes out displaying the row from first fetch.
So, remove the EXIT; before END LOOP and include an EXIT statement like this after your fetch.
..
fetch studentPtr into name, variable_Score;
EXIT WHEN studentPtr%NOTFOUND;
..
..
%NOTFOUND is a cursor attribute and becomes true when all rows are fetched.
what the statement does is that it skips the loop only when no rows could be fetched from the cursor.

How to execute results of dbms_output.put_line

There is a table contains this kind of data: select to_char(sysdate,'day') from dual in a column. I want to get results of the every query that the table keeps.
My result set should be the result of select to_char(sysdate,'day') from dual query. So in this case it is a tuesday.
SO_SQL_BODY is Varchar2.
I wrote this code but it returns only table data.
CREATE or replace PROCEDURE a_proc
AS
CURSOR var_cur IS
select SO_SQL_BODY FROM SO_SUB_VARS group by SO_SQL_BODY;
var_t var_cur%ROWTYPE;
TYPE var_ntt IS TABLE OF var_t%TYPE;
var_names var_ntt;
BEGIN
OPEN var_cur;
FETCH var_cur BULK COLLECT INTO var_names;
CLOSE var_cur;
FOR indx IN 1..var_names.COUNT LOOP
DBMS_OUTPUT.PUT_LINE(var_names(indx).SO_SQL_BODY);
END LOOP;
END a_proc;
DECLARE
res varchar2(4000);
sql_str varchar2(1000);
BEGIN
FOR r IN
(select SO_SQL_BODY FROM SO_SUB_VARS WHERE SO_SQL_BODY IS NOT NULL
)
LOOP
sql_str := r.SO_SQL_BODY;
EXECUTE immediate sql_str INTO res;
dbms_output.put_line(sql_str);
dbms_output.put_line('***********************');
dbms_output.put_line(res);
dbms_output.put_line('***********************');
END LOOP;
END;
/
Try this - iterate to not null records - execute them and print the result.This script works supposing the fact that SO_SQL_BODY contains a query which projects only one column.Also if the projection is with more than two columns then try to use a refcursor and dbms_sql package
İf var_names(indx).SO_SQL_BODY output is a runnable sql text;
CREATE or replace PROCEDURE a_proc
AS
CURSOR var_cur IS
select SO_SQL_BODY FROM SO_SUB_VARS group by SO_SQL_BODY;
var_t var_cur%ROWTYPE;
TYPE var_ntt IS TABLE OF var_t%TYPE;
var_names var_ntt;
BEGIN
OPEN var_cur;
FETCH var_cur BULK COLLECT INTO var_names;
CLOSE var_cur;
FOR indx IN 1..var_names.COUNT LOOP
DBMS_OUTPUT.PUT_LINE(var_names(indx).SO_SQL_BODY);
EXECUTE IMMEDIATE var_names(indx).SO_SQL_BODY;
END LOOP;
END a_proc;
You don't need a full cursor for this example. An implicit one would make it a lot shorter.
create or replace procedure a_proc is
lReturnValue varchar2(250);
begin
for q in (select so_sql_body from so_sub_vars group by so_sql_body)
loop
execute immediate q.so_sql_body into lReturnValue;
dbms_output.put_line(lReturnValue);
end loop;
end a_proc;
You should add an exception handler that will care for cases where there is a bad SQL query in your table. Also note that executing querys saved in a database table is your entry point to SQL injection.