查询返回结果5次

时间:2009-07-23 17:17:11

标签: c# asp.net sql gridview

我有一个奇怪的问题。我在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(第二个表)内容。可能是什么问题?

5 个答案:

答案 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);