How to send an e-mail from database if some condition is met?

心不动则不痛 提交于 2020-07-23 08:18:06

问题


I am beginner.

We have:

database,
schema,
tablename

Table contain columns: Number, State, ExportTime, ImportTime

I need to create a procedure which will send an email from the database (MSSQL) to my mailbox if the amount of the records is bigger than 5 (for records where State=2). That e-mail must contain all rows of that table (if condition is met) in descending order.

Then, the procedure must be performed every hour as a job and connect to server using Linked Server...

I know only how to write two statements with select to get data that I need, but nothing more.

SELECT
  *
FROM schemaname.tablename
WHERE state = 2
ORDER BY ExportDateTime DESC

SELECT
  COUNT(*) AS Queued
FROM schemaname.tablename
WHERE state = 2

Any tips?


回答1:


Here's our solution:

First, create the following proc (hat tip to Tony Rogerson, SQL Server MVP)

CREATE PROC [dbo].[email_object_as_html]
    @source_db    sysname,       --  Where the @object_name is resident
    @schema       sysname,       --  Schema name eg.. dbo.
    @object_name  sysname,       --  Table or view to email
    @order_clause NVARCHAR(MAX), --  The order by clause eg. x, y, z
    @email        NVARCHAR(MAX),  --  Email recipient list
    @subject      NVARCHAR(MAX),
    @body_prefix  NVARCHAR(MAX),
    @body_suffix  NVARCHAR(MAX),
    @bcc NVARCHAR(MAX) = ''
AS
BEGIN
    /**
        Convert's the specified table or view into an html table and emails it.

        Tony Rogerson, SQL Server MVP
        28 March 2008
        http://sqlblogcasts.com/blogs/tonyrogerson

        You are free to use and modify this,
        just keep the above in place;
        I offer no warranties, you get this as is.

    **/
    IF LEN(LTRIM(RTRIM(ISNULL(@order_clause,N'')))) = 0
        SET @order_clause = N''
    ELSE
        SET @order_clause = ' order by ' + @order_clause

    declare
               @body    nvarchar(max)

    --  Get columns for table headers..
    exec( '
    declare col_cur cursor for
        select name
        from ' + @source_db + '.sys.columns
        where object_id = object_id( ''' + @source_db + '.' + @schema + '.' + @object_name + ''')
        order by column_id
        ' )

    open col_cur

    declare @col_name sysname
    declare @col_list nvarchar(max)

    fetch next from col_cur into @col_name

    set @body = N'<table border=1 cellpadding=1 cellspacing=1><tr>'

    while @@fetch_status = 0
    begin
        set @body = cast( @body as nvarchar(max) )
                  + N'<th>' + @col_name + '</th>'

        set @col_list = coalesce( @col_list + ',', '' ) + ' td = ' + cast( @col_name as nvarchar(max) ) + ', '''''

        FETCH NEXT FROM col_cur INTO @col_name

    END

    DEALLOCATE col_cur

    SET @body = CAST( @body AS NVARCHAR(MAX) )
              + '</tr>'

    DECLARE @query_result NVARCHAR(MAX)
    DECLARE @nsql NVARCHAR(MAX)

    --  Form the query, use XML PATH to get the HTML
    SET @nsql = '
        select @qr =
               cast( ( select ' + CAST( @col_list AS NVARCHAR(MAX) )+ '
                       from ' + @source_db + '.' + @schema + '.' + @object_name +
                       @order_clause + '
                       for xml path( ''tr'' ), type
                       ) as nvarchar(max) )'

    EXEC sp_executesql @nsql, N'@qr nvarchar(max) output', @query_result OUTPUT

    SET @body = CAST( @body AS NVARCHAR(MAX) )
              + @query_result

    --  Send notification
    IF @subject IS NULL OR @subject = ''
    SET @subject = 'Your table as requested'

    SET @body = @body + CAST( '</table>' AS NVARCHAR(MAX) )

    SET @body = '<p>' + @body_prefix + '</p>'
              + CAST( @body AS NVARCHAR(MAX) )
              + '<br><br>' + @body_suffix

    SET @body = REPLACE(REPLACE(@body, '&lt;', '<'), '&gt;','>')              


    EXEC msdb.dbo.sp_send_dbmail 
                                  @recipients = @email,
                                  @body = @body,
                                  @body_format = 'HTML',
                                  @subject = @subject,
                                  @blind_copy_recipients = @bcc
END

Then, using a temp table with your query results, you can call the email proc like this:

SELECT * 
INTO #temp
FROM schemaname.tablename
WHERE state=2
ORDER BY ExportDateTime DESC

IF (SELECT COUNT(*) AS Queued FROM #temp ) > 5

    EXEC dbo.email_object_as_html 
        @source_db = 'tempdb',
        @schema = '',
        @object_name = '#temp',
        @order_clause = N'ExportDateTime',
        @email = N'YourRecipient@company.com', 
        @subject = N'schemaname.tablename results',
        @body_prefix = N'Here are your query results:',
        @body_suffix = N'This email brought to you by digital.aaron @ StackOverflow',
        @bcc = N'YourBccAddress@here.com'


来源:https://stackoverflow.com/questions/47932372/how-to-send-an-e-mail-from-database-if-some-condition-is-met

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!