检查多个表中是否存在用户名/密码

时间:2015-01-31 12:53:57

标签: c# sql asp.net login three-tier

我正在登录页面上工作。我想检查一下用户名和用户名。密码存在于数据库中。我有三个数据库表:团队,组织者,管理员用户名和&每个表中的密码字段。我正在实现三层架构的登录。

我认为我的 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;
    }

3 个答案:

答案 0 :(得分:1)

试试这个,从每个表中选择UNION ALL结果,然后计算行数。

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)
)

答案 1 :(得分:1)

我似乎有一个非常笨拙的数据库设计,其中获取单个用户需要一个不自然的大/长SQL查询。

在几乎每个用例中,您都有一个Users表,如果您需要将用户绑定到其他一些信息,那么UserId将引用用户表。你应该读一下外键。

快速样本:

Users:

- UserId (int or guid) (primary key)

- .... (additional fields removed for brewity)

其他表格将引用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

这将返回integer,指定与给定用户名/密码组合匹配的行数。它应该是1或0.在Unique列上添加Username约束,以确保每个Username只出现一次。

脚注:我看到你有一个解决方案可以解决你面临的问题,但我建议你阅读一些数据库设计,并尽量保持简单。随着应用程序的增长,跨多个表管理多个用户可能会很麻烦。

答案 2 :(得分:0)

您的设计非常糟糕,您应该将所有用户放在一个表中。之后,如果你想通过id获取用户,你应该检查3个差异表。无论如何问题出在查询中你应该这样写:

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中返回此内容。你需要:

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 !
}