# nach einer Fehlermeldung fortfahren ORACLE



## cullmann (7. Februar 2007)

servus alle zusammen,

ich schreibe gerade an nem package das mail veschicken soll, 
wenn in der DB eine falsche Email (also der SMTP akzepiert diese nicht) auftaucht bekomme ich folgende Fehlermeldung:


```
ORA-20000: Failed to send mail due to the following error: ORA-29279:
Permanenter SMTP-Fehler: 554 <test@test.de>: Relay access denied
ORA-06512: in "ICAP.ICAP_MAIL", Zeile 107
ORA-06512: in Zeile 4
```

so das soll ja auch so sein, was aber vermieden werden sollte ist die tatsche das die andern mail nicht mehr verschickt werden.
Alos meine frage ist: Kann ich nachdem ein Fehler geworfen wurde, die SP /Funktion weiterlaufen lassen. 
Die Fehlermeldung würde ich dann in ne logFile schreiben (auch wenn ich keinen ahnung hab wie das gehen soll).
also mein package body sieht so aus:


```
CREATE OR REPLACE
PACKAGE BODY iCAP_Mail 
as
c utl_smtp.connection;


/*Die Methode send_subject übergibt den Betreff an den Mailserver, dabei werden
auch Umlaufte (ä,ü,ö;...) richtig übermittelt. Anderfalls würde statt Ü 
ein U übermittelt*/
PROCEDURE send_subject(subject IN VARCHAR2) 
IS
BEGIN
  utl_smtp.write_data(c, 'Subject: =?ISO-8859-15?Q?'||
  utl_raw.cast_to_varchar2(utl_encode.quoted_printable_encode
  (utl_raw.cast_to_raw(subject)))||'?='||utl_tcp.crlf);
END send_subject;


Procedure senden(
                --absender_in in varchar2,
                empfaenger_in in varchar2,
                subject_in in varchar2,
                mailbody_in in varchar2)
as
crlf      VARCHAR2(2) := chr(13)||chr(10);
v_how Varchar2(2):='To';

BEGIN
  
  c := utl_smtp.open_connection(mailserver);  -- Verbindung herstellen
  DBMS_OUTPUT.put_line('Fehler 1');

  utl_smtp.helo(c, mailserver);  
  DBMS_OUTPUT.put_line('Fehler 2');
  utl_smtp.mail(c, absender_db);  -- Absender bekanntgeben
  DBMS_OUTPUT.put_line('Fehler 3');
  
  
  
  utl_smtp.rcpt(c, '<'||empfaenger_in||'>'); --<----------------------Hier wird der Fehler verursacht
  DBMS_OUTPUT.put_line('Fehler 4');
  
  DBMS_OUTPUT.put_line('Fehler 5');
  
-- Jetzt der eigentliche Datenteil
  utl_smtp.open_data(c);
-- 8Bit einstellen, damit ist es auch möglich umlaute in Mailbody zu verschicken
  utl_smtp.write_data(c, 'MIME-version: 1.0' || utl_tcp.CRLF);
  utl_smtp.write_data(c, 'Content-Type: text/html;charset=ISO-8859-15'|| utl_tcp.CRLF);
  utl_smtp.write_data(c, 'Content-Transfer-Encoding: 8bit' || utl_tcp.CRLF);

  /*An dieser Stelle wird dem Smtp*/
  utl_smtp.write_data(c, v_how||': <'||empfaenger_in||'>'||utl_tcp.CRLF);

  -- Subject senden
  send_subject(subject_in);
  utl_smtp.write_data(c,utl_tcp.CRLF);
  -- Jetzt kommt erst der eigentliche Mailbody
  utl_smtp.write_raw_data(c, utl_raw.cast_to_raw(mailbody_in));
  
  utl_smtp.close_data(c);--Verbindung wird abgebaut
  utl_smtp.quit(c);

END senden;


Function mail_to_course(
                          --absender_in in varchar2, 
                          FachID_in number,
                          SemesterID_in in number,
                          subject_in in varchar2, 
                          mailbody_in in varchar2)
                          return number
is                        
                          
TYPE empfaenger_rec IS RECORD (empfaenger student.email%TYPE);
TYPE array_tab IS TABLE OF empfaenger_rec INDEX BY BINARY_INTEGER;

mail_tab array_tab;
v_count number := 0;
BEGIN

execute immediate   'select email from student 
                    where studentid in (select studentid from stud_bezieh_SF
                                        where SemesterID= '|| SemesterID_in || 
                                        'and fachid ='||fachid_in ||')'
                    bulk collect into mail_tab;
                      
for i in mail_tab.FIRST..mail_tab.LAST 
  loop
    DBMS_OUTPUT.put_line('Laeufts bis hier?');
    senden(mail_tab(i).empfaenger, subject_in, mailbody_in);
    --senden(absender_in, mail_tab(i).empfaenger, subject_in, mailbody_in);
    v_count :=v_count+1;
  end loop;

return(v_count);
EXCEPTION
       WHEN utl_smtp.transient_error OR utl_smtp.permanent_error THEN
         BEGIN
           utl_smtp.quit(c);
         EXCEPTION       
          WHEN utl_smtp.transient_error OR utl_smtp.permanent_error THEN
             NULL; -- When the SMTP server is down or unavailable, we don't
                   -- have a connection to the server. The quit call will
                   -- raise an exception that we can ignore.
         END;
         raise_application_error(-20000,
           'Failed to send mail due to the following error: ' || sqlerrm);
return(0);--muss noch verbessert werden, vielleicht text als rückgabewert

END mail_to_course;

END iCAP_Mail;
```

Wäre sehr dankbar wenn ihr mir helfen könnten, auch bei der sache mit der LogFile.

Danke 

Cullmann


----------



## Ritchie_Fomm (7. Februar 2007)

Hallo, 

in Oracle PL/SQL wird durch jeden [begin end] Block ein eigener procedureblock gebildet. In diesem kanns du dann die Exception abfangen und mit NULL übergehen. 

Kleines Beispiel:

```
PROCEDURE P_Test
AS
 lID t_test.id%TYPE;
BEGIN
-- fetch too many rows exception
     SELECT t.id
     INTO lID
     FROM t_test t
     WHERE t.id IS NOT NULL;
END;

PROCEDURE P_Test_2
AS
BEGIN
-- get too many rows exception
     P_Test;
     EXCEPTION WHEN 
          OTHERS THEN NULL; -- do nothing
END;
```

D.h. bei der Procedure welche die Exception wirft hängst du dein Exceptionhandling dran. Ich hoffe damit ist dir geholfen.

Grüße
R.


----------



## cullmann (7. Februar 2007)

Servus,
danke das ist zumindest was, aber gibts das nicht ne elegantere lösung. In Java gibts doch das Schlüsselwort continue, dannn wird torzt fehlermeldung fortgefahren. Hatte gehofft es gibt auch sowas in PL/SQL


cullmann


----------



## Ritchie_Fomm (7. Februar 2007)

Hallo, 

im prinzip fährst du ja fort statt NULL kannst du auch eine Methode aufrufen welche Daten in eine LOGTable schreibt. Deine Procedure bzw. Ablauf fährt trotzdem fort. Du brauhst hier nur kein Schlüsselwort. Wozu auch?

Grüße
R.


----------



## cullmann (7. Februar 2007)

gut ok, dank.

Aber samma du hast nicht zufällig gerade ein linke parat indem ich was über die LogFiles finde. Hab keine Ahnung wie ich selber logfiles anlege, bzw. wie ich dann in diese schreibe. Hab auch schon gegooglt aber nix gefunden.

cullmann


----------



## Ritchie_Fomm (7. Februar 2007)

Hallo, 

es müsste mit dem spoolfile klappen

```
spool c:\\deinFile.log
--####################################
-- schreibe was mit dbms_output rein
--####################################
spool off
```

müsste so klappen. Ich persönlich schreibe eigntlich immer alles per anonymer Transaktion in eine LogTable ist nachher einfacher Fehler bzw. bestimmte Passagen rauszusuchen.

Es gibt wohl auch noch ein Fileschreiber von Oracle, der schreibt meines Wissens jedoch nur auf dem DB Server ein File.

Grüße
R.


----------



## cullmann (7. Februar 2007)

ja aber mit spool kann ich nur die ausgabe in eine file umleiten, ich will aber die fehlermeldung, welche ich in ner var. abgefangen hab in die LogFile schreiben.

Schöner Käse in der doku kann ich auch nix finden

cullmann


----------



## Ritchie_Fomm (7. Februar 2007)

Hallo, 

aber mit dbms_output müsstest du eigentlich auch Variablen ins spoolfile schreiben können.

Grüße
R.


----------



## cullmann (7. Februar 2007)

ja ne, das läuft so net. 

So ne sauererei, finde auch in der doku nix wie man eine logfile anlegt geschweige denn eine Logfile beschreibt.....

Es muss aber sowas geben mit insert into logdat soll das wohl gehen, hab aber nix zu dem thema im netz oder der doku gefunden... schöner käse


----------

