Sql server 2008 使用GETDATE时触发器出现问题

Sql server 2008 使用GETDATE时触发器出现问题,sql-server-2008,triggers,Sql Server 2008,Triggers,我在这件事上完全被难住了。我有一个触发器,如果记录被插入到表中,它应该发送一封电子邮件,但前提是在过去20分钟左右没有插入记录。我已经把范围缩小到一个事实,即它根本不喜欢insert查询中的GETDATE() 如果我更新存储过程以插入静态日期时间字符串,如“2013-03-07 09:53:54.12”,它将执行触发器并构造电子邮件正文,以便发送。如果在存储过程中使用GETDATE()或SYSDATETIME(),则body变量在运行select命令后将为空 我错过什么了吗?我还没有找到任何张贴

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

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

我错过什么了吗?我还没有找到任何张贴在此之前,但我很抱歉,场景已经张贴和解决了这里

MVC项目中的insert命令如下所示:

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());
我的存储过程如下所示:

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

因此,看起来最主要的是,您的电子邮件基于一个WHERE NOT existed,在主表中有一行,该行与当前的日期差小于20分钟,并且该行与插入值共享相同的email和filedownload值


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

根据Jason注意到的,我认为最好的办法是在一个键字段或
TrialRegistrations
表上过滤你的NOT EXIST(…)子句。如果你那样做的话,我认为你应该是正直的


首先,不要在触发器中发送电子邮件。您应该将要发送电子邮件的记录发送到pable,然后每隔5分钟左右运行一次作业以发送电子邮件。如果电子邮件服务器宕机,您不想中断插入。@HLGEM这不正是sp_send_Dmail在SQL server 2008中的行为吗?DownloadTime列是什么数据类型?我的印象是sp_send_Dmail已经这样做了。不是吗?另外,DateTime2是DownloadTime的数据类型。我认为这是正确的。20>DATEDIFF(分钟,o.DownloadTime,GETDATE())对我来说就像差不到20分钟;所以他说他不想为匹配时间少于20分钟的条目发送邮件。@MojoFilter如果不是因为他刚才插入的行,这也没关系。我可能弄错了,但我很确定这一行被认为是在主表中。他可以改为对datediff大于20的数据进行存在检查,这样他只会在这是真的情况下发送电子邮件。哦,是的。我以为这是一个而不是插入触发器。我想那会是个问题。不过,我得到的印象是,他用这个来限制发送的电子邮件。所以,检查是否有一个旧的是不够的。这是非常有帮助的。您可能是对的,插入的记录很可能是我查询的表的一部分。我没有意识到这一点。