Announcement

Collapse
No announcement yet.

Probleme mit xp_findnextmsg - xp_readmail

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Probleme mit xp_findnextmsg - xp_readmail

    Hallo Spezialisten,<br><br>ich versuche nun schon geraume Zeit über die Stored Procedure xp_readmail den Maileingang des SQL-Servers auszulesen. Der Witz dabei ist, dass die Procedure nach dem Aufruf ohne Parameter auch sehr schön beide Mails aus dem Posteingangskorb als Recordset anzeigt. Deklariere ich allerdings OUTPUT-Variablen, um an die einzelnen Werte heranzukommen, funktioniert das nicht! Also:<br><br><b>exec xp_findnextmsg @msg_id OUTPUT</b> - gibt eine Ergebnismenge zurück, die Variable @msg_id bleibt aber null<br><b>exec xp_readmail</b> - gibt mir auch eine Ergebnismenge zurück, die Output-Variablen bleiben aber auch leer.<br><br>Kann mir jemand erklären wie ich verfahren kann? Ich habe auch schon versucht über <b>insert into Hilfstabelle exec xp_findnextmsg</b>an die Einträge auf diese Weise heranzukommen, aber auch das funktioniert nicht.<br>Gibt es vielleicht einen Umweg? Für jede Hilfe jetzt schon vielen Dank! (xp_sendmail klappt übrigends prima)<br><br>Olle

  • #2
    Hallo,

    man muss das Beispiel aus BOL für xp_findnextmsg exakt nachbauen, dort wird die Syntax <i>EXEC @status = xp_findnextmsg @msg_id = @message_id OUTPUT</i> verwendet. In einem richtigen Projekt könnte das zum Beispiel so aussehen:
    <pre>
    CREATE PROCEDURE sp_status_mail
    -- Process only Unread Mail
    @unread_msgs_only varchar(5)='false',
    -- Delete Processed Mail
    @delete_after_reading varchar(5)='false',
    -- Do not change Mail Read Status
    @do_not_change_read_status varchar(5)='true',
    -- Only Process "Stat" mail
    @only_read_stat_mail varchar(5)='true'

    AS
    DECLARE @status int, -- MAPI Status
    @msg_id varchar(64), -- MSG ID for each mail
    @originator varchar(255), -- MAIL FROM
    @msgsubject varchar(255), -- MAIL SUBJECT
    @msgtext varchar(255), -- BUFFER FOR MAIL TEXT
    @messages int, -- Counter for messages processed
    @mapifailure int, -- Indicator if MAPI error
    @maildate varchar(255), -- MAIL SENT Date
    @skip_bytes int, -- Pointer for where to read next
    -- text chunk
    @msg_length int, -- Total size of message text
    @textptr varbinary(16) -- TextPointer

    SELECT @messages=0
    SELECT @mapifailure=0

    WHILE (1=1)
    BEGIN -- BEGIN NEXT MSG LOOP
    EXEC @status=master.dbo.xp_findnextmsg
    @msg_id=@msg_id OUTPUT,
    @unread_only=@unread_msgs_only

    IF @status <> 0
    BEGIN
    SELECT @mapifailure=1
    BREAK -- If any MAPI error, bail out
    END

    IF (@msg_id IS NULL) -- If msg_id is NULL, it's not a
    -- valid received message so continue
    -- with the next message
    BREAK

    SELECT @skip_bytes=0, @msg_length=0

    EXEC @status=master.dbo.xp_readmail
    @msg_id=@msg_id,
    @originator=@originator OUTPUT,
    @subject=@msgsubject OUTPUT,
    @date_received=@maildate OUTPUT,
    @message=@msgtext OUTPUT,
    @skip_bytes=@skip_bytes OUTPUT,
    @msg_length=@msg_length OUTPUT,
    @peek=@do_not_change_read_status

    IF @status <> 0
    BEGIN
    SELECT @mapifailure=1
    BREAK -- If any MAPI error, bail out
    END

    -- If flag is set, only care about mail that has "stat" in the
    -- subject line. So forget rest and continue.
    -- Do not count an "uninteresting" message as one processed.

    IF (LOWER(@only_read_stat_mail)='true' AND
    LOWER(@msgsubject) NOT LIKE '%stat%')
    CONTINUE

    -- Count how many messages processed
    SELECT @messages=@messages + 1

    -- The sender field might be an address or a name.
    -- If it's a name, get the address. Must turn off expand
    -- to friendly names. Then, if there is a < in originator,
    -- parse for the address only using charindex.

    SELECT @originator=CASE
    WHEN (@originator NOT LIKE '%<%' OR @originator
    NOT LIKE '% %')
    THEN @originator
    ELSE SUBSTRING(@originator,
    (charindex('<', @originator) + 1),
    (charindex('@', @originator) -
    (charindex('<', @originator) + 1)))
    END

    -- Insert message into a table:

    INSERT pubs.dbo.mailstore
    (Sent_By, Msg_ID, Subject, Recvd, Msg_Text)
    VALUES (@originator, @msg_id, @msgsubject, @maildate,
    @msgtext)

    -- If MSG_ID already there, then continue and try the next
    -- message: error 2627 is a violation of a unique or PK
    -- constraint due to duplicates, and error 2601 is same but
    -- just due to a unique index

    IF (@@error IN (2627, 2601))
    BEGIN
    RAISERROR ('MSG ID: %s already exists. Skipping to
    next message.', 16, 1, @msg_id)
    CONTINUE
    END

    -- Get the textptr from last row inserted.
    SELECT @textptr=TEXTPTR(Msg_Text)
    FROM pubs.dbo.mailstore WHERE Msg_ID=@msg_id

    -- IF a non-null textptr and skip_bytes shows there is more
    -- to read, then keep reading message text until done, and
    -- append with UPDATETEXT.

    WHILE ((@textptr IS NOT NULL) AND
    (@skip_bytes < @msg_length))
    BEGIN -- BEGIN READ-ALL-TEXT-LOOP
    EXEC @status=master.dbo.xp_readmail
    @msg_id=@msg_id,
    @message=@msgtext OUTPUT,
    @skip_bytes=@skip_bytes OUTPUT,
    @msg_length=@msg_length OUTPUT

    IF @status <> 0
    BEGIN
    SELECT @mapifailure=1
    BREAK -- If any MAPI error, bail out
    END

    UPDATETEXT pubs.dbo.mailstore.Msg_Text
    @textptr NULL 0 WITH LOG @msgtext
    END -- END READ-ALL-TEXT-LOOP

    -- If broke out of text loop because of MAPI failure,
    -- then break out of next message processing too

    IF @mapifailure=1
    BREAK

    -- If delete flag is ON, delete this message

    IF (LOWER(@delete_after_reading)='true')
    BEGIN
    EXEC @status=master.dbo.xp_deletemail @msg_id
    IF @status <> 0
    BEGIN
    SELECT @mapifailure=1
    BREAK -- If any MAPI error, bail out
    END
    END

    END -- END NEXT MSG LOOP

    /* Finished examining the contents of inbox */

    IF @mapifailure=0 -- No MAPI errors. Success!
    BEGIN
    RAISERROR(15079, -1, -1, @messages)
    RETURN(0)
    END
    ELSE -- MAPI Errors. Bailed out.
    BEGIN
    RAISERROR ('MAPI Error. Terminated Procedure', 16, 1)
    RETURN(-100)
    END
    go
    </pre&gt

    Comment


    • #3
      Hallo Herr Kosch,<br><br>also was soll ich sagen, es ist mir ja schon richtig peinlich, dass Sie sich sooooo viel Mühe um <b>meine</b> Probleme machen. Also vielen, vielen Dank :-) !!!<br>
      Natürlich funktioniert die ganze Sache prima. Ich habe zwar immer noch nicht verstanden warum ein <b> insert into Hilfstabelle exec xp_findnextmsg </b> nicht functioniert, wo doch <b> exec xp_findnextmsg </b> ein Recordset zurückliefert, aber Ihre Lösung war genau das, was ich brauche.<br><br>Noch einmal vielen Dank, und viele Grüße!!!<br><br>O. Steffa

      Comment


      • #4
        Hallo Herr Kosch<br><br>also was soll ich sagen, Sie haben ja <b> meine </b> ganze Arbeit gemacht. Also vielen, vielen Dank :-) !!!<br>Die ganze Sache läuft wirklich bestens und mein Problem ist gelöst. Allerdings verstehe ich immer noch nicht ganz, warum <b> insert into Hilfstabelle exec xp_findnextmsg </b> nicht funktioniert, wo doch <b> exec xp_findnextmsg </b> ein Recordset zurückliefert. Diese Konstruktion benutze ich z.B. auch bei <b> insert into Hilfstabelle exec xp_cmdshell 'dir c:\' </b> um die Dateiinformationen weiterverarbeiten zu können. Warum geht das eigentlich in diesem Fall nicht?<br><br>Also mochmal Danke,<br>viele Grüße<br><br>O. Steffa

        Comment

        Working...
        X