|
12.1.0.1 и UTL_SMTP
#39259309
Ссылка:
Ссылка на сообщение:
Ссылка с названием темы:
Ссылка на профиль пользователя:
|
Участник
Откуда: Dortmund
Сообщения: 355
|
|
Коллеги у кого 12.1.0.1 есть и кто UTL_SMTP использует прогоните прилагаемую дурку.
Перед прогоним переменные p_smtp_server, p_sender и p_recipient нужно установить и set serveroutput on.
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111. 112. 113. 114. 115. 116. 117. 118. 119. 120. 121. 122. 123. 124. 125. 126. 127. 128. 129. 130. 131. 132. 133. 134. 135. 136. 137. 138. 139. 140. 141. 142. 143. 144. 145. 146. 147. 148. 149. 150. 151. 152. 153. 154. 155. 156. 157. 158. 159. 160. 161. 162. 163. 164. 165. 166. 167. 168. 169. 170. 171. 172. 173. 174. 175. 176. 177. 178. 179. 180. 181. 182. 183. 184. 185. 186. 187. 188. 189. 190. 191. 192. 193. 194. 195. 196. 197. 198. 199. 200. 201. 202. 203. 204. 205. 206. 207. 208. 209. 210. 211. 212. 213. 214. 215. 216. 217. 218. 219. 220. 221. 222. 223. 224. 225. 226. 227. 228. 229. 230. 231. 232.
CREATE OR REPLACE PROCEDURE GPU_MAIL_BUG10201
IS
p_smtp_server VARCHAR2(64) := '127.0.0.1';
p_sender VARCHAR2(128) := 'root@localhost';
p_recipient VARCHAR2(128) := 'root@localhost';
p_subj VARCHAR2(128) := 'Error in mail communication';
p_body VARCHAR2(128) := utl_tcp.CRLF || chr(46);
p_smtp_port NUMBER := 25;
g_sqlerrm VARCHAR2(2000);
v_con UTL_SMTP.connection;
v_ret UTL_SMTP.reply;
v_msg VARCHAR2(32000);
v_headers VARCHAR2(32000);
V_BOUNDARY VARCHAR2 (256) := '-----030503071209010200030100';
v_retcode NUMBER:= 0;
v_repls UTL_SMTP.replies;
v_body CLOB;
v_data_lenb NUMBER := 0;
PROCEDURE trace_it(p_text IN VARCHAR2)
IS
BEGIN
DBMS_OUTPUT.put_line(TO_CHAR(SYSTIMESTAMP, 'HH24:MI:SS.FF3') || ' ' || p_text);
END trace_it;
PROCEDURE trace_reply(p_reply IN UTL_SMTP.reply)
IS
BEGIN
trace_it('<--' || p_reply.code || ' ' || p_reply.text);
END trace_reply;
FUNCTION create_header(p_name IN VARCHAR2,
p_value IN VARCHAR2)
RETURN VARCHAR2
IS
v_header VARCHAR2(10000);
begin
RETURN p_name || ': ' || p_value || utl_tcp.CRLF;
END create_header;
FUNCTION do_mail_from(p_smtp_conn IN OUT NOCOPY UTL_SMTP.connection,
p_sender IN VARCHAR2)
RETURN UTL_SMTP.reply
IS
v_ret UTL_SMTP.reply;
BEGIN
v_ret :=UTL_SMTP.mail(p_smtp_conn, p_sender);
trace_reply(v_ret);
RETURN v_ret;
END do_mail_from;
FUNCTION do_rcpt(p_smtp_conn IN OUT NOCOPY UTL_SMTP.connection,
p_recipient IN VARCHAR2)
RETURN UTL_SMTP.reply
IS
v_ret UTL_SMTP.reply;
BEGIn
v_ret := UTL_SMTP.rcpt(p_smtp_conn, p_recipient);
trace_reply(v_ret);
RETURN v_ret;
END do_rcpt;
FUNCTION prepare_subj(p_subj IN VARCHAR2)
RETURN VARCHAR2
IS
v_ret VARCHAR2(32000);
v_enc_start VARCHAR2(32) := '=?UTF-8?Q?';
v_enc_end VARCHAR2(32) := '?=';
v_max_line_len NUMBER := 75 - length(v_enc_start) - length(v_enc_end);
v_ch VARCHAR2(1);
v_ch_encoded VARCHAR2(32);
v_line_buff VARCHAR2(32000):= NULL;
BEGIN
FOR i in 0..(length(p_subj) -1) LOOP
v_ch := substr(p_subj, i +1, 1);
v_ch_encoded := UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.QUOTED_PRINTABLE_ENCODE(UTL_RAW.CAST_TO_RAW(v_ch)));
IF (NVL(length(v_line_buff), 0) + length(v_ch_encoded)) < v_max_line_len THEN
v_line_buff := v_line_buff || v_ch_encoded;
ELSE
v_ret := v_ret || v_enc_start || v_line_buff || v_enc_end;
v_line_buff := v_ch_encoded;
END IF;
END LOOP;
IF v_line_buff IS NOT NULL AND length(v_line_buff) > 0 THEN
v_ret := v_ret || v_enc_start || v_line_buff || v_enc_end;
END IF;
RETURN v_ret;
END prepare_subj;
PROCEDURE send_body(p_smtp_conn IN OUT NOCOPY UTL_SMTP.connection,
p_body IN CLOB)
IS
i pls_integer := 1;
len pls_integer;
buff_size pls_integer := 16000;
l_raw raw(16000);
v_chunk_counter BINARY_INTEGER := 0;
l_step PLS_INTEGER := 12000;
v_buff VARCHAR2(12000);
v_raw_buff RAW(32000);
BEGIN
len := dbms_lob.getlength(p_body);
trace_it('start body is transmission');
FOR i IN 0 .. TRUNC((DBMS_LOB.getlength(p_body) - 1 )/l_step) LOOP
v_buff := DBMS_LOB.substr(p_body, l_step, i * l_step + 1);
trace_it('buffer:' || v_buff);
trace_it('len(buffer) characters:' || length(v_buff));
v_raw_buff := UTL_ENCODE.QUOTED_PRINTABLE_ENCODE(UTL_RAW.CAST_TO_RAW(v_buff));
trace_it('len(raw data) bytes:' || lengthb(v_raw_buff));
trace_it('raw data:');
trace_it(v_raw_buff);
UTL_SMTP.WRITE_RAW_DATA(p_smtp_conn, v_raw_buff);
v_chunk_counter := v_chunk_counter +1;
END LOOP;
trace_it('body is trasmitted');
END send_body;
BEGIN
trace_it('start connect to:' || p_smtp_server);
v_ret := UTL_SMTP.open_connection(p_smtp_server, NVL(p_smtp_port,25), v_con);
trace_reply(v_ret);
IF v_ret.code <>220 THEN
RETURN ;
END IF;
v_ret := UTL_SMTP.helo(v_con, p_smtp_server);
trace_reply(v_ret);
IF v_ret.code <>250 THEN
RETURN;
ELSE
trace_it('helo OK');
END IF;
v_ret := do_mail_from(v_con, p_sender);
trace_reply(v_ret);
IF v_ret.code <>250 THEN
RETURN ;
ELSE
trace_it('mail from OK');
END IF;
v_ret := do_rcpt(v_con,p_recipient);
trace_reply(v_ret);
IF v_ret.code not in (250, 251) THEN
RETURN ;
ELSE
trace_it('rcpt to OK');
END IF;
UTL_SMTP.open_data(v_con);
trace_it('open_data OK');
v_headers := create_header('Mime-Version', '1.0')
|| create_header('From', '<' || p_sender || '>')
|| create_header('To', '<' || p_recipient || '>');
v_headers := v_headers || create_header('Subject', prepare_subj(p_subj));
v_headers := v_headers
|| create_header('Content-Type', 'text/plain;charset=utf-8')
|| create_header('Content-Transfer-Encoding', 'quoted-printable');
UTL_SMTP.write_data(v_con, v_headers || utl_tcp.CRLF);
--UTL_SMTP.write_data(v_con, utl_tcp.CRLF);
--UTL_SMTP.write_data(v_con, utl_tcp.CRLF);
trace_it('headers OK');
send_body(v_con, TO_CLOB(p_body));
--UTL_SMTP.write_data(v_con, utl_tcp.CRLF);
trace_it('body OK');
v_ret := UTL_SMTP.close_data(v_con);
trace_it('Data channel closed:');
trace_reply(v_ret);
v_ret := UTL_SMTP.quit(v_con);
trace_it('Session quited:');
trace_reply(v_ret);
if v_ret.code <> 221 THEN
trace_it('Error');
ELSE
trace_it('Completed OK');
END IF;
EXCEPTION
WHEN UTL_SMTP.invalid_operation THEN -- Operation is invalid
-- emulate failure (RFC3463)
v_ret.code := 430;
v_ret.text := 'Invalid operation exception raised by UTL_SMTP';
RETURN;
WHEN UTL_SMTP.transient_error THEN -- Transient server error in 400 range
-- emulate
v_ret.code := 421;
v_ret.text := 'Service not available';
RETURN ;
WHEN UTL_SMTP.permanent_error THEN -- Permanent server error in 500 range
-- emulate
v_ret.code := 500;
v_ret.text := 'Permanent Error exception raised by UTL_SMTP';
RETURN ;
WHEN UTL_SMTP.unsupported_scheme THEN -- Unsupported authentication scheme
-- emulate
v_ret.code := 1;
v_ret.text := 'Unsupported Scheme exception raised by UTL_SMTP';
RETURN ;
WHEN UTL_SMTP.no_supported_scheme THEN -- No supported authentication scheme
-- emulate
v_ret.code := 2;
v_ret.text := 'No supported Scheme exception raised by UTL_SMTP';
RETURN ;
WHEN others THEN
g_sqlerrm := sqlerrm;
-- emulate
v_ret.code := 3;
v_ret.text := SUBSTR(g_sqlerrm, 1, 500);
RETURN ;
END GPU_MAIL_BUG10201;
|
|
|