游标和db_sendmail

时间:2016-02-25 13:49:21

标签: sql-server database stored-procedures cursor sendmail

下面的代码我需要循环查询,为每个记录集发送一封电子邮件 - 似乎工作正常一段时间,现在我似乎得到了一些确定和一些空白 - 任何人都可以看到为什么有些会变成空白?如果我运行查询它会在任何时候给我正确的结果 - 没有空行,所以只能假设它与光标有关吗?

USE [Transport_Comp1]
GO
/****** Object:  StoredProcedure [dbo].[ssp_EmailPOD]    Script Date: 02/25/2016 13:42:21 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO


ALTER PROCEDURE [dbo].[ssp_EmailPOD]
AS 
DECLARE @name VARCHAR(20),
@dtDate NVARCHAR(50),
@email NVARCHAR(50),
@szBlockCapitols NVARCHAR(50),
@dwJobnumber NVARCHAR(50),
@szDelAddressRef NVARCHAR(50),
@dwInternetJobNo NVARCHAR(50),
@szDelpostCode NVARCHAR(50),
@dwrDecimalLongitude NVARCHAR(50),
@dwrDecimalLatitude NVARCHAR(50),
@szDelAddrName NVARCHAR(50)


DECLARE @body NVARCHAR(1000)



DECLARE C1 CURSOR FOR
SELECT JobItem.dwJobNumber, JobItem.szDelAddrName, JobItem.szDelAddressRef, JobItem.dwInternetJobNo, JobItem.szDelPostCode, Signature.szBlockCapitols, Signature.dwrDecimalLongitude, Signature.dwrDecimalLatitude, StirlingManager_Comp1.dbo.SalesAccounts.szReportText8, Signature.dtDate
FROM dbo.JobItem INNER JOIN dbo.dms_document ON dbo.JobItem.dwJobItemId = dbo.dms_document.dwJobItemId LEFT OUTER JOIN dbo.Signature ON dbo.dms_document.id = dbo.Signature.dwDocumentIdFK LEFT OUTER JOIN DocArchive_Comp1.dbo.dms_document AS dms_document_1 ON dbo.dms_document.id = dms_document_1.id LEFT OUTER JOIN StirlingManager_Comp1.dbo.SalesAccounts ON dbo.JobItem.szAccCode = StirlingManager_Comp1.dbo.SalesAccounts.szAccountCode
WHERE [Transport_Comp1].[dbo].[Signature].[dtDate] > DATEADD(MINUTE, -5,  GETUTCDATE()) AND [Transport_Comp1].[dbo].[Signature].[dtDate] < DATEADD(SECOND,-1,GETUTCDATE()) AND Transport_Comp1.dbo.Signature.bArrived = 0
ORDER BY dtDate ASC; 
OPEN C1

FETCH NEXT FROM C1 INTO
@dwJobnumber, @szDelAddrName, @szDelAddressRef, @dwInternetJobNo, @szDelPostCode, @szBlockCapitols, @dwrDecimalLongitude, @dwrDecimalLatitude, @email, @dtDate

WHILE (@@FETCH_STATUS = 0)
BEGIN
        SET @body = '<html>' + '<BR><BR>'   
            SET @body = @body + '<b>Your Delivery was completed at : ' + @dtDate + '<BR><BR>'
            SET @body = @body + 'Your delivery was signed for by : ' + @szBlockCapitols + '<BR><BR>'
            SET @body = @body + 'Latitude : ' + @dwrDecimalLatitude + '<BR>' + 'Longitude : ' + @dwrDecimalLongitude + '<BR>'
            SET @body = @body + 'Delivery to : ' + @szDelAddrName + '<BR>'
            SET @body = @body + 'Postcode : ' + @szDelpostCode + '<BR>'
            SET @body = @body + 'Delivery Reference :' + @szDelAddressRef + '<BR></html>'


            EXEC msdb.dbo.sp_send_dbmail
            @profile_name = 'SQL_Email',
            @recipients = @email,
            @subject = 'EMAIL POD',            
            @body = @body,
            @body_format ='HTML'
      FETCH NEXT FROM C1 INTO
      @dwJobnumber, @szDelAddrName, @szDelAddressRef, @dwInternetJobNo, @szDelPostCode, @szBlockCapitols, @dwrDecimalLongitude, @dwrDecimalLatitude, @email, @dtDate
END
CLOSE C1
DEALLOCATE C1

1 个答案:

答案 0 :(得分:3)

正如@KevinM上面指出的那样,问题是你的变量中有NULL。您可以通过多种方式解决这个问题,但最简单的方法是清理您的查询(无论如何这都非常粗糙)。你真的应该养成使用别名的习惯,它会让一切变得更容易。这是我如何重做这个,所以你不会在你的数据中得到NULL。你必须调整一点,因为我不知道你在这里有什么数据类型。

SELECT isnull(j.dwJobNumber, '') as dwJobNumber
    , isnull(j.szDelAddrName, '') as szDelAddrName
    , isnull(j.szDelAddressRef, '') as szDelAddressRef
    , isnull(j.dwInternetJobNo, '') as dwInternetJobNo
    , isnull(j.szDelPostCode, '') as szDelPostCode
    , isnull(s.szBlockCapitols, '') as szBlockCapitols
    , isnull(s.dwrDecimalLongitude, '') as dwrDecimalLongitude
    , isnull(s.dwrDecimalLatitude, '') as dwrDecimalLatitude
    , isnull(sa.szReportText8, '') as szReportText8
    , isnull(s.dtDate, '') as dtDate
FROM dbo.JobItem j
INNER JOIN dbo.dms_document d ON j.dwJobItemId = d.dwJobItemId 
LEFT OUTER JOIN dbo.Signature s ON d.id = s.dwDocumentIdFK 
LEFT OUTER JOIN DocArchive_Comp1.dbo.dms_document AS dms_doc ON d.id = dms_doc.id 
LEFT OUTER JOIN StirlingManager_Comp1.dbo.SalesAccounts sa ON j.szAccCode = sa.SalesAccounts.szAccountCode
WHERE s.dtDate > DATEADD(MINUTE, -5, GETUTCDATE()) 
    AND s.dtDate < DATEADD(SECOND, -1, GETUTCDATE()) 
    AND s.bArrived = 0
ORDER BY dtDate ASC;