Oracle Apex - Apex Mail Send sending same email two times - oracle

I have a button that runs the apex_mail.send functionality when clicked.
The code I have is the following:
DECLARE
l_body CLOB;
V_ID_MX number;
V_REQUESTER VARCHAR2(1000);
v_user varchar2(300);
BEGIN
--Basically selects the latest added row on my table:
SELECT max(id) INTO V_ID_MX FROM My_Table;
--Line to remove the #mail.com from user email:
select INITCAP(replace(regexp_replace(rep_assigned,'#[a-zA-z0-9.]*',''), '.', ' ')) into
v_user from My_table WHERE ID = V_ID_MX;
--Assigning Rep email to the v_requester variable:
select rep_assigned into V_REQUESTER from My_Table WHERE ID = V_ID_MX;
l_body := 'Hi ' || v_user ||',' || utl_tcp.crlf;
l_body := l_body || utl_tcp.crlf;
l_body := l_body || utl_tcp.crlf;
l_body := l_body || 'Please review latest added row.' ||utl_tcp.crlf;
l_body := l_body || utl_tcp.crlf;
l_body := l_body || 'ID: '|| V_ID_MX ||utl_tcp.crlf;
l_body := l_body || utl_tcp.crlf;
l_body := l_body || utl_tcp.crlf;
l_body := l_body || 'Thank you' || utl_tcp.crlf;
apex_mail.send(
p_to => V_REQUESTER,
p_from => 'generic_email#mail.com',
p_body => l_body,
p_subj => 'Some Subject';
END;
It works perfectly, with one annoying exception: it sends the same email twice.
Does anybody know how to avoid this email duplicity?
Thanks

Related

Send excel file stored in directory using utl_smtp

Need help in sending excel file as an attachment which is stored in directory of a server.
I have a procedure which writes a file to server and need to send it as as attachement with HTML body message which includes multiple tables and excel attachement. but i am quite stuck in attachment part for now!.
CREATE OR REPLACE PROCEDURE p_send_email_with_attach as
file_handle utl_file.file_type;
output VARCHAR2(32767);
attachment_text VARCHAR2(32767);
v_dir VARCHAR2(300) := 'RPT_DIR';
v_recipients VARCHAR2(2000) := 'abc#gmail.com';
v_sub VARCHAR2(300) := 'Hello';
v_smtp_server VARCHAR2(255) := 'mailhost';
conn utl_smtp.connection;
c_mime_boundary CONSTANT VARCHAR2(256) := 'the boundary can be almost anything';
v_from_name VARCHAR2(100) := 'xyz#yahoo.com';
BEGIN
file_handle := utl_file.fopen(
location => v_dir,
filename => 'My_First_CSV.CSV',
open_mode => 'R'
);
LOOP
BEGIN
utl_file.get_line(
file_handle,
output
); -- we read the file, line by line
attachment_text := attachment_text || utl_tcp.crlf; --and store every line in
the attachment_text variable, separated by a ?new line? character.
EXCEPTION
WHEN no_data_found THEN
EXIT;
END;
END LOOP;
utl_file.fclose(file_handle);
conn := utl_smtp.open_connection('mailhost');
utl_smtp.helo(conn, 'mailhost');
utl_smtp.mail(conn, v_from_name);
FOR cur_r IN (
SELECT level AS id, regexp_substr(email_id, '[^;]+', 1, level) AS v_recipient
FROM
email_address
CONNECT BY regexp_substr( email_id, '[^;]+', 1, level) IS NOT NULL
) LOOP
utl_smtp.rcpt(conn,cur_r.v_recipient);
END LOOP;
UTL_SMTP.write_data(conn, '--' || c_mime_boundary || UTL_TCP.crlf);
UTL_SMTP.write_data(conn, 'Content-Type: text/plain' || UTL_TCP.crlf);
UTL_SMTP.write_data(
conn,
'Content-Disposition: attachment; filename="' || 'My_First_CSV.CSV' || '"' || UTL_TCP.crlf
);
utl_smtp.open_data(conn);
EXCEPTION
WHEN OTHERS THEN
raise_application_error(
-20001,
'Error: ' || sqlerrm
);
END;
i beleive i am missing something while writing, kindly help in fixing this. thanks :)

How to send excel attachment while query output using sys.UTL_MAIL.send_attach_raw in oracle?

In the below PL/SQL SP Cursor output store as HTML table and send as Excel file as attachment.
But I am getting the following error, even if I take CLOB datatype:
ORA-06502: PL/SQL: numeric or value error: raw variable length too long
ORA-06512: at "SYS.UTL_MAIL", line 654
ORA-06512: at "SYS.UTL_MAIL", line 739
CREATE OR REPLACE PROCEDURE sp_send_mail_with_attch (
p_mode char,
p_message VARCHAR2 := '.',
p_subject VARCHAR2 := '.',
p_from VARCHAR2 := 'ITTEAM'
) AS
msg_from VARCHAR2(50);
msg_to VARCHAR2(4000);
message_to VARCHAR2(50);
mailhost VARCHAR2(30);
mailport VARCHAR2(20);
crlf VARCHAR2(2) := chr(13)|| chr(10);
msg_subject VARCHAR2(250);
tablehead VARCHAR2(32767);
message VARCHAR2(32767);
mainmsg VARCHAR2(32767);
v_errortext VARCHAR2(200);
v_errormsg VARCHAR2(200) := ' ';
v_error VARCHAR2(2000) := ' ';
mail_conn utl_smtp.connection;
attachment_text clob;
v_messageatt clob;
v_filedate varchar2(100);
CURSOR main_cursor IS
select customer_id,customer_name, to_char(validity_date,'DD-MON-YYYY') validity_date
FROM
(select( trunc(validity_date) - trunc(sysdate) ) datediff,
a.* from table_name a WHERE lei_flag = 'Y'
) lei;
main_cursor_var main_cursor%rowtype;
begin
SELECT a.smtpserver,a.smtpserverport,'' toaddress,'' fromaddress
into mailhost,mailport,message_to,msg_from
from emailsettingtable a
WHERE ROWNUM < 2;
msg_from := p_from;
msg_to := '';
IF p_mode = '89' THEN
dbms_output.put_line('89');
msg_to := message_to;
msg_subject := 'CUSTOMER report';
message := '<html><head></head>';
message := message || '<body>';
message := message || 'Dear Sir/Madam,<br>';
message := message || 'Please find attached of Cutomer LEI Expiry<br>';
message := message || '<table>';
v_messageatt := '<html><head></head>';
v_messageatt := v_messageatt || '<body><br>';
v_messageatt := v_messageatt || '<table>';
OPEN main_cursor;
LOOP
FETCH main_cursor INTO main_cursor_var;
EXIT WHEN
( main_cursor%notfound );
IF main_cursor%rowcount = 1 THEN
v_messageatt := v_messageatt || '<tr><th>CUSTOMER ID</th><th>CUSTOMER NAME</th><th>VALIDITY DATE</th></tr>';
END IF;
v_messageatt := v_messageatt || '<tr>';
v_messageatt := v_messageatt|| '<td>'|| main_cursor%rowcount|| '</td>';
v_messageatt := v_messageatt|| '<td>'|| main_cursor_var.customer_id|| '</td>';
v_messageatt := v_messageatt || '<td>'|| main_cursor_var.CUSTOMER_NAME||'</td>';
v_messageatt := v_messageatt || '<td>'|| main_cursor_var.validity_date||'</td>';
v_messageatt := v_messageatt || '</tr>';
attachment_text := v_messageatt;
END LOOP;
CLOSE main_cursor;
dbms_output.put_line('89');
v_messageatt := v_messageatt || '</table>';
message := message || '</table>';
message := message|| '<br>'|| 'Regards,<br>'|| 'IT Team <br><br> ';
message := message || '</body></html>';
mainmsg := message;
dbms_output.put_line(message);
END IF;
dbms_output.put_line('msg_subject-->' || msg_subject);
dbms_output.put_line('MESSAGE-->' || message);
IF p_mode = '89' THEN
--msg_subject := 'LERM Counterparty - Exposure Data Uploaded sucessfully ...';
msg_to := msg_to || 'abc#gmail.com';
END IF;
select to_char(sysdate,'DD_MON_YYYYHH24:MI:SS') into v_filedate
from dual;
sys.utl_mail.send_attach_raw(
sender => msg_from,
recipients => msg_to,
cc => '',
bcc => '',
subject => msg_subject,
message => mainmsg,
mime_type => 'text/html',
priority => 1,
attachment => utl_raw.cast_to_raw(attachment_text),
att_inline => true,
att_mime_type => 'text/plain; charset=us-ascii',
att_filename => 'filename_'|| v_filedate|| '.xls',
replyto => ''
);
dbms_output.put_line('2');
msg_to := '';
dbms_output.put_line('Send Sucessfully ........');
EXCEPTION
WHEN others THEN
v_errortext := substr(sqlerrm,1,200);
dbms_output.put_line(sqlerrm);
END;
You cannot create a HTML document (using <table>..<tr>, etc.) and convert this simple to RAW. Creating a Excel file purely in PL/SQL is quite painful, perhaps you will find a solution here on SO. One solution is to call an external Java procedure which generates the Excel sheet.
In general you can format your e-mail as HTML with well known formation capabilities or you can attach a binary Excel file.
Attachment for utl_mail.send_attach_raw is limited to 32k, it also have some other limitation. I recommend to use UTL_SMTP, this package is more complex to use but it gives you much more flexibility. Have a look at how to export data from log table to email body in oracle to see a full featured example.

Oracle APEX_MAIL send to multiple recipients

What is the syntax for sending emails to multiple recipients with APEX_MAIL.SEND?
The official page, https://docs.oracle.com/cd/E14373_01/apirefs.32/e13369/apex_mail.htm#AEAPI342, says; p_to
Valid email address to which the email will be sent (required). For multiple email addresses, use a comma-separated list However doesn't show an example of the syntax.
Using the example they give does anyone know the syntax?
DECLARE
l_body CLOB;
BEGIN
l_body := 'Thank you for your interest in the APEX_MAIL
package.'||utl_tcp.crlf||utl_tcp.crlf;
l_body := l_body ||' Sincerely,'||utl_tcp.crlf;
l_body := l_body ||' The APEX Dev Team'||utl_tcp.crlf;
apex_mail.send(
p_to => 'some_user#somewhere.com', -- change to your email address
p_from => 'some_sender#somewhere.com', -- change to a real senders email address
p_body => l_body,
p_subj => 'APEX_MAIL Package - Plain Text message');
END;
/
You just need to put multiple comma separated mail addresses into the p_to parameter.
See this example:
DECLARE
l_body CLOB;
BEGIN
l_body := 'Thank you for your interest in the APEX_MAIL package.'||utl_tcp.crlf||utl_tcp.crlf;
l_body := l_body ||' Sincerely,'||utl_tcp.crlf;
l_body := l_body ||' The APEX Dev Team'||utl_tcp.crlf;
apex_mail.send(
p_to => 'some_user#somewhere.com,other_user#elsewhere.com', -- separate multiple recipients with comma
p_from => 'some_sender#somewhere.com', -- change to a real senders email address
p_body => l_body,
p_subj => 'APEX_MAIL Package - Plain Text message');
END;
hth, Moritz

IF Statement within Trigger PL/SQL

I have a stored procedure within Oracle that dynamically creates triggers for all of my tables (since they trigger the same stored procedure), by constructing SQL code and executing it with Oracle's PL/SQL EXECUTE command (although I am using SQL Commander for testing). How does one correctly create an if statement within a trigger? Below is my code, which gets syntax error on the line with there IF statement starts.
CREATE OR REPLACE TRIGGER "DATABASE"."TABLE_TRIGGER"
AFTER INSERT OR DELETE OR UPDATE ON TABLE
FOR EACH ROW
DECLARE
v_op VARCHAR2(20);
BEGIN
IF INSERTING THEN
v_op := 'INSERT';
ELSIF UPDATING THEN
v_op := 'UPDATE';
ELSE
v_op := 'DELETE';
END IF;
PKG.STORED_PROC(v_op, ' - MY_COLUMN: ' || :NEW.MY_COLUMN || '', 'MY_TABLE');
END;
This is a sample of the code I used to generate the SQL code.
PROCEDURE CREATE_TRIGGERS(
IN_TABLE_OMIT IN VARCHAR2, -- IN_TABLE_OMIT is a list of tables to not create a trigger on, as CSV
OUT_RESULT OUT VARCHAR2)
AS
v_table_results SYS_REFCURSOR;
v_column_results SYS_REFCURSOR;
v_template_head VARCHAR2(512);
v_template_body VARCHAR2(512);
v_template_operation VARCHAR(512);
v_template_column VARCHAR2(128);
v_template_data VARCHAR2(1024);
v_template_foot VARCHAR2(512);
v_result VARCHAR2(1024);
BEGIN
-- Create a template for each trigger
v_template_head := 'CREATE OR REPLACE TRIGGER "MY_DB"."MY_TABLE_TRIGGER"' || chr(10);
v_template_head := v_template_head || 'AFTER INSERT OR DELETE OR UPDATE ON MY_TABLE' || chr(10);
v_template_head := v_template_head || 'FOR EACH ROW' || chr(10) || 'DECLARE' || chr(10) || 'v_op VARCHAR2(20);' || chr(10) || 'BEGIN' || chr(10) || chr(10);
v_template_operation := 'IF INSERTING THEN v_op := ''INSERT''; ELSIF UPDATING THEN v_op := ''UPDATE''; ELSE v_op := ''DELETE''; END IF;' || chr(10);
v_template_body := 'MY_DB.STORED_PROC(' || chr(10) || 'v_op,' || chr(10);
v_template_column := ''' - MY_COLUMN: '' || :NEW.MY_COLUMN || ';
v_template_foot := '''MY_TABLE'');' || chr(10) || chr(10) || 'END;';
-- Insert double quotes into template
-- Loop through each table
FOR LOOP_TABLE IN (SELECT TABLE_NAME FROM USER_TABLES ORDER BY TABLE_NAME) LOOP
IF INSTR(IN_TABLE_OMIT, LOOP_TABLE.TABLE_NAME) != 0 OR INSTR('AUDIT_TABLE', LOOP_TABLE.TABLE_NAME) != 0 THEN
FOR LOOP_COLUMN IN (SELECT COLUMN_NAME FROM ALL_TAB_COLUMNS WHERE TABLE_NAME = LOOP_TABLE.TABLE_NAME) LOOP
v_template_data := v_template_data || REPLACE(v_template_column, 'MY_COLUMN', LOOP_COLUMN.COLUMN_NAME);
END LOOP;
v_template_head := REPLACE(v_template_head, 'MY_TABLE', LOOP_TABLE.TABLE_NAME);
v_template_data := v_template_data || ''''',' || chr(10);
v_template_foot := REPLACE(v_template_foot, 'MY_TABLE', LOOP_TABLE.TABLE_NAME);
v_result := v_template_head || v_template_operation || v_template_body || v_template_data || v_template_foot;
v_template_data := '';
OUT_RESULT := chr(10) || v_result;
ELSE
dbms_output.put_line('Searched for ' || LOOP_TABLE.TABLE_NAME || ' in ' || IN_TABLE_OMIT);
END IF;
END LOOP;
END;
The trigger was successfully created when removing all semi-colons from the generated trigger statement.

Procedure not executing

I have the following procedure, but no scheduler job is getting created and I cannot find any errors while running the job. How can I debug this and what is wrong with the code?
CREATE OR REPLACE PROCEDURE test
IS
prod_no varchar2(32);
prod_date date;
employee varchar2(32);
assurer varchar2(32);
prod_description varchar2(32);
prod_days number;
assig varchar2(32);
reg_no number;
l_v number;
BEGIN
prod_no := '300';
prod_date := sysdate;
employee := 'SAM';
assurer := 'MAT';
prod_description := 'test';
prod_days := 1;
assig := 'A';
reg_no := 1;
DBMS_SCHEDULER.create_job (
job_name => DBMS_SCHEDULER.generate_job_name ('FR'),
job_type => 'PLSQL_BLOCK',
job_action => 'BEGIN test_job('
|| i_prod_no
|| ','''
|| prod_date
|| ','''
|| employee
|| ','''
|| assurer
|| ','''
|| prod_description
|| ','''
|| prod_days
|| ','''
|| assig
|| ','''
|| reg_no
|| '''); end;',
start_date => SYSDATE,
end_date => NULL,
enabled => TRUE,
comments => 'test product'
);
commit;
exception
when others then
dbms_output.put_line (dbms_utility.format_error_stack);
END test;
/
If job action is syntactically incorrect you won't get any warning, but you won't get a job either.
Here is your statement:
BEGIN test_job(300,'04-OCT-12,'SAM,'MAT,'test,'1,'A,'1'); end;
You are missing some ' to close the string values.
CREATE OR REPLACE PROCEDURE test
IS
prod_no varchar2(32);
prod_date date;
employee varchar2(32);
assurer varchar2(32);
prod_description varchar2(32);
prod_days number;
assig varchar2(32);
reg_no number;
l_v number;
l_statement varchar2(32767);
BEGIN
prod_no := '300';
prod_date := sysdate;
employee := 'SAM';
assurer := 'MAT';
prod_description := 'test';
prod_days := 1;
assig := 'A';
reg_no := 1;
l_statement := 'BEGIN test_job('
|| i_prod_no
|| ','''
|| prod_date
|| ','''
|| employee
|| ','''
|| assurer
|| ','''
|| prod_description
|| ','''
|| prod_days
|| ','''
|| assig
|| ','''
|| reg_no
|| '''); end;'
dbms_output.put_line(l_statement);
DBMS_SCHEDULER.create_job (
job_name => DBMS_SCHEDULER.generate_job_name ('FR'),
job_type => 'PLSQL_BLOCK',
job_action => l_statement,
start_date => SYSDATE,
end_date => NULL,
enabled => TRUE,
comments => 'test product'
);
commit;
exception
when others then
dbms_output.put_line (dbms_utility.format_error_stack);
END test;
/

Resources