我有一个奇怪的问题。我在C#/ ASP.NET中的查询返回结果5次。我尝试了刹车,但我找不到错误。我有2个相关的表格。一个表在PAGE_LOAD上加载,当用户单击一个单元格时,它会显示与该单元格相关的另一个表中的内容。这很简单。
//PAGE LOAD
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
OleDbConnection myConnection = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + dbpath + "/secure_user/data/data.mdb");
OleDbDataAdapter adapter = new OleDbDataAdapter("SELECT Project,Manager,Customer,Deadline FROM projects WHERE Username='" + uname + "'", myConnection);
DataTable table = new DataTable();
adapter.Fill(table);
adapter.Dispose();
GridView1.DataSource = table;
GridView1.DataBind();
}
}
它将项目表加载到GridView。现在,当我单击某个项目时,它会显示有关该项目的更多信息:
protected void GridView1_SelectedIndexChanged(object sender, EventArgs e) { GridViewRow row = GridView1.SelectedRow; Label1.Text = row.Cells[1].Text;
OleDbConnection myConnection = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + dbpath + "/secure_user/data/data.mdb");
OleDbDataAdapter adapter = new OleDbDataAdapter("SELECT tasks.Task,tasks.Priority,tasks.Done,taska.Hours FROM projects,tasks WHERE tasks.Username='" + uname + "' AND tasks.Project='" + Label1.Text + "'", myConnection);
DataTable table = new DataTable();
adapter.Fill(table);
adapter.Dispose();
GridView2.DataSource = table;
GridView2.DataBind();
GridView2.Visible = true;
}
它显示没有错误,但无论我从GridView1中选择什么项目它都会显示5次,它总是连续5次显示GridView2(第二个表)内容。可能是什么问题?
答案 0 :(得分:4)
您的查询中看起来有问题。尝试使用INNER JOIN代替,。
而不是:
SELECT tasks.Task, tasks.Priority, tasks.Done, tasks.Hours
FROM projects, tasks
WHERE tasks.Username='" + uname + "' AND tasks.Project='" + Label1.Text + "'
试试这个:
SELECT tasks.Task, tasks.Priority, tasks.Done, tasks.Hours
FROM projects INNER JOIN tasks ON projects.ID = tasks.ProjectID --> may not be correct depends on your table structure
WHERE tasks.Username='" + uname + "' AND tasks.Project='" + Label1.Text + "'
另一件事:构建类似的SQL查询很容易SQL Injection attack。
答案 1 :(得分:1)
您正在projects
表和tasks
表之间进行交叉连接,因此您将为每个项目加入您选择的项目的每个任务。由于你有五个项目,你可以完成五次任务。
使用连接指定projects
表和tasks
表之间的关系:
OleDbDataAdapter adapter = new OleDbDataAdapter(
"SELECT tasks.Task,tasks.Priority,tasks.Done,taska.Hours "+
"FROM projects "+
"INNER JOIN tasks ON tasks.Project = projects.Project "+
"WHERE projects.Username='" + uname + "' AND projects.Project='" + Label1.Text + "'", myConnection);
注意:
请注意,我使用了projects
表中的用户名字段而不是tasks
表。要么表中有冗余,要么字段表示不同的东西。如果其他一些用户可以向您的项目添加任务,那么如果您只想查看自己添加的任务,则还需要tasks.Username
字段的条件。
答案 2 :(得分:0)
可能是此查询返回多条记录;你能列出使用过的表中的主键吗
答案 3 :(得分:0)
在您的第二个查询中,您有一个类似的联接。您永远不会从items表中返回SELECT中的任何内容,但它会在查询中引用。我猜你有5个项目。
此外,您正在将数据注入查询。这很糟糕,因为攻击者很容易对您的代码和数据库进行SQL注入攻击,尤其是当您直接从控件使用数据时。您应该考虑至少使用参数化查询。
答案 4 :(得分:0)
您尝试添加到查询DISTINCT子句。因为如果没有呈现,您的查询就会产生笛卡尔积。
OleDbDataAdapter adapter = new OleDbDataAdapter(“SELECT DISTINCT tasks.Task,tasks.Priority,tasks.Done,taska.Hours FROM projects,tasks WHERE tasks.Username ='”+ uname +“'AND tasks.Project ='” + Label1.Text +“'”,myConnection);