[SQL]讓 Database Mail 可以搭配圖表顯示資料

早先使用 database mail 的時候可以搭配 google 的 image chart,但隨著該服務已經不在提供服務,該怎麼來進行處理呢 ?

 

很久之前還有 Tech Day 的時代,楊志強老師有介紹過使用 Google Image Chart 來搭配圖表元件,當時也偷學到這樣的方法,在一些主機上可以利用這樣的方式,定時寄出一些通知報表的時候,可以搭配圖表元件讓整個報表更賞心悅目。

但好景不常,Google 的 Image Chart 的服務已經在 2019 年時候取消了該服務,因此好一陣子都無法再使用了。這一陣子因為教課的原因,介紹到 database mail 的使用,因此就順手整理一下,改成利用 Quick Chart 的服務來處理,如果您的使用量不大的話,基本上您不用特別去架設甚麼站台或者是費用,就很足夠可以滿足一般使用了。

基本上 Quick Chart 就是一個可以透過 Http 取得 Chart 圖檔的服務,因此當我們在 database mail 內,就可以很方便的利用 html 的 img 的 tag ,在內文忠使用 <img src="quickchart 的網址" /> 的方式來做處理,而那段網址內也包含您要在 chart 上面畫出來的資料,就可以輕鬆地產生圖表了。


下面我用一個簡單的範例來示範怎麼產生這樣的 Mail 

首先我們先確定要產生的資料

select *
from ( values( '甲',120),( '乙',100),( '丙',160),( '丁',150),( '戊',100) ) as Users( Name,Value )

這樣的資料,我們參考一下 Quick Chart 的圖表元件,會需要組成類似以下的 URL  https://quickchart.io/chart?c={type:'bar',data:{labels:['甲','乙','丙','丁','戊'],datasets:[{label:'Users',data:[120,60,50,180,120]}]}}

這個網址主要由五個基本部分來組成 ( 當然您也可以製作更複雜的圖表,這裡我們就先用比較簡單的案例來說明 ):

  1. quick chart 的網址
  2. 設定圖表樣式
  3. 標籤值
  4. 標籤名稱
  5. 資料值

從上述網址中可以看出來資料透過 JSON 的方式來傳遞,雖然 SQL 有支援將資料結果轉成 JSON 字串格式,但要符合這樣的會有點麻煩,因此這裡我就先用土法煉鋼的方式來組合字串,搭配 SQL Server 新提供的 String_Agg 的函數來做處理,因此將原本取資料的 SQL 做一點修改,修改成以下的方式

select STRING_AGG( ''''+Name+'''' ,',') lables, STRING_AGG( Value ,',') datas
from ( values( '甲',120),( '乙',100),( '丙',160),( '丁',150),( '戊',100) ) as Users( Name, Value )

那接下來我們只要調整一下搭配 database mail 的 sp_send_dbmail 的指令,就可以很方便的產生我們所需要的指令

-- 定義變數
DECLARE @lables nvarchar(max) ;
DECLARE @data  nvarchar(max) ;
DECLARE @tableHTML nvarchar(max) ;


-- 設定 Mail 樣板 HTML
SET @tableHTML = '
<html>
	<img 
	width=500 hright=300
	src="https://quickchart.io/chart?c={type:''bar'',data:{labels:[%%labels%%],datasets:[{label:''%%label%%'',data:[%%data%%]}]}}">
	</img>
</html>
'

-- 取得資料
select @lables=STRING_AGG( ''''+Name+'''' ,','), @data=STRING_AGG( Value ,',')
from ( values( '甲',120),( '乙',100),( '丙',160),( '丁',150),( '戊',100) ) Users( Name, Value )


-- 替換樣板的文字
SET @tableHTML = REPLACE( @tableHTML, '%%labels%%', @lables )
SET @tableHTML = REPLACE( @tableHTML, '%%label%%', '業務員' )
SET @tableHTML = REPLACE( @tableHTML, '%%data%%', @data )


-- Mail 寄送
EXEC msdb.dbo.sp_send_dbmail 
    @profile_name = 'DEMO' ,
    @recipients='james@study4.tw',  
    @subject = 'Chart Demo',  
    @body = @tableHTML,  
    @body_format = 'HTML' ;  

要是相關 database mail 的設定沒有錯的話,應該就可以順利地收到帶有圖表的 mail 了