我需要發送一個CLR存儲過程的結果(我無法更改sproc/clr程序集)作爲HTML與電子郵件。在不使用臨時表或其他類型的持久性的情況下,是否可以捕獲和格式化存儲過程的結果集(通過電子郵件發送)?發送電子郵件中的CLR存儲過程結果
1
A
回答
2
USE msdb
EXEC sp_send_dbmail
@profile_name = 'MailProfile1', --you will need to create this profile in the Database Mail under Management
@recipients = '[email protected]',
@subject = 'CLR Sproc Resultset',
@body = 'Resultset is attached.',
@execute_query_database = '[DatabaseName]',
@query = 'exec [DatabaseName].[SchemaName].[CLRProcName]'
試試這個,希望它應該得到你所需要的。
2
我使用Ola Hallengren's SQL Server Maintenance Solution進行數據庫備份和索引優化。我寫了幾個不同的存儲過程,在作業完成時每晚都會生成電子郵件,以便我一眼就能看到每個數據庫備份需要多長時間,重建了多少個索引和統計信息以及在哪些表格上等。
存儲我爲索引和統計編寫的程序如下。
您必須對其進行修改以適應您自己的需求和源數據,但作爲發送HTML電子郵件的模板,它應該適用於任何事情。
雖然你已經有了一個CLR存儲過程,但你必須創建一個與SP返回的模式相同的臨時表,然後執行INSERT EXEC,否則你將無法使用我的代碼。
CREATE PROCEDURE dbo.spCommandLogIndexRebuildTimePerDatabase
@Operator sysname
AS
BEGIN
SET NOCOUNT ON;
/* Debug Block
DECLARE @Operator sysname = 'Your Operator Name';
--*/;
DECLARE @MaxID int
, @xml nvarchar(MAX)
, @body nvarchar(MAX)
, @subj nvarchar(255) = N'Index Optimise Results: ' + CAST(CAST(SYSDATETIME() AS date) AS nvarchar) + N' (' + @@SERVERNAME + N')'
, @span_start nchar(31) = N'<span style="font-weight:bold">'
, @span_end nchar(7) = N'</span>'
, @email varchar(255);
-- drop temp table
BEGIN
IF OBJECT_ID('tempdb..#Temp') IS NOT NULL
DROP TABLE #Temp;
END
-- create temp table
BEGIN
CREATE TABLE #Temp
(
ID int NOT NULL IDENTITY PRIMARY KEY
, [Database] sysname
, [Indexes] int
, [Statistics] int
, [TotalDuration] decimal(19, 3)
, [Time] time
);
END;
-- fill temp table
BEGIN
-- get the starting ID of the latest group of backups
WITH CTEBaseData
AS
(
SELECT l.ID
, l.CommandType
, l.DatabaseName
, l.StartTime
, l.EndTime
, DATEDIFF(MILLISECOND, l.StartTime, l.EndTime) AS DurationMS
, ROW_NUMBER() OVER (ORDER BY l.StartTime) AS RowNum
FROM dbo.CommandLog l
WHERE l.CommandType IN (N'ALTER_INDEX', N'UPDATE_STATISTICS')
)
SELECT @MaxID = MAX(a.ID)
FROM CTEBaseData a
LEFT JOIN CTEBaseData b
ON a.RowNum = b.RowNum + 1
WHERE DATEDIFF(SECOND, ISNULL(b.EndTime, '2013-01-01'), a.StartTime) > 3600;
-- fill the temp table
WITH CTEObjectTimes
AS
(
SELECT l.DatabaseName AS [Database]
, CASE l.CommandType WHEN N'ALTER_INDEX' THEN 1 ELSE 0 END AS [Indexes]
, CASE l.CommandType WHEN N'UPDATE_STATISTICS' THEN 1 ELSE 0 END AS [Statistics]
, DATEDIFF(MILLISECOND, l.StartTime, l.EndTime) AS [Milliseconds]
FROM dbo.CommandLog l
WHERE l.CommandType IN (N'ALTER_INDEX', N'UPDATE_STATISTICS')
AND l.ID >= @MaxID
)
, CTEIndividualTotals
AS
(
SELECT c.[Database]
, SUM(c.[Indexes]) AS [Indexes]
, SUM(c.[Statistics]) AS [Statistics]
, SUM(c.[Milliseconds]) AS [Milliseconds]
FROM CTEObjectTimes c
GROUP BY c.[Database]
)
, CTEResult
AS
(
SELECT c.[Database]
, c.[Indexes]
, c.[Statistics]
, c.[Milliseconds]
, 0 AS SortOrder
FROM CTEIndividualTotals c
UNION ALL
SELECT N'Total'
, SUM(c.[Indexes])
, SUM(c.[Statistics])
, SUM(c.Milliseconds)
, 1
FROM CTEIndividualTotals c
)
INSERT #Temp
(
[Database]
, [Indexes]
, [Statistics]
, [TotalDuration]
, [Time]
)
SELECT c.[Database]
, c.[Indexes]
, c.[Statistics]
, CONVERT(decimal(19, 3), c.[Milliseconds]/1000.00)
, CONVERT(time, DATEADD(MILLISECOND, c.[Milliseconds], 0))
FROM CTEResult c
ORDER BY [SortOrder]
, [Database];
END;
-- convert temp table to html table
SELECT @xml = CONVERT
(
nvarchar(MAX)
, (
SELECT CASE t.[Database] WHEN N'Total' THEN @span_start + t.[Database] + @span_end ELSE t.[Database] END AS [td]
, N''
, N'right' AS [td/@align]
, CASE t.[Database] WHEN N'Total' THEN @span_start + CONVERT(nvarchar(10), t.[Indexes]) + @span_end ELSE CONVERT(nvarchar(10), t.[Indexes]) END AS [td]
, N''
, N'right' AS [td/@align]
, CASE t.[Database] WHEN N'Total' THEN @span_start + CONVERT(nvarchar(10), t.[Statistics]) + @span_end ELSE CONVERT(nvarchar(10), t.[Statistics]) END AS [td]
, N''
, N'right' AS [td/@align]
, CASE t.[Database] WHEN N'Total' THEN @span_start ELSE '' END
+ LEFT(CONVERT(nvarchar(50), t.[Time]), 2) + N'h ' + SUBSTRING(CONVERT(nvarchar(50), t.[Time]), 4, 2) + N'm ' + SUBSTRING(CONVERT(nvarchar(50), t.[Time]), 7, 6) + N's'
+ CASE t.[Database] WHEN N'Total' THEN @span_end ELSE '' END AS [td]
FROM #Temp t
FOR XML PATH('tr')
, ELEMENTS
)
);
-- combine the table rows from above into a complete html document
SELECT @body = N'<html><body><H3>Index Optimise Results for '
+ @@SERVERNAME
+ N' on '
+ CONVERT(nvarchar(10), SYSDATETIME(), 120)
+ N'</H3><table border = 1><tr><th> Database </th><th> Indexes </th><th> Statistics </th><th> Total Time </th></tr>'
+ REPLACE(REPLACE(@xml, '<', '<'), '>', '>')
+ N'</table></body></html>';
-- get the email address of the operator
SELECT @email = o.email_address
FROM msdb.dbo.sysoperators o
WHERE o.name = @Operator;
-- just in case the operator is non-existent
SELECT @email = ISNULL(@email, '[email protected]');
/* Debug Block
SELECT *
FROM #Temp;
SELECT @Body AS Body
, @email AS Email;
--*/;
-- send the email
EXEC msdb.dbo.sp_send_dbmail
@profile_name = N'Database Mail Account'
, @recipients = @email
, @subject = @subj
, @body = @body
, @body_format = 'HTML';
END;
GO
如果您對此有任何疑問,請不要猶豫,問問!
+0
非常感謝...我甚至不需要現在使用clr ...我不知道如何將結果集格式化爲HTML – Dvintila
相關問題
- 1. 如何使用存儲過程結果發送電子郵件
- 2. 如果存儲過程返回無結果不發送電子郵件
- 3. 從Netezza公司發送電子郵件的存儲過程
- 4. SQL Server存儲過程發送電子郵件
- 5. 從SQL Server 2012存儲過程發送電子郵件
- 6. SSIS - 輸出存儲過程結果以電子郵件
- 7. 存儲過程通過電子郵件向多個收件人發送電子郵件
- 8. SQL存儲過程中的語法錯誤發送電子郵件?
- 9. 如何通過電子郵件發送這些oracle結果
- 10. 我需要幫助發送jQuizzy結果通過電子郵件
- 11. 通過電子郵件發送VSTS 2008測試結果
- 12. 發送表單結果到電子郵件地址通過PHP
- 13. 通過電子郵件發送用戶結果
- 14. PowerShell函數結果將不會通過電子郵件發送
- 15. 從存儲過程發送郵件
- 16. 通過電子郵件發送郵件時在texbox結果中添加空間
- 17. PHP電子郵件結合字段發送電子郵件
- 18. Android發送電子郵件不存在發送的電子郵件客戶端
- 19. 將Sproc結果發送到SQL Server中的電子郵件
- 20. 如果沒有電子郵件客戶端通過VB6發送電子郵件
- 21. ASP.NET通過電子郵件發送給多個電子郵件
- 22. GAS幫助 - 通過電子郵件發送電子郵件
- 23. 如何通過電子郵件發送電子郵件地址
- 24. 如何運行存儲過程報告,然後將結果發送到電子郵件?
- 25. VBA - 如何在Outlook中發送電子郵件之前存儲.SentOn在發送電子郵件之前
- 26. 通過電子郵件發送評論到存儲在表中的電子郵件地址
- 27. 發送電子郵件操作不發送電子郵件
- 28. PHP發送電子郵件多次發送電子郵件
- 29. 通過電子郵件發送的navigator.userAgent
- 30. 通過電子郵件發送文件
爲什麼不直接從CLR內部發送電子郵件? –
我不知道從C#類發送電子郵件:) – Dvintila