检查 username/password 是否存在于多个表中
Check if username/password exists in multiple tables
我正在处理登录页面。我想检查数据库中是否存在用户名和密码。我有三个数据库 table:Teams、Organizers、Admins,每个 table 中分别有用户名和密码字段。我在三层架构中实现登录。
我认为我在下面的 SQL 声明 中有问题。我使用 distinct/valid 团队用户名和团队密码测试了我的 sql 查询。 COUNT 查询 returns 多于一行,这是不正确的。
这是我的数据访问层代码:
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;
}
试试这个,从每个 table 和 UNION ALL 结果中 select,然后计算行数。
select count(*) from
(
SELECT 1 as dummyname FROM Teams t
WHERE (t.teamUsername=@username AND t.teamPassword=@password)
union all
SELECT 1 FROM Organizers o
WHERE (o.organizerUsername=@username AND o.organizerPassword=@password)
UNION ALL
select 1 from Admnis
WHERE (a.adminUsername=@username AND a.adminPassword=@password)
)
我觉得你的数据库设计真的很笨拙,其中获取单个用户需要不自然的 large/long sql 查询。
在几乎每个用例中,您都会有一个用户 table,如果您需要将用户与一些附加信息联系起来,您会通过以下方式引用用户 table UserId
。您也应该阅读外键。
快速示例:
Users:
- UserId (int or guid) (primary key)
- .... (additional fields removed for brewity)
其他 table 将引用 UserId
列,并使用它来提取有关具有连接的用户的信息。
例如:SELECT T.*, U.* FROM Teams T INNER JOIN Users U ON U.UserId = T.UserId WHERE U.Username = "AwesomeCoach";
一个简单的验证查询应该是这样的:
SELECT COUNT(*) FROM Users WHERE Username = xx AND Password = xx
那将 return 一个 integer
指定与给定 username/password 组合匹配的行数。它应该是 1 或 0。在 Username
列上放置一个 Unique
约束以确保每个 Username
.
只出现一次
脚注:我看到您已经找到了解决您所面临问题的答案,但我建议您阅读一些数据库设计,并尽量保持简单.随着应用程序的增长,跨多个 table 管理多个用户可能而且将是一件麻烦事。
你的设计真的很糟糕,你应该把所有的用户都集中在一个table。在那之后,如果你想通过 id 获取用户,你应该检查 3 diff tables。无论如何,问题出在查询中,您应该这样写:
string queryStr = @"
SELECT
COUNT(*) AS TeamsCount,
(SELECT COUNT(*) Organizers WHERE organizerUsername=@username AND organizerPassword=@password) AS OrgCount,
(SELECT Count(*) Admins WHERE adminUsername=@username AND adminPassword=@password) AS AdminCount
FROM
Teams
WHERE
teamUsername=@username AND
teamPassword=@password";
查询应如下所示。之后你需要在 DataSet 中 return 这个。您需要:
DataSet dst = new DataSet();
using(SqlAdapter adapter = new SqlAdapter(cmd))
{
adapter.Fill(dst);
}
在这种情况下,您将拥有包含 3 列的 dst。检查现有用户应该是:
if(dst.Tables[0].Rows[0]["TeamsCount"] > 0 ||
dst.Tables[0].Rows[0]["OrgCount"] > 0 ||
dst.Tables[0].Rows[0]["AdminCount"] > 0)
{
//user already exist !
}
我正在处理登录页面。我想检查数据库中是否存在用户名和密码。我有三个数据库 table:Teams、Organizers、Admins,每个 table 中分别有用户名和密码字段。我在三层架构中实现登录。
我认为我在下面的 SQL 声明 中有问题。我使用 distinct/valid 团队用户名和团队密码测试了我的 sql 查询。 COUNT 查询 returns 多于一行,这是不正确的。
这是我的数据访问层代码:
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;
}
试试这个,从每个 table 和 UNION ALL 结果中 select,然后计算行数。
select count(*) from
(
SELECT 1 as dummyname FROM Teams t
WHERE (t.teamUsername=@username AND t.teamPassword=@password)
union all
SELECT 1 FROM Organizers o
WHERE (o.organizerUsername=@username AND o.organizerPassword=@password)
UNION ALL
select 1 from Admnis
WHERE (a.adminUsername=@username AND a.adminPassword=@password)
)
我觉得你的数据库设计真的很笨拙,其中获取单个用户需要不自然的 large/long sql 查询。
在几乎每个用例中,您都会有一个用户 table,如果您需要将用户与一些附加信息联系起来,您会通过以下方式引用用户 table UserId
。您也应该阅读外键。
快速示例:
Users:
- UserId (int or guid) (primary key)
- .... (additional fields removed for brewity)
其他 table 将引用 UserId
列,并使用它来提取有关具有连接的用户的信息。
例如:SELECT T.*, U.* FROM Teams T INNER JOIN Users U ON U.UserId = T.UserId WHERE U.Username = "AwesomeCoach";
一个简单的验证查询应该是这样的:
SELECT COUNT(*) FROM Users WHERE Username = xx AND Password = xx
那将 return 一个 integer
指定与给定 username/password 组合匹配的行数。它应该是 1 或 0。在 Username
列上放置一个 Unique
约束以确保每个 Username
.
脚注:我看到您已经找到了解决您所面临问题的答案,但我建议您阅读一些数据库设计,并尽量保持简单.随着应用程序的增长,跨多个 table 管理多个用户可能而且将是一件麻烦事。
你的设计真的很糟糕,你应该把所有的用户都集中在一个table。在那之后,如果你想通过 id 获取用户,你应该检查 3 diff tables。无论如何,问题出在查询中,您应该这样写:
string queryStr = @"
SELECT
COUNT(*) AS TeamsCount,
(SELECT COUNT(*) Organizers WHERE organizerUsername=@username AND organizerPassword=@password) AS OrgCount,
(SELECT Count(*) Admins WHERE adminUsername=@username AND adminPassword=@password) AS AdminCount
FROM
Teams
WHERE
teamUsername=@username AND
teamPassword=@password";
查询应如下所示。之后你需要在 DataSet 中 return 这个。您需要:
DataSet dst = new DataSet();
using(SqlAdapter adapter = new SqlAdapter(cmd))
{
adapter.Fill(dst);
}
在这种情况下,您将拥有包含 3 列的 dst。检查现有用户应该是:
if(dst.Tables[0].Rows[0]["TeamsCount"] > 0 ||
dst.Tables[0].Rows[0]["OrgCount"] > 0 ||
dst.Tables[0].Rows[0]["AdminCount"] > 0)
{
//user already exist !
}