Skip to Main Content
  • Questions
  • Request to know if the syntax for pl/sql in correct?

Breadcrumb

Question and Answer

Connor McDonald

Thanks for the question, Cornellius.

Asked: January 25, 2017 - 6:44 pm UTC

Last updated: January 26, 2017 - 4:27 pm UTC

Version: Oracle 11g

Viewed 1000+ times

You Asked

I developed a stored procedure that send notification emails. The stored procedure name is, "a_test_email". I created an explicit cursors named, "crs" and the cursor queries the user_objects to check if any objects are INVALID. I am having issues with how "a_test_email" stored procedure loops to send emails. The "a_test_email" stored procedure loop - sends an email for each row (i.e. record), instead of looping through the cursor "crs" to get all records that have an INVALID status and then sends one email the show all rows (i.e. records) together in one email. I would like to know how to correct the "a_test_email" stored procedure, so that I do not get 100,000 separate emails from my explicit cursors, "crs". Thank you. The sample is listed below....

F.Y.I. - I attempted to use LiveSQL, but it was confusing when navigating through it.

create or replace procedure a_test_email is
v_cnt int;
v_object_name varchar2;
v_object_type varchar2;
v_status varchar2;

cursor crs_total is
select count(*)
from user_objects
where status = 'INVALID';

cursor crs is
select object_name, object_type, status
from user_objects
where status = 'INVALID';

BEGIN
open crs_total;
fetch crs_total into v_cnt;

open crs;
LOOP
fetch crs into v_object_name, v_object_type, v_status;

email_format_test(p_to => 'test_email_1@testing.com',
p_cc => 'test_email_2@testing.com',
p_from => 'test_email_3@testing.com',
p_subject => 'INVALID OBJECTS '||v_cnt,
p_message => 'Oracle found '||v_object_name||' '||v_object_type||' as an '||v_status||' object in your database. Please troubleshoot issue. Thank you.',
p_smpt_host => '11.11.111.11');

EXIT WHEN crs%NOTFOUND;
END LOOP;

CLOSE crs_total;
CLOSE crs;
END;

--------------------------------------------------------
---Below is the Stored Procedure that send the emails---
--------------------------------------------------------
--------------------------------------------------------
create or replace procedure email_format_test(p_to => IN varchar2,
p_cc => IN varchar2,
p_from => IN varchar2,
p_subject => IN varchar2,
p_message => IN varchar2,
p_smpt_host => IN varchar2,
p_smpt_port => IN number default 25)
as
v_mail_conn utl_smtp.connection;
BEGIN
v_mail_conn := utl_smtp.open_connection(p_smtp_host, p_smtp_port);
utl_smtp.helo(v_mail_conn, p_smtp_host);
utl_smtp.mail(v_mail_conn, p_from);
utl_smtp.rcpt(v_mail_conn, p_to);

utl_smtp.open_data(v_mail_conn);

utl_smtp.write_data(v_mail_conn, 'Date: '||TO_CHAR(sysdate, 'DD-MON-YYYY HH12:MI:SS')||utl_tcp.crlf);
utl_smtp.write_data(v_mail_conn, 'To: '||p_to||utl_tcp.crlf);
utl_smtp.write_data(v_mail_conn, 'From: '||p_from||utl_tcp.crlf);
utl_smtp.write_data(v_mail_conn, 'Subject: '||p_subject||utl_tcp.crlf);
utl_smtp.write_data(v_mail_conn, 'Reply To: '||p_from||utl_tcp.crlf||utl_tcp.crlf);

utl_smtp.write_data(v_mail_conn, p_message ||utl_tcp.crlf||utl_tcp.crlf);
utl_smtp.close_data(v_mail_conn);

utl_smtp.quit(v_mail_conn);
END;

and Chris said...

I do something like:

- Bulk collect the results of the cursor into an array
- Loop through the array, building up the body of your email from this
- Once you've fetched all the values, then send the email:

e.g.:

declare
  email_body varchar2(32767) := 'Oracle found ';
  messages   dbms_sql.varchar2_table;
  cursor crs is
    select v_object_name||' '||v_object_type||' with status '||v_status msg
    bulk   collect into messages
    from   user_objects
    where  status = 'INVALID';

begin

  open crs;
  
  loop
    fetch crs bulk collect into messages limit 100;
    exit when messages.count = 0;
    
    for i in messages.first .. messages.last loop
      email_body := email_body  || ', ' || messages(i);
    end loop;
  end loop;
  
  email_body := email_body || ' object in your database. Please troubleshoot issue. Thank you.';
  
  email_format_test(p_to => 'test_email_1@testing.com',
    p_cc => 'test_email_2@testing.com',
    p_from => 'test_email_3@testing.com',
    p_subject => 'INVALID OBJECTS '||v_cnt,
    p_message => email_body,
    p_smpt_host => '11.11.111.11'
  );

end;

Rating

  (2 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

Thank you for your response

Cornellius Amey, January 26, 2017 - 10:09 pm UTC

I am getting an error msg statement ORA-06550 ORA-00904 invalid indentifier. Can you point me in the direction of what this means?

Terrific answer. Omit my last comment. I caused the error.

Cornellius Amey, January 26, 2017 - 10:15 pm UTC

Nevermind I figure out what I was doing wrong.
Omit my last comment. I figured out what I did wrong. THANKS FOR YOUR HELP. You were very helpful.

More to Explore

PL/SQL demos

Check out more PL/SQL tutorials on our LiveSQL tool.

PL/SQL docs

PL/SQL reference manual from the Oracle documentation library