我有两个表: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游标更快?
答案 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