用于发送电子邮件的最佳性能TSQL循环?

时间:2015-10-09 14:52:21

标签: sql performance tsql sql-server-2012 database-performance

我有两个表:1)订单是1:N,2)order_item。我需要向订单表上的每个客户电子邮件地址发送1封电子邮件,其中条件与order_item匹配。该电子邮件将包含与这些条件匹配的order_items列表

这是在T-SQL 2012中执行此操作的最佳方式吗?

DECLARE @email NVARCHAR(254);

DECLARE email_cursor CURSOR READ_ONLY FOR
    SELECT DISTINCT o.email
    FROM order_item AS i
        INNER JOIN order AS o ON i.order_id = o.order_id
    WHERE i.send_email = '1';

OPEN email_cursor;
FETCH NEXT FROM email_cursor INTO @email;

WHILE @@FETCH_STATUS = 0
BEGIN
    EXEC sp_send_dbmail
        @profile_name = 'mail'
        @recipients = @email,
        @subject = 'Order Items',
        @body = 
        N'<table>' +
            N'<tr>' +
                N'<th>Order</th>' +
                N'<th>Item</th>' +
            N'</tr>' +
            CAST (( 
                SELECT 
                     i.order_id,
                     i.name
                FROM order_item AS i
                    INNER JOIN order AS o ON i.order_id = o.order_id
                WHERE i.send_email = '1'
                  AND o.email = @email
                FOR XML PATH('tr'), TYPE 
            ) AS NVARCHAR(MAX) ) +
        N'</table>',
        @body_format = 'HTML';
END;

更新从@ JamieD77建议使用表变量:

DECLARE @temp TABLE(
    email NVARCHAR(254),
    order_id INT,
    name NVARCHAR(MAX)
)

INSERT INTO @temp
SELECT 
    o.email
    i.order_id,
    i.name
FROM order_item AS i
    INNER JOIN order AS o ON i.order_id = o.order_id
WHERE i.send_email = '1'.

DECLARE @email NVARCHAR(254);

DECLARE email_cursor CURSOR READ_ONLY FOR
    SELECT DISTINCT email
    FROM @temp

OPEN email_cursor;
FETCH NEXT FROM email_cursor INTO @email;

WHILE @@FETCH_STATUS = 0
BEGIN
    EXEC sp_send_dbmail
        @profile_name = 'mail'
        @recipients = @email,
        @subject = 'Order Items',
        @body = 
        N'<table>' +
            N'<tr>' +
                N'<th>Order</th>' +
                N'<th>Item</th>' +
            N'</tr>' +
            CAST (( 
                SELECT 
                     order_id,
                     name
                FROM @temp
                WHERE email = @email
                FOR XML PATH('tr'), TYPE 
            ) AS NVARCHAR(MAX) ) +
        N'</table>',
        @body_format = 'HTML';
END;

UPDATE 2 我认为使用fast_forward游标更快?

1 个答案:

答案 0 :(得分:0)

尝试在表变量中而不是在游标中派生xml / html。

DECLARE @temp TABLE(
    email NVARCHAR(254),
    order NVARCHAR (MAX)
)

INSERT INTO @temp (email, order)
SELECT 
    o.email,
    c.order
FROM order AS o
CROSS APPLY (
    SELECT CAST (( 
            SELECT 
                 oi.order_id AS td,
                 oi.name AS td
            FROM order_item oi
            WHERE oi.order_id = o.order_id
            FOR XML PATH('tr'), TYPE 
        ) AS NVARCHAR(MAX) )
) c (order)
WHERE i.send_email = 1

DECLARE @email NVARCHAR(254),

DECLARE email_cursor CURSOR LOCAL FAST_FORWARD
FOR
SELECT email, order
FROM @temp

 OPEN email_cursor;
 FETCH NEXT FROM email_cursor INTO @email, @order

WHILE ( @@FETCH_STATUS = 0 )
BEGIN
    EXEC sp_send_dbmail
        @profile_name = 'mail'
        @recipients = @email,
        @subject = 'Order Items',
        @body = 
            N'<table>' +
            N'<tr>' +
            N'<th>Order</th>' +
            N'<th>Item</th>' +
            N'</tr>' +
            @order +
            N'</table>',
    @body_format = 'HTML';

    FETCH NEXT FROM email_cursor INTO @email, @order
END;

CLOSE email_cursor
DEALLOCATE email_cursor