如何不允许用户注册超过一天一次
本文关键字:一次 一天 不允许 用户注册 | 更新日期: 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()
,它将返回找到的行数(作为可以转换为int
的Object
)。
这可以工作,并且性能稍微好一些:
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的答案和这篇博客文章。