Export SQL result to csv through sp_send_dbmail - sql

I am trying to create a Job that sends SQL result as a CSV attachment via email.
I manage to do it through the following code:
EXEC msdb.dbo.sp_send_dbmail
#profile_name = 'main',
#recipients = 'test#email.com',
#body = 'test',
#query = 'SELECT column1, column2, column3 FROM DB.dbo.Table',
#attach_query_result_as_file = 1,
#query_attachment_filename = 'Test.csv',
#query_result_header = 1,
#query_result_width = 256,
#query_result_separator = ',',
#exclude_query_output = 1,
#append_query_error = 1,
#query_no_truncate = 0,
#query_result_no_padding = 1,
#subject = 'Test';
However, I have 2 problems:
They are all in one column separated by comma instead of 3 columns.
There is an extra row after the column header that contains dashes.
Current CSV File:
Desired CSV File:
Any help will be appreciated :)
Thanks!

So, I just found an answer to my own question.
Apparently, I have to insert a new row in the top of the file containing “sep=,”. This forces Excel to understand that it is a comma delimited file, and ensures that it will open correctly.
You can alter the name of the first column to include this header text. We simply rename “Column1” to “sep=,{CR}{LF}Column1”. Then when dbmail prints out the column headers in the file, the Column1 name will be split on two lines, preceeded by “sep=,”.
Excel treats this first row as an instruction and does not display it, just uses it to make sure it formats the data correctly.
Full Details here: https://www.purplefrogsystems.com/blog/2014/04/excel-doesnt-open-csv-files-correctly-from-sp_send_dbmail/

USE "SET NOCOUNT ON" with two query's to solve this problem.
the first query is the headers.
the second query is the result.
example:
#query = 'SET NOCOUNT ON
SELECT ''COLUMN NAME 1'', ''COLUMN NAME 2'', ''COLUMN NAME3''
SELECT P.PRODUCT, P.PRICE, P.TYPE
FROM PRODUCTS P'

Related

CSV file from the SQL Server is out of format

I am new to SQL Server and trying to send a CSV file as an email attachment to business users. Unfortunately, the file received is totally out of format. I have the following code and the table is from SAP B1. What would be the best way to resolve this?
EXEC msdb.dbo.sp_send_dbmail
#profile_name = 'profile name',
#recipients = 'recipent name',
#subject = 'Test',
#query = 'select slpcode, slpname, memo, commission from dbo.OSLP ',
#attach_query_result_as_file = 1,
#query_attachment_filename = 'Results.csv',
#query_result_separator = ',',
#query_result_width = 32767,
#query_result_header = 1,
#append_query_error = 1,
#query_no_truncate = 0
edit: Ideally, the data should be shown in only 4 columns as I have queried only 4 columns but instead this information is spread across columns A:N
Any help would be greatly appreciated.
The sample data in the table looks as follows:
Sample Data Link
and the result from my code shows up as follows:
Final Result Link
Thanks,

sp_sent_email - attachment as grid

I have quite a big problem with a task which should be easy.
I would like to write a procedure that would send query results by mail as an attachment.
My problem is that the format of attachment is in text, not an grid form.
Using code as below:
set #query = 'select 1 as a , 2 as b'
EXEC msdb.dbo.sp_send_dbmail #profile_name = #profilename
, #recipients = #emailto
, #copy_recipients = #recipients
, #Subject = #SubjectTitle
, #body = #body
, #query = #query
, #query_attachment_filename = 'test.csv'
, #attach_query_result_as_file = 1
, #query_result_no_padding = 1
I get on my email .csv file as per below:
a b
- -
1 2
(1 rows affected)
While, I would like to have something in the format which would be recognized by excel. So something like that:
a,b
1,2
Could you please advise?
While I totally agree with #Larnu that SQL is - putting this politely - not the best at this, it can be done with ugly queries like
SELECT CONCAT('a', ',', 'b')
UNION ALL
SELECT CONCAT(CAST(1 AS VARCHAR(5)),',',CAST(2 AS VARCHAR(5)))
Result:
a,b
1,2
It's also possible to coax SQL into creating valid HTML tables, but it's a lot of string manipulation and very brittle.

SQL HTML email showing blank when one table has no results

The following code sends 2 diferent tables based on an sql query through the function sp_send_dbmail , the catch is , if both tables return results , the email shows up without any problem , perfectly. If one of the tables has NO results, the email comes up completly blank.
How can i fix this?
Thanks
declare #tableHTML NVARCHAR(MAX);
set #tableHTML = N'Este foi o resultado de Faturas Emitidas: <br><br><table border ="1">' +
N'<tr><th>Documento</th></tr>' +
cast (( select td = cc.tx
from cc
for xml path ('tr'),type) as nvarchar(max)) +
N' </table><table border ="1"><tr><th>Valor Total Vencido</th></tr>'
+
cast (( select td = fx.tc
from fx
for xml path ('tr'),type) as nvarchar(max)) +
N'</table>';
EXEC sp_send_dbmail
#profile_name ='xx_SqlMail',
#recipients ='ccccc#hotmail.com',
#subject ='Resumo',
#body =#tableHTML,
#body_format='HTML';
I would suspect that part of your query is returning a NULL value. Concatenating any value with a NULL will always result in NULL.
SELECT 'A' + NULL + 'B' will return NULL.
As you are doing multiple concatenations it would mean that if any value is NULL then #tableHTML will be NULL. Try wrapping your selects in an ISNULL().
select ISNULL(td, '') = cc.tx ...
Any table in your concatenation that returns a NULL will make the entire concatenation NULL.
To resolve this, just wrap each section that could potentially be NULL with an ISNULL().
I had a similar issue where I was running two separate queries and building two tables that I wanted to include in the body of the email. One would occasionally return no values and the email would come back blank. Using ISNULL fixed it for me.
See the code below for an example of what I did:
set #tablesHTML = **ISNULL**(#tableOneHTML,'NO RESULTS')
+ **ISNULL**(#tableTwoHTML,'NO RESULTS')
exec XXXXXX.[XXX].[sp_send_dbmail]
#profile_name='Mail'
,#recipients = #EmailRecipients
,#copy_recipients= #EmailCopyRecipients
,#subject = 'Email Subject Here'
,#body = #tablesHTML
,#body_format = 'HTML'

CSV file splitting my row data into separate rows

I have a a query that creates a CSV file and then emails it out to a user but the CSV file is not in the correct format. For some reason when the CSV file is opened it is separating some of my rows into 2 separate rows for some unknown reason! The spliting of the rows seems to be getting done at random because some rows are split while other rows remain intact. This is a difficult scenario to explain so below shows the query I have wrote for creating the CSV file and emailing it out to the user and then the results of the CSV file!
EXEC msdb.dbo.sp_send_dbmail
#profile_name='TestProfile',
#recipients='Test#gmail.com',
#subject='Test message',
#body='This is a test.',
#query = 'Select *
FROM (
SELECT
replace(LEFT(convert(NVARCHAR, getdate(), 106),6) + ''-'' + RIGHT(year(convert(NVARCHAR, getdate(), 106)),2), '' '', ''-'') as [Date],
FirstName, Surname,TestTime as TestTime , Percentage as Percentage, Score as Score
FROM TestDatabase.dbo.TestingTable
) as s
PIVOT
(
SUM(Score)
FOR [TestTime] IN ([00:00],[00:30],[01:00],[01:30],[02:00],[02:30],[03:00],[03:30],[04:00],[04:30],[05:00],[05:30],[06:00],[06:30],[07:00],[07:30],[08:00],[08:30],[09:00],[09:30],[10:00],[10:30],[11:00],[11:30],[12:00],[12:30],[13:00],[13:30],[14:00],[14:30],[15:00],[15:30],[16:00],[16:30],[17:00],[17:30],[18:00],[18:30],[19:00],[19:30],[20:00],[20:30],[21:00],[21:30],[22:00],[22:30],[23:00],[23:30])
) Results
',
#query_result_separator = ' ',
#query_result_header = 1,
#exclude_query_output = 1,
#append_query_error = 1,
#attach_query_result_as_file = 1,
#query_attachment_filename = 'test.csv',
#query_result_no_padding = 1
Output
When in fact it should look like this:
Bottom image is the correct format and the top row goes from 00.00 to 23.30 as intended!
By default, sp_send_dbmail inserts a line break after 256 characters on any given line. You can modify this by specifying the #query_result_width parameter when calling the stored procedure. Maximum value is 32767.
Aside: If this is supposed to be a CSV file, why is #query_result_separator = ' ' and not #query_result_separator = ','?

set delimiter when using sp_send_dbmail (csv file)

I have a query that brings me back a result set but when I use sp_send_dbmailto send an email to someone containing this result set as a CSV file it opens in excel in the incorrect format! I know that I can correct this format through excel but I don't want the user to do that! I want them to just be able to open the file and everything be visible in the correct format. Below shows how I am creating the CSV file and emailing it out the someone (I am also specifying the seperator but it doesn't work and I can't figure out why):
EXEC msdb.dbo.sp_send_dbmail
#profile_name='TestProfile',
#recipients='Test#gmail.com',
#subject='Test message',
#body='This is a test.',
#query = 'Select firstName, LastName, Address, Score from TestData.dbo.Student',
#query_result_header = 0,
#exclude_query_output = 1,
#append_query_error = 1,
#attach_query_result_as_file = 1,
#query_result_separator = ',',
#query_result_width = 25,
#query_attachment_filename = 'Test.csv',
#query_result_no_padding = 1
Once the CSV File is received and opened all the data is represented in the first column, which isn't the desired results!
Screenshot of my list seperator settings
I struggled with this issue for a couple of days , but finally got it to work
#query_result_separator =' ', did the trick, it's TAB as the result separator.
Full code
EXEC msdb.dbo.sp_send_dbmail
#profile_name ='MailProfile',
#from_address = 'def#abc.com',
#recipients = 'Abc#abc.com',
#body = #varBody,
#body_format = 'HTML',
#execute_query_database ='MyDB',
#query = #VarSQL,
#attach_query_result_as_file = 1,
#query_result_separator =' ',
#exclude_query_output =1,
#query_result_no_padding=1,
#query_result_header =1,
#query_attachment_filename ='MyDB.csv'
If you are using Excel anyway, you can override Excel list separator and remove the problem all together, across every single regional setting out there.
Add the following line in the beginning of the CSV file: sep=;
In your example you would have this inside your #query.
..
#query_result_separator = ';',
#query = '
print ''sep=;''
SELECT 1,2'
..
Content of csv:
sep=;
1;2
Result; correct separation. Always!
You can't count on user regional settings or the application used to open the file.
Besides, any Excel user should know about Data->Text To Columns function.
The only thing you should take care of are fields that might contain the field separator (,) like addresses which should be wrapped with text qualifiers (e.g. ").
I think I could reproduce your issue with the data you provided. I found the answer in this superuser post.
It seems, Excel ignores your list separator if it is the same character as another already used character (for example decimal separator), it will work when you switch decimal separator to something else. But since you need this working on other client machines, too, you should consider switching to another csv-separator altogether (;?)