如何从两个表中获取数据以进行登录
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 数据