【发布时间】:2015-01-31 12:53:56
【问题描述】:
我正在处理登录页面。我想检查数据库中是否存在用户名和密码。我有三个数据库表:Teams、Organizers、Admins,每个表中分别带有用户名和密码字段。我正在实现三层架构中的登录。
我认为下面的 SQL 语句 有问题。我使用不同/有效的团队用户名和团队密码测试了我的 sql 查询。 COUNT 查询返回多行,不正确。
这是我的数据访问层代码:
public int getExistingAccount(string username, string password)
{
string queryStr = "SELECT COUNT(*) FROM Teams t,Organizers o,Admins a WHERE (t.teamUsername=@username AND t.teamPassword=@password) OR (o.organizerUsername=@username AND o.organizerPassword=@password) OR (a.adminUsername=@username AND a.adminPassword=@password)";
SqlConnection conn = new SqlConnection(_connStr);
SqlCommand cmd = new SqlCommand(queryStr, conn);
cmd.Parameters.AddWithValue("@username", username);
cmd.Parameters.AddWithValue("@password", password);
int returnValue = 0;
conn.Open();
returnValue = (int)cmd.ExecuteScalar();
conn.Close();
return returnValue;
}
至于业务逻辑层代码:
public string getAccount(string username, string password)
{
string returnMessage = "";
if (username.Length == 0)
returnMessage += "Username cannot empty</br>";
if (password.Length == 0)
returnMessage += "Password cannot be empty</br>";
if (username.Equals(password))
{
returnMessage += "Duplicate value. Please try again</br>";
}
//Invoke validateInput() method to validate data
if (returnMessage.Length == 0)
{
int noOfRows = 0;
LogAccounts logInd = new LogAccounts();
noOfRows = logInd.getExistingAccount(username, password);
if (noOfRows > 0)
returnMessage += "Account found";
else
returnMessage += "Invalid username/password.";
}
return returnMessage;
}
【问题讨论】:
-
如果将 count(*) 替换为 * 会发生什么情况,是否得到预期的行?
-
没有。它不返回预期的行
-
SELECT COUNT(*) FROM ( SELECT t.teamUsername as username FROM Teams t WHERE t.teamUsername=@username AND t.teamPassword=@password UNION SELECT o.organizerUsername as username FROM Organizers o WHERE o .organizerUsername=@username AND o.organizerPassword=@password UNION SELECT a.adminUsername as username FROM Admins a WHERE a.adminUsername=@username AND a.adminPassword=@password)
-
提供一些示例数据和预期输出。你真的应该考虑重新设计。您应该使用所有用户所在的单个用户表,然后从 Teams/Organizers/admin 表中引用它。您应该遵循 C# 命名约定,并使用 CamelCase,而不是使用 lowerCamelCase 的 Java 约定。
-
附带说明,您应该使用强大的算法(例如bcrypt)对存储在数据库中的密码进行散列和加盐处理。
标签: c# sql asp.net login three-tier