如何不允许用户注册超过一天一次

本文关键字:一次 一天 不允许 用户注册 | 更新日期: 2023-09-27 18:05:11

我正在创建一个用户记录"ticks"的小服务。我有一些问题,我的用户不应该能够登录超过一天一次。这里是我的SQL检查:

using (SqlCommand cmd = new SqlCommand())
                    {
                        cmd.Connection = conn;
                        cmd.CommandText = "SELECT * FROM TickLog WHERE Username = @username AND DATEPART(year, Inserted) = DATEPART(year, @date) AND DATEPART(month, Inserted) = DATEPART(month, @date) AND DATEPART(day, Inserted) = DATEPART(day, @date)";
                        cmd.Parameters.AddWithValue("@username", username);
                        cmd.Parameters.AddWithValue("@date", DateTime.Now);
                        int affectedRows = cmd.ExecuteNonQuery();
                        if (affectedRows > 0)
                            throw new Exception("allready registered");
                    }

表的结构很简单:

  • Id, int
  • 用户名,字符串
  • 插入,日期

如何不允许用户注册超过一天一次

ExecuteNonQuery()返回受UPDATE、INSERT或DELETE操作影响的行数。因为你只是做一个选择,它将始终返回0受影响的行。尝试使用ExecuteReader()并检查返回结果是否有任何值。

http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.executenonquery.aspxhttp://msdn.microsoft.com/en-us/library/9kcbe65k.aspx

或者,您可以将查询更改为SELECT COUNT(*)...并使用ExecuteScalar(),它将返回找到的行数(作为可以转换为intObject)。

http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.executescalar.aspx

这可以工作,并且性能稍微好一些:

using (var cmd = new SqlCommand())
{
    cmd.CommandText = @"CASE
        WHEN EXISTS (
            SELECT
                *
            FROM
                TickLog TL
            WHERE
                TL.Username = @username
                AND TL.Inserted BETWEEN @date AND DATEADD(DAY, 1, DATEADD(MILLISECOND, -3, @date))
            ) THEN 1
        ELSE 0
    END";
    cmd.Parameters.AddWithValue("@username", username);
    cmd.Parameters.AddWithValue("@date", DateTime.Date);
    var exists = cmd.ExecuteScalar();
    if (exists != 0)
    {
        throw new Exception("already registered");
    }
}
解释:

  • EXISTS是最好的选择,你不需要从数据库中获取整个记录。
  • TL.Inserted应该是一个索引列,但是当你使用DATEPART时,你不会使用任何索引。

关于使用-3毫秒的原因,请参阅StackOverflow的答案和这篇博客文章。