Procedure problem ORA-00904 invalid identifier - oracle

I'm trying to create reschedule procedure for AQ queues. So i have created procedure with one IN parameter where our operator will enter just a name of queue, and i hit error when i execute create of procedure
CREATE OR REPLACE PROCEDURE RESCHEDULE1 (p_queue IN VARCHAR2)
AS
BEGIN
SYS.DBMS_AQADM.STOP_QUEUE (p_queue);
END;
DECLARE
CURSOR upit
IS
SELECT destination
FROM USER_QUEUE_SCHEDULES
WHERE qname = p_queue;
BEGIN
FOR dest_rec IN upit
LOOP
DBMS_AQADM.UNSCHEDULE_PROPAGATION (queue_name => p_queue,
destination => dest_rec.destination);
DBMS_AQADM.SCHEDULE_PROPAGATION (queue_name => p_queue,
destination => dest_rec.destination,
start_time => SYSDATE);
END LOOP;
END;
;
BEGIN
SYS.DBMS_AQADM.START_QUEUE (p_queue);
END;
/
Error is
ORA-06550: line 7, column 39:
PL/SQL: ORA-00904: "P_QUEUE": invalid identifier
ORA-06550: line 5, column 4:
PL/SQL: SQL Statement ignored
ORA-06550: line 14, column 54:
PLS-00201: identifier 'P_QUEUE' must be declared
ORA-06550: line 14, column 2:
PL/SQL: Statement ignored
ORA-06550: line 17, column 52:
PLS-00201: identifier 'P_QUEUE' must be declared
ORA-06550: line 17, column 2:
PL/SQL: Statement ignored

p_queue is out of scope everywhere, except in RESCHEDULE1 procedure. You have to pass its value, somehow.
One option is this: instead of using an anonymous PL/SQL blocks, switch to procedures (and - of course - declare the p_queue parameter).

I think your procedure has improper use of BEGIN..END and DECLARE
Try following code:
CREATE OR REPLACE PROCEDURE RESCHEDULE1 (p_queue IN VARCHAR2)
AS
-- all declarations should go here
CURSOR upit
IS
SELECT destination
FROM USER_QUEUE_SCHEDULES
WHERE qname = p_queue;
BEGIN -- starting of procedure
BEGIN -- starting of this block -- can be removed
SYS.DBMS_AQADM.STOP_QUEUE (p_queue);
END; -- ending of this block -- can be removed
FOR dest_rec IN upit -- loop started from here
LOOP
DBMS_AQADM.UNSCHEDULE_PROPAGATION (queue_name => p_queue,
destination => dest_rec.destination);
DBMS_AQADM.SCHEDULE_PROPAGATION (queue_name => p_queue,
destination => dest_rec.destination,
start_time => SYSDATE);
END LOOP; -- loop ends here
BEGIN -- starting of this block -- can be removed
SYS.DBMS_AQADM.START_QUEUE (p_queue);
END; -- ending of this block -- can be removed
END RESCHEDULE1; -- end of procedure
/
Note: You can remove unnecessary BEGIN and END from code if you dont want to handle exceptions.
I have kept all BEGIN and END in procedure as it is, considering tht you actually need it for future development.
Cheers!!

Please sorry i didnt post that i have found answer, problem was with bad begin and end. Now this works
CREATE OR REPLACE PROCEDURE AQADMIN.RESCHEDULE1 (p_queue in varchar2)
is
begin
begin
DBMS_AQADM.STOP_QUEUE(p_queue);
end;
declare
cursor upit
is
SELECT destination
FROM USER_QUEUE_SCHEDULES
WHERE qname = p_queue ;
begin
for dest_rec in upit
loop
DBMS_AQADM.UNSCHEDULE_PROPAGATION (queue_name => p_queue,
destination => dest_rec.destination);
DBMS_AQADM.SCHEDULE_PROPAGATION (queue_name => p_queue,
destination => dest_rec.destination,
start_time => SYSDATE);
end loop;
end;
begin
DBMS_AQADM.START_QUEUE (p_queue);
end;
end;
/
Thank you for all your help!

Related

'LANG_CUR' is not a procedure or is undefined ORA-06550 Error

1.I have been trying to fetch 1 column from a table using reference cursor in plsql, table only has 11 column lang_cur is the declared cursor.
create or replace PACKAGE MOVIE_PKG
AS
PROCEDURE lang_display(lang_cur out SYS_REFCURSOR);
END MOVIE_PKG;
create or replace PACKAGE BODY MOVIE_PKG
AS
PROCEDURE lang_display(lang_cur out SYS_REFCURSOR)
as
begin
OPEN lang_cur FOR select lang_name from LANGUAGE_SELECT;
end lang_display;
END MOVIE_PKG;
declare
lang_cur SYS_REFCURSOR;
begin
movie_pkg.lang_display(lang_cur);
for data in lang_cur
loop
dbms_output.put_line('langauge:'||data.lang_name);
end loop;
end;
GETTING THIS ERROR
ORA-06550: line 5, column 13:
PLS-00221: 'LANG_CUR' is not a procedure or is undefined
ORA-06550: line 5, column 1:
PL/SQL: Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:)```
You can use FETCH:
declare
lang_cur SYS_REFCURSOR;
lang_name LANGUAGE_SELECT.LANG_NAME%TYPE;
begin
movie_pkg.lang_display(lang_cur);
LOOP
FETCH lang_cur INTO lang_name;
EXIT WHEN lang_cur%NOTFOUND;
dbms_output.put_line('langauge:'||lang_name);
END LOOP;
CLOSE lang_cur;
END;
/
db<>fiddle here

Oracle DBMS_FGA dynamically create an audit trail or policy

my goal is to run a select to a table and based on the certain rows dynamically create an audit trail or policy on them.
so..
create a set_policy function that gets called/Looped:
create or replace
function set_policy
( sch VARCHAR2 ,
tab VARCHAR2,
colm VARCHAR2,
pred VARCHAR2,
emailer VARCHAR2
)
return VARCHAR2 is
policy_sql_stmt varchar2(1000);
BEGIN
policy_sql_stmt :=
'BEGIN
SYS.DBMS_FGA.ADD_POLICY (
object_schema => :s,
object_name => :t,
policy_name => ''CHK_:s_:t'',
audit_column => :c,
audit_condition => :p,
handler_schema => ''SYSADMIN_FGA'',
handler_module => '''||emailer||'(:s,:t,''''CHK_:s_:t'''')'',
enable => TRUE,
statement_types => ''SELECT, UPDATE'',
audit_trail => SYS.DBMS_FGA.DB + SYS.DBMS_FGA.EXTENDED);
END;';
--DBMS_OUTPUT.PUT_LINE('policy_sql_stmt = :' || policy_sql_stmt);
BEGIN
EXECUTE IMMEDIATE policy_sql_stmt USING sch,tab,colm,pred;
--EXECUTE IMMEDIATE policy_sql_stmt USING pred;
EXCEPTION
WHEN OTHERS THEN
BEGIN
--dbms_output.put_line('set_policy error code: '||SQLCODE);
--dbms_output.put_line(DBMS_UTILITY.FORMAT_CALL_STACK);
RETURN ('set_policy error code: '||SQLCODE);
END;
END;
RETURN 'success';
END;
Then a procedure that calls the function...
CREATE OR REPLACE PROCEDURE audit_slac_tables
AS
--DECLARE
emailer VARCHAR2(40):='audit_email_alert';
isSuccess VARCHAR2(40);
CURSOR myCursor
IS
SELECT SCHEMA AS sch,
TABLE_NAME AS tab,
FILTER_COLUMN AS colm,
WHERE_COND AS pred
FROM SLAC_REDACTION_TABLE slac;
--WHERE slac.table_name IN ('RECIPIENT','CARD');
BEGIN
FOR curRec IN myCursor
LOOP
BEGIN
--emailer := getEmailer(curRec.sch ,curRec.tab);
isSuccess := set_policy(curRec.sch ,curRec.tab, curRec.colm, curRec.pred, emailer);
DBMS_OUTPUT.PUT_LINE('Proc isSuccess = :' || isSuccess);
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line('Proc error code: '||SQLCODE);
dbms_output.put_line('Proc error msg: '||SQLERRM);
--dbms_output.put_line(DBMS_UTILITY.FORMAT_CALL_STACK);
--dbms_output.put_line('================================================');
CONTINUE;
END;
--dbms_output.put_line('================================================');
END LOOP;
COMMIT;
END audit_slac_tables;
if I call it...
exec AUDIT_SLAC_TABLES;
I get the following bewildering error
Error starting at line : 6 in command -
exec AUDIT_SLAC_TABLES
Error report -
ORA-06550: line 12, column 18:
PLS-00201: identifier 'SYS.DBMS_FGA' must be declared
ORA-06550: line 2, column 3:
PL/SQL: Statement ignored
ORA-06512: at "GAPLITE.SET_POLICY", line 51
ORA-06512: at "GAPLITE.AUDIT_SLAC_TABLES", line 27
ORA-06512: at line 1
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
Why a reference problem where the script DBMS_FGA.ADD_POLICY never had a problem?
I can run this script ( listed 1st above ) but not dynamically... it loses trhe contextual reference to the SYS packages somehow ??

Separate tables from splitting comma separated strings

I am trying to take two comma separated strings and split them into two separate tables to use later for comparison reasons. Below is as close as I have gotten to this point. Both strings are being put into the same table, which honestly would work in the case I need it for, but it is a very clunky solution.
I tried to change the name of the table from 'TEST' to something else in the second loop, but I always got a compile error. Does someone know a more elegant solution?
DECLARE
L_INPUT_LOG VARCHAR2(25) := 'Error,Audit';
L_INPUT_MOD VARCHAR(4000) := 'MODULE1,MODULE2';
L_COUNT BINARY_INTEGER;
LOG_TYPE_ARRAY DBMS_UTILITY.LNAME_ARRAY;
APP_MODULE_ARRAY DBMS_UTILITY.LNAME_ARRAY;
BEGIN
DBMS_UTILITY.COMMA_TO_TABLE(LIST => REGEXP_REPLACE(L_INPUT_LOG, '(^|,)', '\1x'), TABLEN => L_COUNT, TAB => LOG_TYPE_ARRAY);
DBMS_UTILITY.COMMA_TO_TABLE(LIST => REGEXP_REPLACE(L_INPUT_MOD, '(^|,)', '\1x'), TABLEN => L_COUNT, TAB => APP_MODULE_ARRAY);
FOR I IN 1 .. L_COUNT
LOOP
INSERT INTO TEST VALUES
(SUBSTR(LOG_TYPE_ARRAY(I), 2) );
COMMIT;
END LOOP;
FOR I IN 1 .. L_COUNT
LOOP
INSERT INTO TEST VALUES
(SUBSTR(APP_MODULE_ARRAY(I), 2) );
COMMIT;
END LOOP;
END;
UPDATE: Below is the error that I am getting when I try to change the table TEST in the second loop. Asked for by MaxU
Error starting at line : 1 in command -
DECLARE
L_INPUT_LOG VARCHAR2(25) := 'Error,Audit';
L_INPUT_MOD VARCHAR(4000) := 'MODULE1,MODULE2';
L_COUNT BINARY_INTEGER;
LOG_TYPE_ARRAY DBMS_UTILITY.LNAME_ARRAY;
APP_MODULE_ARRAY DBMS_UTILITY.LNAME_ARRAY;
BEGIN
DBMS_UTILITY.COMMA_TO_TABLE(LIST => REGEXP_REPLACE(L_INPUT_LOG, '(^|,)', '\1x'), TABLEN => L_COUNT, TAB => LOG_TYPE_ARRAY);
DBMS_UTILITY.COMMA_TO_TABLE(LIST => REGEXP_REPLACE(L_INPUT_MOD, '(^|,)', '\1x'), TABLEN => L_COUNT, TAB => APP_MODULE_ARRAY);
FOR I IN 1 .. L_COUNT
LOOP
INSERT INTO TEST VALUES
(SUBSTR(LOG_TYPE_ARRAY(I), 2) );
COMMIT;
END LOOP;
FOR I IN 1 .. L_COUNT
LOOP
INSERT INTO GRIM VALUES
(SUBSTR(APP_MODULE_ARRAY(I), 2) );
COMMIT;
END LOOP;
END;
Error report -
ORA-06550: line 18, column 18:
PL/SQL: ORA-00942: table or view does not exist
ORA-06550: line 18, column 6:
PL/SQL: SQL Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
There can be multiple reasons for which the issue can arise.
1) If the 'TEST' table created in the same schema from where you
executing the script?
If NO Try providing schema_name.TEST and if you are relying on ROLES
for GRANT here it wont work. So you need to provide the DIRECT OBJECT
level GRANTS to access the table.
Try GRANT SELECT,insert,update,delete ON SCHEMA.TEST TO <USER>;
Hope this helps.

Executing Stored Procedure - Oracle PL SQL

I'm currently trying to execute a stored procedure in Oracle PL SQL. I keep running into the same error for the below with execution.
I've tried both execution with the same error
SET SERVEROUTPUT ON;
EXEC get_phone(200.00,500.00);
OR
SET SERVEROUTPUT ON;
DECLARE
c_minprice products.price%type;
c_maxprice products.price%type;
BEGIN
c_minprice := get_phone(200);
c_maxprice := get_phone(500);
END;
ERROR from executing the above:
c_minprice := get_phone(200);
*
ERROR at line 5:
ORA-06550: line 5, column 15:
PLS-00306: wrong number or types of arguments in call to 'GET_PHONE'
ORA-06550: line 5, column 1:
PL/SQL: Statement ignored
ORA-06550: line 6, column 15:
PLS-00306: wrong number or types of arguments in call to 'GET_PHONE'
ORA-06550: line 6, column 1:
PL/SQL: Statement ignored
****Sample Snip-its form my code:
CREATE OR REPLACE PROCEDURE get_phone
(
c_minprice IN products.price%type,
c_maxprice IN products.price%type,
i_result OUT VARCHAR2
) AS
--Checking if starting price range is valid or not
IF c_minprice IS NULL THEN
i_result := 'Starting price range should be valid and cannot be empty';
RAISE V_MINPRICE; -- Raising exception if starting price is null
END IF;
--Checking if end price range is valid or not
IF c_maxprice IS NULL THEN
i_result := 'End price range should be valid and cannot be empty';
RAISE V_MAXPRICE; -- Raising exception if end price is null
END IF;
Your procedure requires three parameters so you have to pass in three parameters
DECLARE
l_result varchar2(100);
BEGIN
get_phone( 200, 500, l_result );
END;
/
should work. Of course, your procedure seems rather pointless. And if the goal is simply to return a result, you really ought to be using a function rather than a procedure with an out parameter.
get_phone expects 3 arguments, c_minprice, c_maxprice and i_result. You are only passing it one number. Pass it the rest of the arguments.

i have created stored procedure but can't able to execute same

I defined a stored procedure
create or replace procedure spfirst
(
sp_loc out varchar,
sp_sal out int
)
as
begin
select LOCATION, MONTHLY_SALARY
into sp_loc, sp_sal
from nilesh;
end;
I then call the procedure and get an error
begin
spfirst;
end;
ORA-06550: line 2, column 1:
PLS-00201: identifier 'SPNAME' must be declared
ORA-06550: line 2, column 1:
PL/SQL: Statement ignored
Your procedure takes two parameters. You are calling it without any parameters. Oracle thus looks for a procedure named spfirst that takes no parameters, finds no such procedure, and throws an error.
Something like
DECLARE
l_location nilesh.location%type;
l_salary nilesh.monthly_salary%type;
BEGIN
spfirst( l_location, l_salary );
END;
should work. Of course, you'd generally want to do something with the variables that are returned. If you've enabled dbms_output, you could print them out
DECLARE
l_location nilesh.location%type;
l_salary nilesh.monthly_salary%type;
BEGIN
spfirst( l_location, l_salary );
dbms_output.put_line( 'Location = ' || l_location );
dbms_output.put_line( 'Salary = ' || l_salary );
END;
Be aware that your procedure will throw an error unless the nilesh table has exactly one row. It seems likely that you either want the procedure to take an additional parameter that is the key to the table so that the select into always returns a single row or that you want a function that returns a sys_refcursor rather than a procedure that has multiple out parameters.

Resources