I am fairly new to doing more involved SQL work.
My goal is to email using the results of a query to drive email creation. I intend to create a stored procedure and schedule this twice a week (there will be at most 20 emails, this will not be heavy email load) on SQL Server 2008.
SELECT ProjectCodes.ProjectCode, COUNT(Projects.ProjectsID), ProjectApprovers.EmailApprover
FROM Projects
INNER JOIN ProjectCodes
ON Projects.ProjectCodesID=ProjectCodes.ProjectCodesID
INNER JOIN ProjectApprovers
ON Projects.ProjectCodesID=ProjectApprovers.ProjectCodesID
WHERE ProjectApprovers.IsPrimaryApprover=1
group by ProjectCodes.ProjectCode, ProjectApprovers.EmailApprover
This returns something similar to:
+-------------+-------+--------------+
| ProjectCode | Count | EmailAddress |
+-------------+-------+--------------+
| Code1 | 4 | Email1 |
| Code2 | 2 | Email2 |
| Code3 | 2 | Email3 |
| Code4 | 3 | Email4 |
+-------------+-------+--------------+
What I would like to do is basically loop through this result, running the following:
EXEC msdb.dbo.sp_send_dbmail
@recipients= 'email1', --email address from above query
@subject='Test email',
@body='You have X projects waiting' -- where X is the COUNT() term
for each of the rows.
My understanding is I could do this somewhat straightforward for each entry if I use a cursor, but, all the documentation and Stack Overflow results I've found strongly suggest this is not a good strategy.
What is the best way to do something like this?
Getting a SQL Server result set from a stored procedure The stored procedure has a required parameter Iterating through the rows of data returned from SQL Server Using column values from the SQL server result set to create – and uniquely name – text files
In Stored Procedures, a cursor makes it possible to perform complex logic on a row by row basis. Cursors have three important properties: Asensitive: The server may or may not make a copy of its result table. Read-only: The data may not be updated.
Enter the following statement in the For Each Container textbox @body (‘Execute_stored_procedure’) [‘ResultSets’] [‘Table1’], this sets up the For Each Container to loop over each item returned from the stored procedure.
Use Transact-SQL Statements to Iterate Through a Result Set There are three methods you can use to iterate through a result set by using Transact-SQL statements. One method is the use of temp tables. With this method, you create a snapshot of the initial SELECT statement and use it as a basis for cursoring.
Usually the reason cursors are discouraged is because there's ways to do what you want without using a cursor. Many developers start in procedural languages so loops are common and natural. Thinking in terms of set-based operations is not "natural" and so cursors are used to mimic loops.
In this case, using a cursor is appropriate because there's no set-based way to send individual emails.
Whether or not it's a good idea to send emails directly from you database server is another question...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With