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
Announcement
Collapse
No announcement yet.
Probleme mit xp_findnextmsg - xp_readmail
Collapse
X
-
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>
-
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
-
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
Comment