automatic email alert for sqlyog - mysql

I need to generate automatic email alert, in which
- the query should be in MySQL(ready)
- how to embed it in HTML and make connections (no idea)
I did the same thing with SQL server I don't have any idea about MySql.
Here is the code for SQL which I did.
declare #tableHTML NVARCHAR(MAX),#s1 varchar (max), #s2 varchar (max) ,
#s3 varchar (max);
set #s1 = 'Sales Data Of All Stores Of CN and HK '
set #s2 = (convert(varchar, getdate()-1, 107))
set #tableHTML = '<H1>Sales Data Of All Stores Of CN and HK </H1>
<table border="1" cellpadding="10">
<style>
table,th,td
{
border="5" bordercolor="#ff0000";
}
table
{
BORDER=10 BORDERCOLOR="#0000FF" BORDERCOLORLIGHT="#33CCFF"
BORDERCOLORDARK="#0000CC"
}
td
{
height:40px;
}
tr
{
background-color:green;
color:white;
}
th
{
background-color:yellow;
color:black;
}
</style>
<tr>
<th>S.NO.</th>
<th>STORE NO.</th>
<th>BUSINESS DATE</th>
<th>TOTAL NO. OF TRANSACTIONS </th>
<th>TOTAL NO. OF RETURNS </th>
<th>TOTAL NO. OF BILL CANCELLATIONS</th>
<th>TOTAL AMOUNT</th>
</tr>' +
CAST ( (
select *
FROM XYZ
WHERE X=Y
GROUP BY X
FOR XML PATH('tr'), TYPE ) AS NVARCHAR(MAX) )+'</table>';
--Print #tableHTML;
set #s3 = #s1 + #s2
exec msdb.dbo.sp_send_dbmail
#recipients=''
, #profile_name=''
, #subject= #s3
, #body = #tableHTML
, #body_format = 'HTML'
I need the same result for Mysql using SQLYog.Please Help me out with
this.

Related

TSQL Emailing data field containing URL didn't work

I am trying to email data field containing URL. What am I doing wrong. Below is my code:
If I comment out the URL field [URL_Field] it works fine. Right now with the [URL_Field] the email sends but nothing comes through my email inbox.
DECLARE
#EmailSubject VARCHAR(100),
#TextTitle VARCHAR(100),
#TableHTML NVARCHAR(MAX),
#Body NVARCHAR(MAX),
#Profile_name VARCHAR(100) = 'TstDBMail',
#Recipients VARCHAR(2000) = 'name#company.com',
#startdate DATETIME,
#enddate DATETIME
SET #EmailSubject = 'ALERT: on'''+##SERVERNAME +''''
SET #TextTitle = 'Alert on ' + ##SERVERNAME +'.'
SET #TableHTML =
'<html>'+
'<head><style>'+
-- Data cells styles font size
'td {border:1px solid #ddd;padding-left:5px;padding-right:5px;padding-top:1px;padding-bottom:1px;font-size:10pt}'+
'</style></head>'+
'<body>'+
-- Text Title style
'<div style="margin-top:15px; margin-left:15px; margin-bottom:15px; font-weight:bold; font-size:13pt; font-family:calibri;">' + #TextTitle +'</div>' +
-- Color and columns names
'<div style="font-family:Calibri; "><table>'+'<tr bgcolor="red">'+
'<td align=left><font face="calibri" color=White><b>customer_id</b></font></td>'+
'<td align=left><font face="calibri" color=White><b>timestamp_utc</b></font></td>'+
'<td align=left><font face="calibri" color=White><b>URL_Field</b></font></td>'+
'</tr></div>'
-----------------------------------------------------------
----- Querying Data --------
-----------------------------------------------------------
SELECT #Body =(SELECT top 1
td = customer_id
,td = timestamp_utc
,td = URL_Field
FROM LAMN_Temp with (nolock)
FOR XML RAW('tr'), ELEMENTS)
SET #Body = REPLACE(#Body, '<td>', '<td align=left><font face="calibri">')
SET #TableHTML = #TableHTML + #Body + '</table></div></body></html>'
SET #TableHTML = '<div style="color:Black; font-size:8pt; font-family:Calibri; width:auto;">' + #TableHTML + '</div>'
-------------------------------
----- Sending email -----------
-------------------------------
IF(#Body IS NOT NULL)
BEGIN
EXEC msdb.dbo.sp_send_dbmail
#Profile_name = #Profile_name,
#Recipients = #Recipients ,
#Body = #TableHTML,
#Subject = #EmailSubject,
#Body_format = 'HTML'
END;
NULL appended to any string value results in NULL, rather than appending an empty string. So if you have any missing values for the URL_Field, the entire #Body will end up as NULL. This fails the IF check and won't send email.
You can probably fix it by changing this:
,td = URL_Field
To this:
,td = coalesce(URL_Field,'')
This other way this might happen is if URL_Field adds enough size to the variable it overflows.
But I agree with the comment that this is a misuse of the SQL mail feature. You'll have much less pain and get much better results using a real mail processing service. It'll probably also cost less in the long run if you're properly accounting for your time spent maintaining this.

How to Conditionally format HTML TABLE in SQL SP

I created a SP to monitor SQL Server Agent Jobs and generating Email for the same in HTML Format.
However, I want to conditionally format the Run Status column to be Red/Green based on cell value(TEXT-Success/Fail).
Please find the code at https://social.msdn.microsoft.com/Forums/sqlserver/en-US/2663e23b-0b55-4816-beb8-fdf8a020396d/formating-msdbdbospsenddbmail?forum=transactsql
(Marked Answer by Hilary Cotter(MCC, MVP))
Kindly help me with the missing code to implement this feature.
Thank You.
Here's how you can modify the creation of the HTML to work:
DECLARE #tableHTML nvarchar(max);
SET #tableHTML =
N'<style type="text/css">h2, body {font-family: Arial, verdana;}
table{font-size:11px; border-collapse:collapse;}
td{background-color:#F1F1F1; border:1px solid black; padding:3px;}
th{background-color:#99CCFF;}</style>'
+ N'<h2>Recent Job Status</h2>'
+ N'<table border="1">' + N'<tr>
<th>Job Name</th>
<th>Last Run Date</th>
<th>Last Run Time</th>
<th>Last Run Status</th>'
+ CAST(( SELECT td = j.[name],
'',
td = MAX(jh.run_date),
'',
td = MAX(run_time),
'',
td = CASE run_status
WHEN 0
THEN N'<font color="red">Failure</font>'
WHEN 1
THEN N'<font color="green">Success</font>'
WHEN 2
THEN N'<font color="yellow">Retry</font>'
WHEN 3
THEN N'<font color="blue">Cancellation</font>'
WHEN 4
THEN N'<font color="black">In Progress</font>'
ELSE N'<font color="black">Unknown</font'
END
FROM dbo.sysjobhistory AS jh
INNER JOIN dbo.sysjobs AS j
ON j.job_id = jh.job_id
WHERE CONVERT(datetime,
SUBSTRING(CONVERT(varchar(12), jh.run_date),
0, 5) + N'-'
+ SUBSTRING(CONVERT(varchar(12), jh.run_date), 5, 2) + '-'
+ SUBSTRING(CONVERT(varchar(12), jh.run_date), 7, 2)) > DATEADD(day, -1, GETDATE())
AND j.category_id <> 14
GROUP BY j.[name], jh.run_status
FOR XML PATH('tr'), TYPE) AS NVARCHAR(MAX)) + N'</table>';
SET #tableHTML = REPLACE(REPLACE(#tableHTML, N'<', N'<'), N'>', N'>');
For my system, that then outputs this:
Hope that's what you need.

How to create multiple HTML tables of data inside 1 email

I am trying to send 2 different tables inside of 1 email. I want one table to establish data concerning data stored in 1 database and the other table for a second database of information. I can produce 1 email simply enough but i cannot understand how to set a second table with a completely different query and data in the same email.
here is what i am currently working with:
USE MY DATABASE
DECLARE
#tableHTML NVARCHAR(MAX)
SET #tableHTML =
N'<H1>Lacrosse Inquiries</H1>' +
N'<table border="1" style="text-align: middle;" width:100% height:20px style="cell" cellspacing="0" cellpadding="5">' +
N'<tr><th>FIRST NAME</th><th>LAST NAME</th><th>Entry Term</th></th><th>Market Segment</th><th>State</th><th>Home Number</th><th>Cell Phone</th>'+
CAST ( ( SELECT td = INQUIRY.F_NAME , ''
, td = INQUIRY.L_NAME , ''
, td = INQUIRY.ENTRY_TERM , ''
, td = INQUIRY.MARKET_SEG , ''
, td = EWADDRESS.STATE , ''
, td = EWADDRESS.HOME_PHONE , ''
, td = EWADDRESS.WORK_PHONE , ''
from EWSTUDENT AS INQUIRY inner join EWMULTI1M as sport on sport.EWSTUID=INQUIRY.EWSTUID left JOIN EWADDRESS ON EWADDRESS.EWSTUID=INQUIRY.EWSTUID LEFT JOIN ESTUDENT ON ESTUDENT.EWSTUID=INQUIRY.EWSTUID
where VCODETYPE = 'EACTIV1M' AND VCODE ='CLAX' AND INQUIRY.GENDER = 'F' AND STUD_TYPE ='P' and (CONVERT(VARCHAR(8), sport.CREATE_DT, 112) = CONVERT(varchar(8), GETDATE(), 112))
order by INQUIRY.L_NAME
FOR XML PATH('tr'), TYPE
) AS NVARCHAR(MAX) ) +
N'</table>' ;
EXEC msdb.dbo.sp_send_dbmail
#profile_name= 'Jordan.Sorensen',
#recipients = 'Jordan.sorensen#svu.edu',
#from_address = 'Jordan.Sorensen#svu.edu',
#body = #tableHTML,
#execute_query_database= 'MY DATABASE',
#subject ='Womens Lacrosse Inquiries',
#body_format= 'HTML'
GO
ANY SUGGESTIONS ON HOW TO CREATE TWO DIFFERENT TABLES WITH TWO COMPLETELY DIFFERENT SETS OF DATA IN ONE EMAIL?
FOR XML PATH('tr'), TYPE
) AS NVARCHAR(MAX) ) +
N'</table>' --<-- This is where you 1st query ends add a couple of line breaks
+ N'<br/><br/>' -- and add you second table just like you have done before
+ N'<table border="1" style="text-align: middle;" width:100% height:20px style="cell" cellspacing="0" cellpadding="5">'
+ N'<tr><th>FIRST NAME</th><th>LAST NAME</th><th>Entry Term</th></th><th>Market Segment</th><th>State</th><th>Home Number</th><th>Cell Phone</th>'
+ CAST ( (/*Your Select just like you have done for 1st table*/) AS NVARCHAR(MAX))
+ N'</table>'
Obviously HTML generated from both sql queries are concatenated and set the value to variable #tableHTML, the rest of the stuff remains the same passing parameters to your procedure and etc etc.

sending two table results in body of html email for SQL SERVER 2008

I have been able to generate reports by creating tables holding results of sql queries and sending periodic emails. I am now required to combine some of them into one and am having a hard time getting it to work. A single table works but two tables results in a blank email.
DECLARE #TITLE NVARCHAR(MAX)
DECLARE #BODY NVARCHAR(MAX)
DECLARE #TITLE2 NVARCHAR(MAX)
DECLARE #BODY2 NVARCHAR(MAX)
DECLARE #SECTABLE NVARCHAR(MAX)
SET #TITLE =CAST((SELECT DISTINCT A.CLIENTPROJ as 'td','', A.CLIENTKEY as 'td','',
A.APIBOX as 'td','', A.ID as 'td', '',
COUNT(B.QUERYTERMS) as 'td', ''
FROM Clients AS A INNER JOIN QueryData AS B ON A.clientKey = B.clientKey
WHERE A.Id='0001000'
group by A.clientProj, A.clientkey, A.APIBox, A.ID order by
COUNT(B.QUERYTERMS) desc
FOR XML PATH ('tr'), ELEMENTS XSINIL) AS NVARCHAR(MAX))
SET #BODY = '<html><body><H4>QUERY ACTIVITY</H4>
<H5>CLIENT ID - 0001000</H5>
<table border = 2>
<tr>
<th> CLIENT NAME </th> <th> CLIENT KEY </th> <th> API FEED </th>
<th> CLIENT ID </th> <th> TOTAL QUERIES </th></tr>'
SET #BODY = #BODY + #TITLE + '</TABLE></BODY></HTML>'
EXEC msdb.dbo.sp_send_dbmail #profile_name='ME Admin',
#recipients = 'YAHOO#WOOHOO.com',
#subject = 'CLIENT QUERY REPORT',
#body = #BODY,
#body_format = 'HTML';
Not sure how and where to include the following second query:
SET #TITLE2 =CAST((SELECT DISTINCT B.CLIENTPROJ as 'td','',
B.CLIENTKEY as 'td','', B.apiBOX as 'td','', B.ID as 'td', '',
COUNT(A.QUERYTERMS) as 'td', ''
FROM QUERYDATA AS A RIGHT JOIN CLIENTS AS B ON
A.clientKey = B.clientKey WHERE A.Id='0001000' AND A.clientKey
IS NULL
group by B.clientProj, B.clientkey, B.APIBox, B.ID order by
COUNT(A.QUERYTERMS) desc
FOR XML PATH ('tr'), ELEMENTS XSINIL) AS NVARCHAR(MAX))
SET #BODY2 = '<html><body><H4>QUERY INACTIVITY</H4>
<H5>CLIENT ID - 0001000</H5>
<table border = 2>
<tr>
<th> CLIENT NAME </th> <th> CLIENT KEY </th> <th> API FEED</th>
<th>CLIENT ID </th> <th> TOTAL QUERIES </th></tr>'
I need both tables to appear in the body of the email and I am not sure how to integrate this.Any ideas appreciated.
final set statement
SET #TITLE = ....
SET #BODY = 'QUERY ACTIVITY
....'
SET #TITLE2 = ...//SECOND TABLE CONTENTS
SET #BODY2 = '<html><body><H4>QUERY INACTIVITY</H4>
<H5>....</tr>'
SET #BODY2 = #BODY + #BODY2 + #TITLE2 + '</TABLE></BODY></HTML>'

Create HTML Table with SQL FOR XML

I'm creating a HL7 Continuity of Care Document (CCD) using FOR XML statements in SQL Server 2008 R2.
I've done A LOT with this method, but this is the first time I have to represent part of the data in a HTML table, which is giving me trouble.
So, I have the following information in a table:
Problem | Onset | Status
---------------------------------
Ulcer | 01/01/2008 | Active
Edema | 02/02/2005 | Active
and I'm trying to render the following
<tr>
<th>Problem</th>
<th>Onset</th>
<th>Status</th>
</tr>
<tr>
<td>Ulcer</td>
<td>01/01/2008</td>
<td>Active</td>
</tr>
<tr>
<td>Edema</td>
<td>02/02/2005</td>
<td>Active</td>
</tr>
I'm using this query:
SELECT p.ProblemType AS "td"
, p.Onset AS "td"
, p.DiagnosisStatus AS "td"
FROM tblProblemList p
WHERE p.PatientUnitNumber = #PatientUnitNumber
FOR XML PATH('tr')
And I keep getting the following:
<tr>
<td>Ulcer2008-01-01Active</td>
</tr>
<tr>
<td>Edema2005-02-02Active</td>
</tr>
Anyone got any advice?
select
(select p.ProblemType as 'td' for xml path(''), type),
(select p.Onset as 'td' for xml path(''), type),
(select p.DiagnosisStatus as 'td' for xml path(''), type)
from tblProblemList p
where p.PatientUnitNumber = #PatientUnitNumber
for xml path('tr')
To add the header as well you can use union all.
select
(select 'Problem' as th for xml path(''), type),
(select 'Onset' as th for xml path(''), type),
(select 'Status' as th for xml path(''), type)
union all
select
(select p.ProblemType as 'td' for xml path(''), type),
(select p.Onset as 'td' for xml path(''), type),
(select p.DiagnosisStatus as 'td' for xml path(''), type)
from tblProblemList p
where p.PatientUnitNumber = #PatientUnitNumber
for xml path('tr')
Mikael's answer works but so will this:
Rather than using FOR XML PATH('tr'), use FOR XML RAW('tr'), ELEMENTS. This will prevent the values from being concatenated and give you very clean output. Your query would look like this:
SELECT p.ProblemType AS td,
p.Onset AS td,
p.DiagnosisStatus AS td
FROM tblProblemList p
WHERE p.PatientUnitNumber = #PatientUnitNumber
FOR XML RAW('tr'), ELEMENTS
I prefer to append the header row using pure markup so I can have a little better control over what is happening. The full code block would look something like this:
DECLARE #body NVARCHAR(MAX)
SET #body = N'<table>'
+ N'<tr><th>Problem</th><th>Onset</th><th>Status</th></tr>'
+ CAST((
SELECT p.ProblemType AS td,
p.Onset AS td,
p.DiagnosisStatus AS td
FROM tblProblemList p
WHERE p.PatientUnitNumber = #PatientUnitNumber
FOR XML RAW('tr'), ELEMENTS
) AS NVARCHAR(MAX))
+ N'</table>'
EDIT
I wanted to add some extra value that I came up based on the need to format the output table.
The "AS td" alias will produce <td>value</td> elements in the markup but not because it understands that a table cell is a td. This disconnect allows us to create fake HTML elements that can be later updated after the query has been executed. For instance, if I wanted to the ProblemType value to be center aligned I can tweak the element name to allow for this. I can't add a style or class to the element name because it breaks alias naming conventions in SQL, but I can create a new element name such as tdc. This will produce <tdc>value</tdc> elements. While this is not valid markup in any way, it is easy for a replace statement to handle.
DECLARE #body NVARCHAR(MAX)
SET #body = N'<table>'
+ N'<tr><th>Problem</th><th>Onset</th><th>Status</th></tr>'
+ CAST((
SELECT p.ProblemType AS tdc,
p.Onset AS td,
p.DiagnosisStatus AS td
FROM tblProblemList p
WHERE p.PatientUnitNumber = #PatientUnitNumber
FOR XML RAW('tr'), ELEMENTS
) AS NVARCHAR(MAX))
+ N'</table>'
SET #body = REPLACE(#body, '<tdc>', '<td class="center">')
SET #body = REPLACE(#body, '</tdc>', '</td>')
This will create cell elements with the format <td class="center">value</td>. A quick block at the top of the string and you'll have center aligned values with a simple tweak.
Another situation I needed to solve was inclusion of links in the markup. As long as the value in the cell is the value you need in the href this is pretty easy to solve. I'll expand the example to include an ID field that I want linked to a detail URL.
DECLARE #body NVARCHAR(MAX)
SET #body = N'<table>'
+ N'<tr><th>Problem</th><th>Onset</th><th>Status</th></tr>'
+ CAST((
SELECT p.ID as tda
p.ProblemType AS td,
p.Onset AS td,
p.DiagnosisStatus AS td
FROM tblProblemList p
WHERE p.PatientUnitNumber = #PatientUnitNumber
FOR XML RAW('tr'), ELEMENTS
) AS NVARCHAR(MAX))
+ N'</table>'
SET #body = REPLACE(#body, '<tda>', '<td><a href="http://mylinkgoeshere.com/id/')
SET #body = REPLACE(#body, '</tda>', '">click-me</a></td>')
This example doesn't account for using the value in the cell inside of the link text but that is a solvable problem with some CHARINDEX work.
My final implementation of this system was for sending HTML emails based on SQL queries. I had a repeated need for cell alignment and common link types so I moved the replace functions into a shared scalar function in SQL so I didn't have to have them in all my stored procedures that sent email.
I hope this adds some value.
This is a generic solution with a FUNCTION on XML-base using FLWOR
It will transform any SELECT into a XHTML table.
It works (tested) with 2008R2+, but I'm pretty sure this would work on 2008, might be even on 2005, too. If someone wants to verify this, please leave a comment. Thx
The following function replaces all the various functions I provided before (see the previous version if needed)
CREATE FUNCTION dbo.CreateHTMLTable
(
#SelectForXmlPathRowElementsXsinil XML
,#tblClass VARCHAR(100) --NULL to omit this class
,#thClass VARCHAR(100) --same
,#tbClass VARCHAR(100) --same
)
RETURNS XML
AS
BEGIN
RETURN
(
SELECT #tblClass AS [#class]
,#thClass AS [thead/#class]
,#SelectForXmlPathRowElementsXsinil.query(
N'let $first:=/row[1]
return
<tr>
{
for $th in $first/*
return <th>{if(not(empty($th/#caption))) then xs:string($th/#caption) else local-name($th)}</th>
}
</tr>') AS thead
,#tbClass AS [tbody/#class]
,#SelectForXmlPathRowElementsXsinil.query(
N'for $tr in /row
return
<tr>{$tr/#class}
{
for $td in $tr/*
return
if(empty($td/#link))
then <td>{$td/#class}{string($td)}</td>
else <td>{$td/#class}{string($td)}</td>
}
</tr>') AS tbody
FOR XML PATH('table'),TYPE
)
END
GO
The easiest call
A mock-up table with some values
DECLARE #tbl TABLE(ID INT, [Message] VARCHAR(100));
INSERT INTO #tbl VALUES
(1,'Value 1')
,(2,'Value 2');
--The call must enclose the SELECT ... FOR XML in paranthesis!
--click run snippet to see the result!
SELECT dbo.CreateHTMLTable
(
(SELECT * FROM #tbl FOR XML PATH('row'),ELEMENTS XSINIL)
,NULL,NULL,NULL
);
<table>
<thead>
<tr>
<th>ID</th>
<th>Message</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Value 1</td>
</tr>
<tr>
<td>2</td>
<td>Value 2</td>
</tr>
</tbody>
</table>
If you need headers with blanks
If your table contains a column with a blank in its name, or if you want to set a column's caption manually (multi langugage support!), or if you want to replace a CamelCaseName with an out-written caption, you can pass this as attribute:
DECLARE #tbl2 TABLE(ID INT, [With Blank] VARCHAR(100));
INSERT INTO #tbl2 VALUES
(1,'Value 1')
,(2,'Value 2');
SELECT dbo.CreateHTMLTable
(
(
SELECT ID
,'The new name' AS [SomeOtherName/#caption] --set a caption
,[With Blank] AS [SomeOtherName]
FROM #tbl2 FOR XML PATH('row'),ELEMENTS XSINIL
)
,NULL,NULL,NULL
);
<table>
<thead>
<tr>
<th>ID</th>
<th>The new name</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Value 1</td>
</tr>
<tr>
<td>2</td>
<td>Value 2</td>
</tr>
</tbody>
</table>
Full CSS-support and hyper-links
You can use attributes to pass over a link or a row-based and even a value-based class to mark columns and even cells for CSS styling.
--a mock-up table with a row based condition and hyper-links
DECLARE #tbl3 TABLE(ID INT, [With blank] VARCHAR(100),Link VARCHAR(MAX),ShouldNotBeNull INT);
INSERT INTO #tbl3 VALUES
(1,'NoWarning',NULL,1)
,(2,'No Warning too','http://www.Link2.com',2)
,(3,'Warning','http://www.Link3.com',3)
,(4,NULL,NULL,NULL)
,(5,'Warning',NULL,5)
,(6,'One more warning','http://www.Link6.com',6);
--The query adds an attribute Link to an element (NULL if not defined)
SELECT dbo.CreateHTMLTable
(
(
SELECT
CASE WHEN LEFT([With blank],2) != 'No' THEN 'warning' ELSE NULL END AS [#class] --The first #class is the <tr>-class
,ID
,'center' AS [Dummy/#class] --a class within TestText (appeary always)
,Link AS [Dummy/#link] --a mark to pop up as link
,'New caption' AS [Dummy/#caption] --a different caption
,[With blank] AS [Dummy] --blanks in the column's name must be tricked away...
,CASE WHEN ShouldNotBeNull IS NULL THEN 'MarkRed' END AS [ShouldNotBeNull/#class] --a class within ShouldNotBeNull (appears only if needed)
,'Should not be null' AS [ShouldNotBeNull/#caption] --a caption for a CamelCase-ColumnName
,ShouldNotBeNull
FROM #tbl3 FOR XML PATH('row'),ELEMENTS XSINIL),'testTbl','testTh','testTb'
);
<style type="text/css" media="screen,print">
.center
{
text-align: center;
}
.warning
{
color: red;
}
.MarkRed
{
background-color: red;
}
table,th
{
border: 1px solid black;
}
</style>
<table class="testTbl">
<thead class="testTh">
<tr>
<th>ID</th>
<th>New caption</th>
<th>Should not be null</th>
</tr>
</thead>
<tbody class="testTb">
<tr>
<td>1</td>
<td class="center">NoWarning</td>
<td>1</td>
</tr>
<tr>
<td>2</td>
<td class="center">
No Warning too
</td>
<td>2</td>
</tr>
<tr class="warning">
<td>3</td>
<td class="center">
Warning
</td>
<td>3</td>
</tr>
<tr>
<td>4</td>
<td class="center" />
<td class="MarkRed" />
</tr>
<tr class="warning">
<td>5</td>
<td class="center">Warning</td>
<td>5</td>
</tr>
<tr class="warning">
<td>6</td>
<td class="center">
One more warning
</td>
<td>6</td>
</tr>
</tbody>
</table>
As a possible enhancement one might pass in a one-row-footer with aggregated values as additional parameter and append it as <tfoot>
All these answers work fine but I ran into a problem recently where I wanted to have conditional formatting on the html ie. I wanted the style property of the td to vary based on data. The basic format is similar with the addition of setting td = :
declare #body nvarchar(max)
set #body =
cast
(select
'color:red' as 'td/#style', td = p.ProblemType, '',
td = p.Onset, '',
td = p.DiagnosisStatus, ''
from tblProblemList p
where p.PatientUnitNumber = #PatientUnitNumber
for xml path('tr'), type)
as nvarchar(max)
To add in conditional formatting to this you simply need to add a case statement:
declare #body nvarchar(max)
set #body =
cast
select
cast (case
when p.ProblemType = 1 then 'color:#ff0000;'
else 'color:#000;'
end as nvarchar(30)) as 'td/#style',
td = p.ProblemType, '',
td = p.Onset, '',
td = p.DiagnosisStatus, ''
from tblProblemList p
where p.PatientUnitNumber = #PatientUnitNumber
for xml path('tr'), type)
as nvarchar(max)
I ran into this problem awhile ago. Here is how I solved it:
SELECT
p.ProblemType AS "td"
, '' AS "text()"
, p.Onset AS "td"
, '' AS "text()"
, p.DiagnosisStatus AS "td"
FROM tblProblemList p
WHERE p.PatientUnitNumber = #PatientUnitNumber
FOR XML PATH('tr')
Try this:
FOR XML raw, elements, root('tr')
There are a tremendous answers already. I just wanted to add that you can also use styles within your query which might be a good in terms of design.
BEGIN
SET NOCOUNT ON;
DECLARE #htmlOpenTable VARCHAR(200) =
'<table style="border-collapse: collapse; border: 1px solid #2c3e50; background-color: #f9fbfc;">'
DECLARE #htmlCloseTable VARCHAR(200) =
'</table>'
DECLARE #htmlTdTr VARCHAR(max) = (
SELECT
'border-top: 1px solid #2c3e50' as [td/#style], someColumn as td, '',
'border-top: 1px solid #2c3e50' as [td/#style], someColumn as td, ''
FROM someTable
WHERE someCondition
FOR XML PATH('tr')
)
SELECT #htmlOpenTable + #htmlTdTr + #htmlCloseTable
END
Where someColumn is your attribute from your table
And someTable is your table name
And someCondition is optional if you are using WHERE claus
Please note that the query is only selecting two attributes, you can add as many as you want and also you can change on the styles.
Of course you can use styles in other ways. In fact, it is always better to use external CSS, but it is a good practice to know how to put inline styles because you might need them
i prefer do this:
select
convert(xml,
(
select 'column1' as th,
'column2' as th
for xml raw('tr'),elements
)),
convert(xml,
(
select t1.column1 as td,
t1.column2 as td
from #t t1
for xml raw('tr'),elements
))
for xml raw('table'),elements