我需要发送一个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