如何从两个表中获取数据以进行登录

Posted

技术标签:

【中文标题】如何从两个表中获取数据以进行登录【英文标题】:How to fetch data from two tables for login 【发布时间】:2021-10-27 05:44:12 【问题描述】:

我的 SQL Server 数据库中有两个表。

表 #1:登录用户

Unam, Pswd

表 #2 - 添加用户

fName, lName, mobile, Eid, Unam, Pswd, Yob

两个表都有数据。

我的查询是每当用户想要登录时,登录凭据将从 table1 或 table2 中获取。我编写了一个带有内部连接的 SQL 查询,如下所示:

string s = " select * from Login_User inner join Add_User on Login_User.Unam = Add_User.Unam where Login_User.Unam='" + txtUser.Text + "' and Login_User.Pswd='" + txtPswd.Text + "'";

SqlConnection con = new SqlConnection(@"Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Product.mdf;Integrated Security=True;User Instance=True");
       
SqlDataAdapter da = new SqlDataAdapter(s, con);
DataTable dt = new DataTable();
da.Fill(dt);

if (dt.Rows[0][0].ToString() == "1")

    this.Hide();

    Home hm = new Home();
    hm.ShowDialog();

else

    MessageBox.Show("Invalid User Name or Password!.");

我收到一个错误

位置0没有行

请帮帮我

【问题讨论】:

错误提示查询没有返回结果,dt为空。 SQL Injection alert - 您应该将您的 SQL 语句连接在一起 - 使用 参数化查询 来避免 SQL 注入 - 查看Little Bobby Tables 您的主要问题:您需要union all 而不是inner join。您的代码还有很多其他问题:SQL 注入,您应该参数化。使用using 处理连接、命令和适配器。不要存储纯文本密码。 Don't select * just select what you need,在这种情况下只是数字1(然后您可以使用ExecuteScalar 获得单个结果并避免使用适配器和数据表)。不要假设数据表实际上有任何行....... ......Avoid AttachDbFilename。不要在两个地方存储相同的信息,每个事实都有真实的来源。 还有一个建议:不要将密码与 sql 查询一起发送,因为任何跟踪数据库服务器的人都可以看到它。仅将登录名保留为搜索参数,并将您检索到的密码列值(如果找到)与变量中的值进行比较。这样密码就不会出现在您的应用程序的任何地方,您也可以区分用户未找到和密码错误的情况。 【参考方案1】:

通过将输入数据与 SQL 代码连接起来,严格避免创建普通的 SQL 查询。 SQL Injections 非常危险!

您可以使用一些 ADO.NET 功能,这些功能可以让您更好地阅读代码、更清洁的内存处理以及更安全地使用数据库。

在 ADO.NET 中执行 SQL 查询可能如下所示:


void login (string txtUser, string txtPassword) 

// Always hash login-informations (at least the password):
// therefore you hash the input-data and compare it 
// to an also hashed value inside a database
// with this you never transfer 1:1 login-informations from your service to the db

...


  // use "using" - this clears the memory after the object runs out of scope
  using (SqlConnection connection = new SqlConnection(connectionString))
  
      try
      
          connection.Open();
  
          using (DbCommand dbCmd = connection.CreateCommand())
          

              // don't use "*", only select what you need
              string query = @"SELECT t.Unam, t.Pswd FROM 
                               (
                                    SELECT Unam, Pswd FROM User_Login
                                    UNION 
                                    SELECT Unam, Pswd FROM Add_User
                               ) t
                               WHERE t.Unam = @name AND t.Pswd = @pwd";

              dbCmd.CommandText = query;
              // a StringBuilder is possible as well, but always use parameters!

              // hashed txtName and txtPassword!
              dbCmd.Parameters.Add(new SqlParameter("@name", txtName));
              dbCmd.Parameters.Add(new SqlParameter("@pwd", txtPassword));
          
              using (DbDataAdapter adapter = DbProviderFactories.GetFactory(connection).CreateDataAdapter())
              
                  adapter.SelectCommand = dbCmd;

                  DataTable dt = new DataTable();
                  adapter.Fill(dt);

                  // here you can do your stuff
              
          
      
      catch (Exception)
      
          throw;
      
      finally
      
          connection.Close(); 
          // close the connection after using to minimize database traffic
      
  

您可以在docs 中阅读有关 ADO.NET 数据库功能的适当用法的更多信息。

始终牢记:尤其是在处理登录信息和用户数据时,确保代码干净可靠以提供安全性非常重要。

【讨论】:

以上是关于如何从两个表中获取数据以进行登录的主要内容,如果未能解决你的问题,请参考以下文章

数据库:如何从具有一个公共列的两个表中获取多个值

如何通过 SQL 语句从两个特定日期(由用户指定)之间的数据库表中获取数据?

如何从 Power Query 的不同表中的 2 列中获取数据以汇总为 1 列?

使用两个 SQL 表为 Javascript 获取 JSON 数据

如何使用 Laravel 在 LIKE 搜索中使用 ORM 从两个表中获取数据

MySQL 从两个不同的表中获取 user_id 和密码的查询