For nylig fik jeg opgaven at bygge et slags mailklientsystem i Oracle Apex. Kravet var at vise meddelelserne fra e-mail-indbakken på en side for en bestemt konto, så brugeren kan se e-mail-beskederne, vedhæftede filer og kan slette meddelelserne osv. Men i Oracle er der pakker til at sende e-mails ved hjælp af UTL_SMPT, UTL_MAIL , og APEX_MAIL, og der er ingen pakke til at hente postbeskederne fra postkassen. Efter at have søgt lidt fandt jeg en PL/SQL MAIL_CLIENT API skrevet af Carsten Czarski, hvormed man nemt kan hente beskederne fra postkassen. Og i dette selvstudie giver jeg eksempler på MAIL_CLIENT API kommandoer og procedurer. Først skal du downloade og installere PL/SQL MAIL_CLIENT ved at bruge følgende link:
Download PL/SQL MAIL_CLIENT API
PL/SQL MAIL_CLIENT API-eksempler
I de følgende sektioner giver jeg eksemplerne trin for trin på at oprette forbindelse ved hjælp af MAIL_CLIENT-pakken, derefter hvordan man får vist postkasseindhold, hvordan man får vist en bestemt besked og dens vedhæftede filer osv.
Eksempel-1:Opret forbindelse ved hjælp af MAIL_CLIENT
For at oprette forbindelse til mailserveren skal du bruge følgende PL/SQL-kode:
begin mail_client.connect_server( p_hostname => 'YourMailServer.com', p_port => YourPortIntegerValue, p_protocol => mail_client.protocol_IMAP, -- or mail_client.protocol_POP3 p_userid => 'YourUserID', p_passwd => 'YourPassword', p_ssl => true -- true or false depends on your mailbox ); mail_client.open_inbox; dbms_output.put_line('Mailbox successfully opened.'); dbms_output.put_line('The INBOX folder contains '||mail_client.get_message_count||' messages.'); end; /
Skift værtsnavn, port, protokol, bruger-id og adgangskode i henhold til dine postkasseindstillinger. Og efter at have udført ovenstående kode vil du blive forbundet til din postkasse. Nu vil du helt sikkert se indholdet af din indbakke. Brug følgende kommando:
Eksempel-2:Se postkassens indhold
For at se postkassens indhold ved hjælp af PL/SQL MAIL_CLIENT API skal du køre følgende SQL-sætning for at se de seneste beskeder øverst:
select * from table(mail_client.get_mail_headers()) order by msg_number desc;
Du får følgende kolonner fra ovenstående forespørgsel:
- MSG_NUMBER
- EMNE
- AFSENDER
- SENDER_EMAIL
- SENT_DATE
- CONTENT_TYPE
- SLETTET
- Nogle flere flagkolonner
Eksempel-3:Få strukturen af e-mailbeskeden
Strukturen af en e-mail-meddelelse indeholder oplysningerne, såsom hvilken PARTINDEX nummer indeholder brødteksten i almindeligt tekstformat, brødteksten i HTML-format og mailens vedhæftede filer. Antag, at du ønsker at få den almindelige tekst af e-mails kropsdel køre følgende SQL-forespørgsler:
select * from table(mail_client.get_message(1).get_structure());
Værdien 1 ovenfor er MSG_NUMBER af beskederne. Det vil give dig følgende oplysninger:
- PARTINDEX
- PARENTINDEX
- CONTENT_TYPE
- STØRRELSE osv.
PARTINDEX | PARENTINDEX | CONTENT_TYPE | STØRRELSE |
0,0 | 0 | tekst/almindelig | 2993 |
0,1 | 1 | tekst/html | 94849 |
1 | 1 | multipart/rapport | 39398 |
Eksempel-4:Hent meddelelsesteksten
Hvis du f.eks. ønsker at få meddelelsesteksten i almindeligt tekstformat for meddelelse nummer 1, skal du køre følgende forespørgsel:
SELECT Mail_Client.Get_Message(1 /* specify message number */).get_bodypart_content_varchar2('0,0') FROM Dual;
Bemærk: 0,0 ovenfor er værdien af PARTINDEX-kolonnen for tekst/almindelig indholdstype.
For at få brødteksten i HTML-format, kører vi følgende forespørgsel med PARTINDEX kolonneværdi 0,1. Det vil returnere kroppen i CLOB :
SELECT Mail_Client.Get_Message(1 /* specify message number */).get_bodypart_content_clob('0,1') FROM Dual;
Eksempel-5:Hent den vedhæftede post
På samme måde kan du hente den vedhæftede mail ved hjælp af PARTINDEX værdi 1 som parameter, som vist i nedenstående forespørgsel:
SELECT Mail_Client.Get_Message(1 /* specify message number */).Get_Bodypart_Content_Blob('1') FROM Dual;
Eksempel-6:Slet en mailbesked
Nedenfor er et eksempel på den lagrede procedure for at slette e-mail-meddelelsen ved hjælp af MAIL_CLIENT API.
Create or Replace PROCEDURE Delete_Mail_Msg(i_Msg_Number IN NUMBER) IS t_Msg Mail_t; BEGIN Mail_Client.Connect_Server(p_Hostname => 'YourMailServer', p_Port => MailServerPort, p_Protocol => Mail_Client.Protocol_Imap, p_Userid => 'username', p_Passwd => 'password', p_Ssl => TRUE); Mail_Client.Open_Inbox; t_Msg := Mail_Client.Get_Message(i_Msg_Number); t_Msg.Mark_Deleted(); Mail_Client.Expunge_Folder; Mail_Client.Close_Folder; Mail_Client.Disconnect_Server; EXCEPTION WHEN OTHERS THEN IF Mail_Client.Is_Connected() = 1 THEN Mail_Client.Close_Folder; Mail_Client.Disconnect_Server; END IF; Raise; END Delete_Mail_Msg;
Kald nu bare ovenstående procedure for at slette en specifik e-mail-besked, sendt som parameter. Nedenfor er eksemplet:
Begin Delete_Mail_Msg(3); End;
Ovenstående opfordring til procedure DELETE_MAIL_MSG vil fjerne e-mail-meddelelse nummer 3 fra serveren.
Giver også eksemplet nedenfor for at gemme alle indbakkemeddelelser til en tabel med mailens brødtekst og vedhæftet fil. Følg disse trin:
Trin-1:Opret en tabel.
CREATE TABLE MAIL_INBOX ( MSG_NUMBER INTEGER, SUBJECT VARCHAR2(4000), SENT_DATE DATE, SENDER_EMAIL, BODY_TEXT CLOB, MAIL_ATTACHMENT BLOB) /
Trin 2:Opret en Oracle PL/SQL Stored Procedure
CREATE OR REPLACE PROCEDURE LOAD_EMAILS IS
CURSOR c_Inbox IS
SELECT Msg_Number,
Subject,
Sender,
Sender_Email,
Sent_Date,
Content_Type
FROM TABLE(Mail_Client.Get_Mail_Headers())
ORDER BY Msg_Number DESC;
c_Clob CLOB;
b_blob BLOB;
t_Msg Mail_t;
v_Partindex VARCHAR2(100);
BEGIN
Mail_Client.Connect_Server(p_Hostname => 'YOURMAILSERVER',
p_Port => YOURPORT,
p_Protocol => Mail_Client.Protocol_Imap,
p_Userid => 'USERID',
p_Passwd => 'PASSWORD',
p_Ssl => TRUE);
Mail_Client.Open_Inbox;
FOR c IN c_Inbox LOOP
Dbms_Lob.Createtemporary(Lob_Loc => c_Clob,
Cache => TRUE,
Dur => Dbms_Lob.Call);
Dbms_Lob.Createtemporary(Lob_Loc => b_blob,
Cache => TRUE,
Dur => Dbms_Lob.Call);
IF Substr(c.Content_Type,
1,
9) = 'multipart' THEN
v_Partindex := NULL;
BEGIN
SELECT Partindex
INTO v_Partindex
FROM TABLE(Mail_Client.Get_Message(c.Msg_Number).Get_Structure())
WHERE Substr(Content_Type,
1,
9) = 'text/html';
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
IF v_Partindex IS NOT NULL THEN
BEGIN
SELECT Mail_Client.Get_Message(c.Msg_Number).Get_Bodypart_Content_Clob(v_Partindex)
INTO c_Clob
FROM Dual;
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
BEGIN
SELECT Mail_Client.Get_Message(c.Msg_Number).Get_Bodypart_Content_BLOB('1')
INTO b_blob
FROM Dual;
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
END IF;
INSERT INTO mail_inbox
(Msg_Number,
Subject,
Sent_Date,
Sender_email,
Body_Text,
mail_attachment)
VALUES
(c.Msg_Number,
c.Subject,
c.Sent_Date,
c.Sender_Email,
c_Clob,
b_blob);
ELSIF Substr(c.Content_Type,
1,
9) = 'text/html' THEN
BEGIN
SELECT Mail_Client.Get_Message(c.Msg_Number).Get_Content_Clob()
INTO c_Clob
FROM Dual;
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
INSERT INTO mail_inbox
(Msg_Number,
Subject,
Sent_Date,
Sender_email,
Body_Text)
VALUES
(c.Msg_Number,
c.Subject,
c.Sent_Date,
c.Sender_Email
c_Clob);
END IF;
END LOOP;
COMMIT;
Mail_Client.Close_Folder;
Mail_Client.Disconnect_Server;
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
IF Mail_Client.Is_Connected() = 1 THEN
Mail_Client.Close_Folder;
Mail_Client.Disconnect_Server;
END IF;
RAISE;
END LOAD_EMAILS;
Kør ovenstående procedure for at udfylde tabellen med e-mail-meddelelser som følger:
Begin
Load_Emails;
End;
Nu kan du forespørge tabellen MAIL_INBOX for at se e-mail-beskederne.
Select * from mail_inbox;Download dette projekt fra GitHub
Relaterede selvstudier:
- Hvordan får man BLOB fra fil i PL/SQL?
- Oracle UTL_SMTP:Send mail med vedhæftet eksempel ved hjælp af Oracle Wallet-godkendelse