July 22, 2013 at 12:01 pm
I am simply trying to look through a table select out email(recipient), and combing to columns into one(body and unique) and can't seem to do it.My query will generate 4 emails, but all four contain data from the first row of table. What am i missing?
Here is table:
CREATE TABLE [dbo].[TestData](
[text] NULL,
[LTNM ] [varchar](100) NULL,
[varchar](100) NULL,
[CREATEDBY] [varchar](100) NULL,
[BODY] [varchar](800) NULL,
[UNIQUE] [varchar](40) NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
data:
EMAILLTNMREC_EMAILCREATEDBYBODYUNIQUE
test1l@blah.comtest1,one1testl@blah.combajackson12345609329952586HVWBRDWMHPKD
test2@blah.comtest2,one2test@blah.combajackson1234113299503766ZSGCEECCBHQB
test3l@blah.comtest3,one3test@blah.comatholder123516373455442CXVEDSOHUTID
test4@blah.comtest4,one4test@blah.comjppompa12973199046577MNMEEUEIICWR
DECLARE @count int
set @count = 1
DECLARE @Recepient_Email VARCHAR(MAX)
DECLARE @Body1 VARCHAR(MAX)
while (@count <=(select COUNT(*) from TestData))
begin
set @Recepient_Email = (select top(1) EMAIL From TESTDATA where @count=@count)
set @Body1 = (select top(1) TESTDATA.BODY + '' + TESTDATA.UNIQUE from TESTDATA where @count=@count)
EXEC msdb.dbo.sp_send_dbmail
@profile_name='DBA',
@recipients=@Recepient_Email,
@subject = 'This is subject of test Email',
@body =@Body1,
@body_format = 'HTML'
set @count =@count +1
END
July 22, 2013 at 12:13 pm
it's because you aren't actually looping through the data. put an identity column in and then reference it with your count and it will likely work fine.
you might also want to pull the select count out of your loop and only call that once and set it to a variable.
@count=@count is the problem. should be identity_column_name=@count
July 22, 2013 at 12:18 pm
Your problem is the select statements inside your loop.
set @Recepient_Email = (select top(1) EMAIL From TESTDATA where @count=@count)
set @Body1 = (select top(1) TESTDATA.BODY + '' + TESTDATA.UNIQUE from TESTDATA where @count=@count)
The values will always be the same (well they should be) because your where clause has nothing to do with the row. The reason I say should be is because you have no order by with your top 1.
If you do this in a loop you would probably be better off using a cursor. However, I don't think you need a loop here though. Can you just do an insert into a holding table and have a sql job pick up rows from that table and send out the email?
_______________________________________________________________
Need help? Help us help you.
Read the article at http://www.sqlservercentral.com/articles/Best+Practices/61537/ for best practices on asking questions.
Need to split a string? Try Jeff Modens splitter http://www.sqlservercentral.com/articles/Tally+Table/72993/.
Cross Tabs and Pivots, Part 1 – Converting Rows to Columns - http://www.sqlservercentral.com/articles/T-SQL/63681/
Cross Tabs and Pivots, Part 2 - Dynamic Cross Tabs - http://www.sqlservercentral.com/articles/Crosstab/65048/
Understanding and Using APPLY (Part 1) - http://www.sqlservercentral.com/articles/APPLY/69953/
Understanding and Using APPLY (Part 2) - http://www.sqlservercentral.com/articles/APPLY/69954/
July 22, 2013 at 12:19 pm
richard.noordam (7/22/2013)
it's because you aren't actually looping through the data. put an identity column in and then reference it with your count and it will likely work fine.you might also want to pull the select count out of your loop and only call that once and set it to a variable.
@count=@count is the problem. should be identity_column_name=@count
If you use this type of approach I would recommend using ROW_NUMBER() instead of an identity. If you have gaps in your identity it could prove to be challenging. 😉
_______________________________________________________________
Need help? Help us help you.
Read the article at http://www.sqlservercentral.com/articles/Best+Practices/61537/ for best practices on asking questions.
Need to split a string? Try Jeff Modens splitter http://www.sqlservercentral.com/articles/Tally+Table/72993/.
Cross Tabs and Pivots, Part 1 – Converting Rows to Columns - http://www.sqlservercentral.com/articles/T-SQL/63681/
Cross Tabs and Pivots, Part 2 - Dynamic Cross Tabs - http://www.sqlservercentral.com/articles/Crosstab/65048/
Understanding and Using APPLY (Part 1) - http://www.sqlservercentral.com/articles/APPLY/69953/
Understanding and Using APPLY (Part 2) - http://www.sqlservercentral.com/articles/APPLY/69954/
July 22, 2013 at 12:23 pm
Sean Lange (7/22/2013)
richard.noordam (7/22/2013)
it's because you aren't actually looping through the data. put an identity column in and then reference it with your count and it will likely work fine.you might also want to pull the select count out of your loop and only call that once and set it to a variable.
@count=@count is the problem. should be identity_column_name=@count
If you use this type of approach I would recommend using ROW_NUMBER() instead of an identity. If you have gaps in your identity it could prove to be challenging. 😉
agreed, if you are loading the table then using it, the identity column works great. load then use... if not then ROW_NUMBER() is better.
July 22, 2013 at 1:40 pm
Done and Done, and Thanks
July 22, 2013 at 1:58 pm
TryingToLearn (7/22/2013)
Done and Done, and Thanks
Did you fix the loop or fix the code so it doesn't need a loop?
_______________________________________________________________
Need help? Help us help you.
Read the article at http://www.sqlservercentral.com/articles/Best+Practices/61537/ for best practices on asking questions.
Need to split a string? Try Jeff Modens splitter http://www.sqlservercentral.com/articles/Tally+Table/72993/.
Cross Tabs and Pivots, Part 1 – Converting Rows to Columns - http://www.sqlservercentral.com/articles/T-SQL/63681/
Cross Tabs and Pivots, Part 2 - Dynamic Cross Tabs - http://www.sqlservercentral.com/articles/Crosstab/65048/
Understanding and Using APPLY (Part 1) - http://www.sqlservercentral.com/articles/APPLY/69953/
Understanding and Using APPLY (Part 2) - http://www.sqlservercentral.com/articles/APPLY/69954/
July 22, 2013 at 2:05 pm
as a first step i fixed the loop, used variable for count. I tried before(and failed) and will try again to use row_number, and will also try the load into table, but won't the email program need to loop through same table to send emails? Now that i have a fix, i will try to use each suggestion and use the best one. Thanks...I do appreciate the free training...
July 22, 2013 at 2:09 pm
TryingToLearn (7/22/2013)
as a first step i fixed the loop, used variable for count. I tried before(and failed) and will try again to use row_number, and will also try the load into table, but won't the email program need to loop through same table to send emails? Now that i have a fix, i will try to use each suggestion and use the best one. Thanks...I do appreciate the free training...
Yes somewhere along the line you will have to pick them up one at a time. It sort of depends on if you have people waiting for this to run. If you load it to a holding table, it will be able return to the user a bit quicker.
_______________________________________________________________
Need help? Help us help you.
Read the article at http://www.sqlservercentral.com/articles/Best+Practices/61537/ for best practices on asking questions.
Need to split a string? Try Jeff Modens splitter http://www.sqlservercentral.com/articles/Tally+Table/72993/.
Cross Tabs and Pivots, Part 1 – Converting Rows to Columns - http://www.sqlservercentral.com/articles/T-SQL/63681/
Cross Tabs and Pivots, Part 2 - Dynamic Cross Tabs - http://www.sqlservercentral.com/articles/Crosstab/65048/
Understanding and Using APPLY (Part 1) - http://www.sqlservercentral.com/articles/APPLY/69953/
Understanding and Using APPLY (Part 2) - http://www.sqlservercentral.com/articles/APPLY/69954/
July 22, 2013 at 2:25 pm
This is why cursors exist. Just use a cursor, unless you have an extraordinarily high volume of emails to send.
CREATE TABLE [dbo].[TestData](
[text] NULL, --?? why not change to varchar(max) ??
...
DECLARE csr_email CURSOR FAST_FORWARD FOR
SELECT
CAST(email AS varchar(max)) AS email,
body,
unique
FROM [dbo].[TestData]
--WHERE ...
DECLARE @email varchar(max)
DECLARE @body varchar(8000)
DECLARE @unique varchar(400)
DECLARE @body1 varchar(8000)
OPEN csr_email
WHILE 1 = 1
BEGIN
FETCH NEXT FROM csr_email INTO @email, @body, @unique
IF @@FETCH_STATUS = -1
BREAK
IF @@FETCH_STATUS = -2
CONTINUE
SET @body1 = @body + '' + @unique
EXEC msdb.dbo.sp_send_dbmail
@profile_name = 'DBA',
@recipients = @email,
@subject = 'This is subject of test Email',
@body = @body1,
@body_format = 'HTML'
END --WHILE
DEALLOCATE csr_email
SQL DBA,SQL Server MVP(07, 08, 09) "It's a dog-eat-dog world, and I'm wearing Milk-Bone underwear." "Norm", on "Cheers". Also from "Cheers", from "Carla": "You need to know 3 things about Tortelli men: Tortelli men draw women like flies; Tortelli men treat women like flies; Tortelli men's brains are in their flies".
July 24, 2013 at 3:55 am
Viewing 11 posts - 1 through 10 (of 10 total)
You must be logged in to reply to this topic. Login to reply