2

我完全被这个难住了。如果记录已插入表中,我有一个触发器应该发送电子邮件,但前提是在过去 20 分钟左右没有插入记录。我已将其范围缩小到它根本不喜欢插入查询中的 GETDATE() 的事实。

如果我更新我的存储过程以插入像“2013-03-07 09:53:54.12”这样的静态日期时间字符串,它将执行触发器并构造电子邮件正文以便可以发送。如果它在存储过程中使用 GETDATE() 或 SYSDATETIME(),则在运行 select 命令后 body 变量将为空。

我错过了什么吗?我无法找到之前发布的任何内容,但我很抱歉,场景已经在这里发布并解决了。

我的 MVC 项目中的插入命令如下所示:

SqlConnection conn = new SqlConnection();
        conn.ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["RegistrationEntriesConnectionString"].ToString();

        SqlCommand command = new SqlCommand("RegisterCustomerDownload", conn);
        command.CommandType = System.Data.CommandType.StoredProcedure;

        command.Parameters.AddWithValue("@Email", userEmail);
        command.Parameters.AddWithValue("FileDownloaded", "Product Name Here");

        try
        {
            //Open connection and try to execute the command
            conn.Open();
            command.ExecuteNonQuery();

            conn.Close();
        }
        catch (Exception ex)
        {
            //do something
        }

我的存储过程如下所示:

SET NOCOUNT ON;

INSERT INTO TrialDownloads(Email, FileDownloaded, DownloadTime) 
VALUES(@Email, @FileDownloaded, GETDATE());

从那里,如果最后一个匹配记录的插入时间超过 20 分钟,我有一个触发器(用于插入),然后发送电子邮件:

SET NOCOUNT ON;

DECLARE @body NVARCHAR(MAX) = N'';

--For debugging purposes
INSERT INTO [DebugLog] (message) VALUES ('Entered SendTrialDownloadEmail');

SELECT @body += 'A trial has been downloaded:' +
        CHAR(13) + CHAR(10)+ 'Email Address: ' + Email +
        CHAR(13) + CHAR(10)+ 'Product Downloaded ' + FileDownloaded +
        CHAR(13) + CHAR(10)+ 'Date Downloaded: ' + CONVERT(NVARCHAR, DownloadTime)
    FROM [inserted] i 
        WHERE NOT EXISTS (SELECT * FROM [dbo].[TrialDownloads] o 
        WHERE 20 > DATEDIFF(minute, o.DownloadTime, GETDATE()) 
            AND i.Email = o.Email 
            AND i.FileDownloaded = o.FileDownloaded);

--For debugging purposes
INSERT INTO [DebugLog] (message) VALUES ('Before IF block');
INSERT INTO [DebugLog] (message) VALUES (@body);
DECLARE @insertCount NVARCHAR(MAX);
SELECT @insertCount = CONVERT(nvarchar, COUNT(*)) FROM inserted
INSERT INTO DebugLog (message) VALUES (@insertCount);


IF NOT @body = N''
    BEGIN
        EXEC msdb.dbo.sp_send_dbmail 
            @profile_name="NoReplyProfile",
            @recipients="email@domain.com",
            @subject="A Trial has been downloaded",
            @body=@body;
        INSERT INTO [DebugLog] (message) VALUES ('Mail sent');
        INSERT INTO [DebugLog] (message) VALUES (@body);
    END
4

2 回答 2

2

根据 Jason 注意到的情况,我想说最好的办法是在关键字段或TrialRegistrations表上过滤您的 NOT EXIST (...) 子句。如果你这样做,我认为你应该是直的。

...

WHERE NOT EXISTS (SELECT * FROM [dbo].[TrialDownloads] o 
        WHERE 20 > DATEDIFF(minute, o.DownloadTime, GETDATE()) 
            AND i.Email = o.Email 
            AND i.FileDownloaded = o.FileDownloaded
            AND NOT i.Id = o.Id)
于 2013-03-07T16:42:30.970 回答
1

所以看起来主要是你的电子邮件基于主表中的 WHERE NOT EXISTS 行,该行与现在之间的日期差异小于 20 分钟,并且该行共享相同的电子邮件和filedownloaded 值作为插入值。

因此,如果没有一行是真的,你只会收到一封电子邮件,但你已经有一行是真的,你刚刚插入的行。

于 2013-03-07T16:20:36.410 回答