由于涉及Oracle不久,有许多调试方法还不是很会,目前用的最多的就是PLSQL developer 自带的调试,虽然没有微软的 VS.net系列好用,比如说查看变量值的时候,如果变量是一个collection,在观察数值里面是显示不出collection里面的具体内容的,但是对于我这个初学者来说已经是大大够用了。
现在碰到有一个比较棘手的问题,就是在调试的时候,我的某些packages中的函数输入参数是我自定义的nest table,但是PLSQL 调试的时候,输入变量类型中是没有我自己定义的变量类型,这叫我如何是好?google了很长一段时间都没有发现有类似的参考文章。
经过多番反复的折磨和折腾,我终于有了一个我自己的解决方法,虽然挺笨的,但是却行之有效。
这个方法就是利用邮件~!
对,没错,就是发邮件。利用sys中的ult_smtp package的函数可以实现发送邮件的功能,这样,我在我觉得有问题的函数当中,“设置断点”,当然这个是个人虚拟的,然后在这个断点后面附上一段发送邮件的代码函数,这样,在运行整个系统的时候,程序到达这个断点,就会发送邮件到指定的邮箱,然后你就知道程序是否运行到此处,你可以在邮件的内容中写上一些信息,如此段点在那个函数中,在那一个代码块,运行的条件是什么,等等,这样就更加清晰。现在我还不知道如何把变量的值写入到邮件中,我不知道如何获取变量的值并赋值到字符串,如果可以的话,这种方法就更加完美了。
附上自己写的发送邮件的procedure
-- ============================================================
PROCEDURE send_html_mail (
-- ============================================================
p_sender_in IN VARCHAR2,
p_to_rcpt_in IN VARCHAR2,
p_cc_rcpt_in IN VARCHAR2 DEFAULT NULL,
p_bcc_rcpt_in IN VARCHAR2 DEFAULT NULL,
p_subject_in IN VARCHAR2,
p_htmlmsg_in IN VARCHAR2,
p_priority_in IN PLS_INTEGER DEFAULT NULL) IS
l_smtp_conn UTL_SMTP.connection;
l_sender VARCHAR2(32767) := p_sender_in;
l_to_rcpt VARCHAR2(32767) := p_to_rcpt_in;
l_cc_rcpt VARCHAR2(32767) := p_cc_rcpt_in;
l_bcc_rcpt VARCHAR2(32767) := p_bcc_rcpt_in;
BEGIN
l_smtp_conn := open_session;
UTL_SMTP.mail(l_smtp_conn, fetch_address(l_sender));
WHILE (l_to_rcpt IS NOT NULL) LOOP
UTL_SMTP.rcpt(l_smtp_conn, fetch_address(l_to_rcpt));
END LOOP;
WHILE (l_cc_rcpt IS NOT NULL) LOOP
UTL_SMTP.rcpt(l_smtp_conn, fetch_address(l_cc_rcpt));
END LOOP;
WHILE (l_bcc_rcpt IS NOT NULL) LOOP
UTL_SMTP.rcpt(l_smtp_conn, fetch_address(l_bcc_rcpt));
END LOOP;
-- Start body of email
UTL_SMTP.open_data(l_smtp_conn);
-- Set "From" MIME header
write_mime_header(l_smtp_conn, 'From', p_sender_in);
-- Set "To" MIME header
write_mime_header(l_smtp_conn, 'To', p_to_rcpt_in);
-- Set "Cc" MIME header
write_mime_header(l_smtp_conn, 'Cc', p_cc_rcpt_in);
-- Set "Bcc" MIME header
write_mime_header(l_smtp_conn, 'Bcc', p_bcc_rcpt_in);
-- Set "Subject" MIME header
write_mime_header(l_smtp_conn, 'Subject', p_subject_in);
-- Set "Reply-To" MIME header
write_mime_header(l_smtp_conn, 'Reply-To', c_reply_to);
-- Set "Content-Type" MIME header
write_mime_header(l_smtp_conn, 'Content-Type', c_multipart_mime_type);
-- Set "X-Mailer" MIME header
write_mime_header(l_smtp_conn, 'X-Mailer', c_mailer_id);
-- Set priority:
-- High Normal Low
-- 1 2 3 4 5
IF (p_priority_in IS NOT NULL) THEN
write_mime_header(l_smtp_conn, 'X-Priority', p_priority_in);
END IF;
-- Send an empty line to denote end of MIME headers and
-- beginning of message body.
UTL_SMTP.write_data(l_smtp_conn, UTL_TCP.crlf);
-- Set upper HTML boundary
write_boundary(l_smtp_conn, FALSE);
write_text(l_smtp_conn,'content-type: text/html;' || UTL_TCP.crlf || UTL_TCP.crlf);
-- Send HTML content
write_text(l_smtp_conn, p_htmlmsg_in);
-- Set lower HTML boundary
write_boundary(l_smtp_conn, TRUE);
-- End mail msg
end_mail(l_smtp_conn);
-- End mail connection
end_session(l_smtp_conn);
EXCEPTION
WHEN UTL_SMTP.transient_error OR UTL_SMTP.permanent_error THEN
end_session(l_smtp_conn);
ERR_RAISE_PKG.record_and_continue (
p_err_in => SQLCODE,
p_msg_in => 'Failed to send mail due to error : ' || SQLERRM);
WHEN UTL_SMTP.invalid_operation THEN
end_session(l_smtp_conn);
ERR_RAISE_PKG.record_and_continue (
p_err_in => SQLCODE,
p_msg_in => 'Invalid Operation due to error : ' || SQLERRM);
WHEN OTHERS THEN
end_session(l_smtp_conn);
ERR_RAISE_PKG.record_and_continue (
p_err_in => SQLCODE);
END send_html_mail;