oracle sql developer email alert - oracle

can you please check this for me
this is not working
do we need special utl_mail
no idea what this utl_mail is
create or replace
procedure check_stock_qty
begin
for r ( select inv_qoh from inventory
where qty = 0 )
loop
UTL_MAIL.send(sender => 'na#yahoo.com',
recipients => 'krn9#mail.ca',
subject => 'Test Mail',
message => (r.inv_qoh),
mime_type => 'text; charset=us-ascii');
end loop;
end;
BEGIN
dbms_scheduler.create_job (
job_name => 'stock check',
job_type => 'PLSQL_BLOCK',
job_action => 'BEGIN check_stock_qty; END;',
start_date => SYSTIMESTAMP,
repeat_interval => 'freq=minutely; interval=7200; bysecond=0;',
end_date => NULL,
enabled => TRUE,
END;
my error is
Error(2,1): PLS-00103: Encountered the symbol "BEGIN" when expecting one of the following: ( ; is with authid as cluster compress order using compiled wrapped external deterministic parallel_enable pipelined result_cache

The syntax for creating the procedure is
create or replace procedure <Name>
(<variable list>)
as (or is)
local variable declaration
begin
code section
exceptions
end;
here you missed the IS or AS Keyword before BEGIN

i tried with as
Error(5,8): PLS-00103: Encountered the symbol "(" when expecting one of the following: in The symbol "in" was substituted for "(" to continue.
Error(16,1): PLS-00103: Encountered the symbol "BEGIN"
Error(25,1): PLS-00103: Encountered the symbol "END" when expecting one of the following: ( - + case mod new not null continue avg count current exists max min prior sql stddev sum variance execute forall merge time timestamp interval date pipe
so much errors :(

Related

ORA-29913-Error executing call, after migrating the database to Exadata

I have a scheduler job which calls the procedure PR_DELETE_AUDIT_LOG. This code was working fine until the Oracle database was migrated to Exadata. Now whenever the job is executed we get the following errors as shown below.
ORA-29913: Error executing call
ORA-06512: in "ABC.PR_DELETE_AL_IMPORTLOG", AT LINE 49
ORA-06512: in "ABC.PR_DELETE_AL_IMPORTLOG", AT LINE 34
ORA-06512: in "ABC.PR_DELETE_AL_IMPORTLOG", AT LINE 34
The code for the job and the procedures are as follows.
DELETE_AL_IMPORTLOG_JOB
BEGIN
DBMS_SCHEDULER.CREATE_JOB (
job_name => 'ABC.DELETE_AL_IMPORTLOG_JOB',
job_type => 'STORED_PROCEDURE',
job_action => 'ABC.PR_DELETE_AL_IMPORTLOG',
number_of_arguments => 0,
start_date => NULL,
repeat_interval => 'FREQ=DAILY;BYTIME=000000',
end_date => NULL,
enabled => FALSE,
auto_drop => FALSE,
comments => '');
DBMS_SCHEDULER.SET_ATTRIBUTE(
name => 'ABC.DELETE_AL_IMPORTLOG_JOB',
attribute => 'store_output', value => TRUE);
DBMS_SCHEDULER.SET_ATTRIBUTE(
name => 'ABC.DELETE_AL_IMPORTLOG_JOB',
attribute => 'logging_level', value => DBMS_SCHEDULER.LOGGING_OFF);
DBMS_SCHEDULER.enable(
name => 'ABC.DELETE_AL_IMPORTLOG_JOB');
END;
/
PR_DELETE_AL_IMPORTLOG
CREATE OR REPLACE EDITIONABLE PROCEDURE "ABC"."PR_DELETE_AL_IMPORTLOG"
AS
V_DELETION_DATE DATE;
CURSOR CUR_OLD_FILES
IS SELECT FNAME
FROM EXT_TAB_AL_IMPORTLOG_FILE_LIST
WHERE REGEXP_LIKE(FNAME,'AL_\d{2}-\d{2}-\d{2}_\d{8}_\d{6}.txt')
AND TO_DATE(SUBSTR(FNAME, -19,15),'YYYYMMDD_HH24MISS') < V_DELETION_DATE;
BEGIN
SELECT ADD_MONTHS
( TRUNC
( SYSDATE
, DECODE( STARTZEITPUNKTABF
, 1 ,'DD'
, 2 ,'MM'
, 3 ,'Q'
, 4 ,'YY'
,'DD'
)
)
, DECODE(PERIODEABF,2,-DAUERABF,3,-DAUERABF*12,0)) - DECODE(PERIODEABF,1,DAUERABF,0)
INTO V_DELETION_DATE
FROM LOESCHREGEL
WHERE VERWENDUNGSZWECK_ID = 'CLALL';
FOR REC_OLD_FILES IN CUR_OLD_FILES
LOOP
UTL_FILE.FREMOVE('ABC_AL_IMPORTLOG', REC_OLD_FILES.FNAME);
dbms_output.put_line('Deleted file '||REC_OLD_FILES.FNAME);
END LOOP;
EXCEPTION
WHEN OTHERS
THEN
DECLARE
V_PROCEDURE_NAME VARCHAR2(30) := $$PLSQL_UNIT;
V_SUBJECT VARCHAR2(255) := 'Error on DB procedure '||V_PROCEDURE_NAME||' on '||to_char(sysdate,'dd.mm.yyyy hh24:mi:ss');
V_BODY VARCHAR2(10000) := 'Hi all,'||chr(10)||chr(10)||'Procedure '||V_PROCEDURE_NAME||' returned the following error:'||chr(10)||SQLERRM;
BEGIN
SEND_MAIL ( 'GENERIC_DB_ERROR', V_SUBJECT,V_BODY);
RAISE;
END;
END PR_DELETE_AL_IMPORTLOG;
/
DDL for Table EXT_TAB_AL_IMPORTLOG_FILE_LIST
CREATE TABLE ABC.EXT_TAB_AL_IMPORTLOG_FILE_LIST
( FNAME VARCHAR2(255 CHAR )
)
ORGANIZATION EXTERNAL
( TYPE ORACLE_LOADER
DEFAULT DIRECTORY COLEIN_AUDITLOG
ACCESS PARAMETERS
( RECORDS DELIMITED BY NEWLINE
PREPROCESSOR COLEIN_PROCESS:'AL_ImportLog_list_files.sh'
noLOGFILE
nobadfile
nodiscardfile
FIELDS TERMINATED BY WHITESPACE
)
LOCATION
( 'lsOutput.log'
)
)
REJECT LIMIT UNLIMITED ;
where is the problem?
The error seems to come from a value of ext_tab_al_importlog_file_list.fname that doesn't match the expected filename format. You might want to check the values to see which one is invalid and how it got there.
If you are using Oracle 12.2 or later, change the cursor to use an on conversion error clause:
select fname
from ext_tab_al_importlog_file_list
where regexp_like(fname, 'AL_\d{2}-\d{2}-\d{2}_\d{8}_\d{6}.txt')
and to_date(substr(fname, -19, 15) default null on conversion error, 'YYYYMMDD_HH24MISS') < v_deletion_date;
If not, you could try adding some more filters:
select fname
from ext_tab_al_importlog_file_list
where regexp_like(fname, 'AL_\d{2}-\d{2}-\d{2}_\d{8}_\d{6}.txt')
and to_date(substr(fname, -19, 15), 'YYYYMMDD_HH24MISS') < v_deletion_date
and to_number(substr(fname,-10,2)) < 24
and to_number(substr(fname,-8,2)) < 60
and to_number(substr(fname,-6,2)) < 60;
This worked in my quick test, but combining filters with a conversion function is risky because there is no guarantee that Oracle will apply the filtering conditions in any particular order.
You can find the invalid values using either of the following:
select fname
from ext_tab_al_importlog_file_list
where regexp_like(fname, 'AL_\d{2}-\d{2}-\d{2}_\d{8}_\d{6}.txt')
and to_date(substr(fname, -19, 15) default null on conversion error, 'YYYYMMDD_HH24MISS') is null;
select fname
from ext_tab_al_importlog_file_list
where regexp_like(fname, 'AL_\d{2}-\d{2}-\d{2}_\d{8}_\d{6}.txt')
and ( to_number(substr(fname,-10,2)) >= 24
or to_number(substr(fname,-8,2)) >= 60
or to_number(substr(fname,-6,2)) >= 60 );

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

DBMS scheduler oracle - how to execute a procedure

I'm loosing my mind. I have a procedure named foo() which takes no arguments. I'd like to execute it, let's say, every 3 minutes. The code I wrote looks like:
BEGIN
dbms_scheduler.create_job(job_name => FooJob,
job_type => 'PLSQL_BLOCK',
job_action => '
BEGIN
foo();
END;',
start_date => SYSTIMESTAMP,
repeat_interval => 'FREQ=MINUTELY;INTERVAL=3;BYHOUR=17;BYMINUTE=35;',
enabled => TRUE
comments => 'A comment.');
END;
/
This gives me an error: identificator 'applyjobpenalities' should be defined.
I based on this example: How to execute a procedure with DBMS_SCHEDULER.CREATE_JOB procedure
Also:
1) How to execute dbms_output.put_line() after execution of foo();? Is it possible to just put this line strightly away?
2) How to check if procedure foo() is (was) executing on behalf of scheduler?
UPDATE:
Ok so what I've done is:
1) I typed in SQL Plus 'set serveroutput on'
2) I made a procedure:
create or replace procedure proc1
IS
BEGIN
dbms_output.put_line('sth');
end;
/
3) I changed scheduler code to:
BEGIN
dbms_scheduler.create_job( job_name => 'JustATest',
job_type => 'PLSQL_BLOCK',
job_action =>
'BEGIN
proc1();
END;',
start_date => systimestamp + interval '10' second,
repeat_interval => 'FREQ=SECONDLY',
enabled => TRUE);
END;
/
But I can't see any result in SQL Plus. What am I missing? Both procedures compiled succesfully and I can see this job when I type:
SELECT * FROM DBA_SCHEDULER_JOBS;
1) There is no way to extract DBMS_OUTPUT from a scheduled job.
2) To check if FOO was executing, I use the following SQL (extracted from TOAD's "Spool SQL to Screen" option. If you are going to be spending any time at all developing in Oracle, get TOAD for Oracle).
SELECT l.job_name
, l.JOB_SUBNAME
, l.log_id "Log ID"
, l.log_date "Log Date"
, l.operation "Operation"
, l.status "Status"
, l.user_name "User Name"
, l.client_id "Client ID"
, l.global_uid "Global UID"
, r.req_start_date "Required Start Date"
, r.actual_start_date "Actual Start Date"
, r.run_duration "Run Duration"
, r.instance_id "Instance ID"
, r.session_id "Session ID"
, r.slave_pid "Slave PID"
, TO_CHAR (r.cpu_used) "CPU Used"
, r.additional_info "Additional Info (Run)"
FROM dba_scheduler_job_log l, dba_scheduler_job_run_details r
WHERE l.log_id = r.log_id(+)
and l.job_name like 'FooJob'
ORDER BY 1 DESC NULLS LAST;
2b) To see jobs that are currently running:
SELECT *
FROM dba_scheduler_running_jobs;
3) If you want to see results from your job, you need to have your job do something, such as insert a record into a table.
Change Job_action => 'proc1';
And in another notepad type
BEGIN
DBMS_SCHEDULER.RUN_JOB(
JOB_NAME => 'justATest',
USE_CURRENT_SESSION => FALSE);
END;
And then execute the above code
You can see result of dbms_output.put_line() in dba_scheduler_job_run_details column "output".
Put in job action
BEGIN
foo();
dbms_output.put_line( 'foo executed in job' ) ;
END;

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;

Programming DBA Jobs in Stored procs

I am a little new to programming, so any help is appreciated.
Find below the code of my stored proc to delete a table and also create a DBA job which will run on a hourly basis.
CREATE OR REPLACE procedure DELETE_My_TABLE(myschema varchar2) as
BEGIN
BEGIN
execute immediate 'delete from '||myschema||'.mytable where clause;';
END;
BEGIN
DBMS_SCHEDULER.create_program (
program_name => 'DELETE_My_TABLE',
program_type => 'STORED_PROCEDURE',
program_action => 'execute DELETE_My_TABLE(myschema)',
number_of_arguments => 1,
enabled => FALSE,
comments => 'Program to delete table using a stored procedure.');
DBMS_SCHEDULER.define_program_argument (
program_name => 'DELETE_My_TABLE',
argument_name => 'myschema',
argument_position => 1,
argument_type => 'VARCHAR2',
default_value => 'myschema');
DBMS_SCHEDULER.enable (name => 'DELETE_My_TABLE');
END;
BEGIN
DBMS_SCHEDULER.create_schedule (
schedule_name => 'DELETE_My_TABLE',
start_date => SYSTIMESTAMP,
repeat_interval => 'freq=hourly; byminute=0',
end_date => NULL,
comments => 'Hourly Job to purge SEARCH_TEMP_TABLE');
END;
END;
/
Issues:
ERROR at line 1:
ORA-00920: invalid relational operator
ORA-06512: at "MYSCHEMA.DELETE_My_TABLE", line 4
ORA-06512: at line 1
Will the logic (and syntax) work?
One issue I can see is that you need to take the semi-colon out of the EXECUTE IMMEDIATE string:
execute immediate 'delete from '||myschema||'.mytable where clause';
^^
Removed from here
thought I suspect this won't solve your immediate problem, which looks like it's your BEGIN ...END blocks.
For the Oracle Scheduler you normally create a program, once. Next you create a job that has the program as action. You can give that job a schedule like you specified in your code but you have to choose. Either you create a schedule and have the job use it, or you give the job it's own repeat interval.
I happen to know about a book ( Mastering Oracle Scheduler ) that I wrote that could be very helpful.

Resources