Oracle DBMS_FGA dynamically create an audit trail or policy - oracle

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 ??

Related

Procedure problem ORA-00904 invalid identifier

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!

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.

How do i create triggers i have my code but it has an error

create or replace TRIGGER "CARAVAN"
before insert or update ON caravan
FOR EACH ROW DECLARE cara_no number;
BEGIN
if inserting then
if :new.caravan_no is null then
select caravan.nextval into cara_no from dual;
:new.caravan := cara_no;
end if;
if :new.tags is not null then
:new.tags := caravan_new.tags_cleaner(:new.tags);
end if;
end if;
caravan_new.tag_sync(
p_new_tags => :new.tags,
p_old_tags => :old.tags,
p_content_type => 'CUSTOMER',
p_content_id => :new.caravan_no );
END;
These are the two errors with my code
ORA-24344: success with compilation error
PLS-00103: Encountered the symbol "CREATE" when expecting one of the following:
( begin case declare exit for goto if loop mod null pragma
raise return select update while with <an identifier>

Call stored procedure from PL/SQL Job

In sqlplus I created the procedure, whitch fill my table GeneratedData with int values...
create procedure fillGeneratedData (x in int) as
begin
for i in 1..x loop
insert into GeneratedData values (i);
end loop;
end;
/
I want to create job, whitch call this procedure, but it throws errors and dont call the procedure...
BEGIN
sys.dbms_scheduler.create_job(
job_name => 'job1',
job_type => 'PLSQL_BLOCK',
job_action => 'begin exec fillGeneratedData(50000); end;',
repeat_interval => 'FREQ=MINUTELY;INTERVAL=2',
start_date => systimestamp at time zone 'Europe/Belgrade',
auto_drop => FALSE,
enabled => TRUE);
END;
sqlplus says PL/SQL procedure successfully completed, but when i look to alert log, it throw error:
Tue Apr 01 00:50:45 2014
Errors in file c:\app\adbsuser\diag\rdbms\orcl\orcl\trace\orcl_j000_7516.trc:
ORA-12012: error on auto execute of job 74677
ORA-06550: line 1, column 734:
PLS-00103: Encountered the symbol "" when expecting one of the following:
:= . ( # % ;
The symbol ";" was substituted for "" to continue.
Errors in file c:\app\adbsuser\diag\rdbms\orcl\orcl\trace\orcl_j000_7516.trc:
ORA-12012: error on auto execute of job 74679
ORA-06550: line 1, column 734:
PLS-00103: Encountered the symbol "FILLGENERATEDDATA" when expecting one of the following:
:= . ( # % ;
The symbol ":=" was substituted for "FILLGENERATEDDATA" to continue.
Can somebody help me?
Thanks a lot.
To start with, you PL/SQL block is not valid. If you tried to run just this
begin
exec fillGeneratedData(50000);
end;
you'd get an error. You don't use exec in a PL/SQL block-- that's a SQL*Plus command. Your PL/SQL block would just be
begin
fillGeneratedData(50000);
end;

Cause: FDPSTP failed due to ORA-06550: line 1, column 7:PLS-00221: is not a procedure or is undefined

I'm trying to run a concurrent request in APPS but i keep getting this error
(Cause: FDPSTP failed due to ORA-06550: line 1, column 7:
PLS-00221: 'XXINV_ITEM_ORACLE_E5B0' is not a procedure or is undefined
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored)
and heres my package body its just a simple insert.
CREATE OR REPLACE PACKAGE BODY APPS.XXINV_ITEM_ORACLE_E5B0 IS
PROCEDURE inv_com_proc (
o_chr_errbuf OUT VARCHAR2,
o_num_retcode OUT NUMBER
)
AS
begin
EXECUTE IMMEDIATE 'TRUNCATE TABLE XXINV.XXINV_ITEM_ORACLE_E5B0';
Insert into XXINV.XXINV_ITEM_ORACLE_E5B0(ORGANIZATION_CODE ,
ITEM_NUM,
ON_HAND_QUANTITY ,
ITEM_TYPE ,
STATUS ,
MATERIAL_COST ,
MATERIAL_OVERHEAD_COST,
RESOURCE_COST,
OVERHEAD_COST,
OUTSIDE_PROCESSING_COST,
SUBINVENTORY_CODE ,
LOCATORS )
select OWNING_ORG_CODE, ITEM_NUMBER, ON_HAND_QUANTITY, ITEM_TYPE, STATUS, MATERIAL_COST ,
MATERIAL_OVERHEAD_COST,
RESOURCE_COST,
OVERHEAD_COST,
OUTSIDE_PROCESSING_COST,
SUBINVENTORY_CODE ,
LOCATOR
from apps.XXRPT_INV_VALUATION_D535_V
where apps.XXRPT_INV_VALUATION_D535_V.SUBINVENTORY_CODE = 'FG' AND apps.XXRPT_INV_VALUATION_D535_V.STATUS = 'ONHAND';
COMMIT;
END;
end XXINV_ITEM_ORACLE_E5B0;
When you define the Concurrent Program Executable in System Administration, make sure you the Execution File Name includes the schema.package.procedure, as in APPS.XXINV_ITEM_ORACLE_E5B0.inv_com_proc (no parenthesis).
It seems you're trying to execute the package itself - that won't work. You must execute a procedure/function within the package:
DECLARE
o_chr_errbuf VARCHAR2(256);
o_num_retcode NUMBER;
BEGIN
APPS.XXINV_ITEM_ORACLE_E5B0.inv_com_proc ( o_chr_errbuf, o_num_retcode);
END;
/
A simple test:
DECLARE
err VARCHAR2(256);
CODE NUMBER;
BEGIN xx(err, CODE); END;
ORA-06550: line 5, column 7:
PLS-00221: 'XX' is not a procedure or is undefined
ORA-06550: line 5, column 7:
PL/SQL: Statement ignored
SQL> SELECT * FROM a;
ID
---------------------------------------
SQL> DECLARE
2 err VARCHAR2(256);
3 CODE NUMBER;
4 BEGIN
5 xx.tst(err, CODE);
6 END;
7 /
PL/SQL procedure successfully completed
SQL> SELECT * FROM a;
ID
---------------------------------------
1

Resources