2009-05-20 10 views
3

Ich möchte eine E-Mail für jede Zeile einer Ergebnismenge mit sp_send_dbmail senden.E-Mail für jede Zeile in einer Ergebnismenge senden

Was ist der geeignete Weg, dies ohne Schleifen zu erreichen?

Edit: Ich bestehe nicht darauf, dass eine Schleife hier nicht korrekt ist, aber gibt es eine Set-basierte Möglichkeit, dies zu tun. Ich habe versucht, eine Funktion zu erstellen, aber eine Funktion kann einen gespeicherten Prozess nicht darin aufrufen. Nur eine andere Funktion oder erweiterte SP (was ich auch nicht tun würde).

+1

Loops scheinen für diese ideal. Können Sie erklären, warum Sie sie vermeiden möchten? –

+0

Schleifen sind eine schlechte Idee für diese Art von Sache. Siehe unten. – NotMe

+0

Ich mag Schleifen nicht schreiben und würde lieber eine Set-basierte Methode verwenden. – Sam

Antwort

0

Der beste Weg, dies zu tun ist Ihre E-Mail zu senden Logik in einer benutzerdefinierten Funktion zu setzen.

Dann rufen Sie würden einfach SELECT MyEmailFunc (E-Mailadresse) FROM MyTable

Es vermeidet Schleifen und man kann es auch in einer Update-Anweisung verwenden, um zu zeigen, dass die E-Mail gesendet wurde. Zum Beispiel:

UDPATE MyTable SET SENT = MyEmailFunc (E-Mailadresse) WHERE gesendet = 0

+0

Was passiert, wenn die Abfrage dazwischen fehlschlägt? Sie werden Ihre Ergebnismenge verlieren und nicht einmal wissen, was Ihre letzte E-Mail war, die erfolgreich war. – Quassnoi

+1

Nur Funktionen und erweiterte gespeicherte Prozeduren können innerhalb einer Funktion ausgeführt werden. – Sam

+0

Verwenden Sie einfach die UPDATE-Anweisung. Die Funktion sollte Fehlercode enthalten und ein entsprechendes Ergebnis senden. – NotMe

3

Dieser Fall ist genau das, was Loops gut sind (und für die entwickelt).

Da Sie Dinge tun, die außerhalb des Datenbankbereichs liegen, ist es absolut legitim, für sie Schleifen zu verwenden.

Datenbanken dienen zum Speichern von Daten und zum Ausführen der Abfragen für diese Daten, die sie am praktischsten zurückgeben.

Relationale Datenbanken können Daten in Form von Rowsets zurückgeben.

Cursor (und Schleifen, die diese verwenden) sollen ein stabiles Rowset erhalten, so dass einige Dinge mit jeder Zeile erledigt werden können.

Mit "Dinge" meine ich hier keine reinen Datenbanktricks, sondern reale Dinge, die die äußere Welt betreffen, die Dinge, für die die Datenbank gedacht ist, sei es eine Tabelle auf einer Webseite, einen Finanzbericht oder eine E-Mail .

Es ist schlecht, Cursors für reine Datenbankaufgaben zu verwenden (wie das Umwandeln eines Rowsets in ein anderes), aber es ist vollkommen nett, sie für die Dinge zu verwenden, die Sie beschrieben haben.

Set-basierte Methoden sind so konzipiert, dass sie innerhalb einer einzigen Transaktion arbeiten.

Wenn Ihre Set-Base-Abfrage aus irgendeinem Grund fehlschlägt, wird die Datenbank in den vorherigen Zustand zurückgesetzt, aber Sie können eine gesendete E-Mail nicht "zurücksetzen". Sie können Ihre Nachrichten im Falle eines Fehlers nicht verfolgen.

+0

Ich bin mir bewusst, dass es in Ordnung ist, eine Schleife für diese Art von Sache zu verwenden, aber fragte mich, ob es einen anderen Weg gab. Hoffentlich findet jemand Ihren umfangreichen Text hilfreich: P – Sam

+0

Set-based Operationen sind einfach nicht gut dafür. Ich habe versucht, die Dinge zu tun, die Sie vor etwa 10 Jahren in PostgreSQL beschrieben haben (Drucken von Restaurantrechnungen), und das war ein Albtraum aus den von mir beschriebenen Gründen und noch viel mehr. Verwenden Sie einfach Schleifen :) – Quassnoi

0

Nicht die beste Übung, aber wenn Sie wollen Schleifen vermeiden:

Sie könnten eine „Sendmail“ Tabelle erstellen, mit einem Trigger auf Einfügen

Die sp_send_dbmail aus dem Innern des Trigger genannt wird

dann tun Sie:

Truncate Table SendMails 

insert into SendMails (From, To, Subject,text) Select field1,field2,field3,field4 from MyTable 
0

Es muss eine Zeile-für-Zeile-Operation sein, wenn Sie eine E-Mail pro Zeile benötigen. Es ist keine Standard-Set-basierte Aktion.

Entweder während Sie durch sie in SQL oder Sie „für jeden“ in einer Client-Sprache

ich E-Mails von Trigger nicht BTW senden würde: Ihre Transaktion ist offen, während der Trigger ausgeführt

+0

Die neue E-Mail in SQL Server wartet nicht wirklich auf die E-Mail gesendet werden. Es wird in eine Warteschlange gestellt und von einer separaten .exe verarbeitet – Sam

+0

Ich würde es immer noch nicht in einem Trigger tun, noch würde ich einen Trigger in Schleife – gbn

0

ein Daten einrichten -driven Abonnement in SQL Server Reporting Services :-D

Klingt wie eine SSRS-Anforderung für mich - TSQL ist nicht wirklich für das Reporting an und für sich.

Verwandte Themen