代码之家  ›  专栏  ›  技术社区  ›  user134570

查询返回结果5次

  •  0
  • user134570  · 技术社区  · 17 年前

    我有个奇怪的问题。C/ASP.NET中的查询返回5次结果。我试过刹车,但找不到错误。我有两张相关的桌子。一个表加载在页面上,当用户单击一个单元格时,它显示与该单元格相关的另一个表的内容。这很简单。

        //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 回复  |  直到 17 年前
        1
  •  4
  •   Adrian Godong    17 年前

    看起来您的查询有问题。尝试使用内部联接而不是,。

    而不是这个:

    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 .

        2
  •  1
  •   Guffa    17 年前

    你在做交叉连接 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);
    

    注:
    注意,我在 项目 表而不是 任务 表。要么表中有冗余,要么字段的含义不同。如果其他用户可以向项目中添加任务,则需要 tasks.Username 如果您只想查看自己添加的任务,也可以使用字段。

        3
  •  0
  •   Krishna Kumar    17 年前

    可能是该查询返回了多个记录;是否可以列出已用表中的主键

        4
  •  0
  •   Colin Mackay    17 年前

    在第二个查询中,您有一个联接,有很多种。从不返回“从项目中选择”表中的任何内容,但它在查询中被引用。我猜你有5个项目。

    另外,您正在向查询中注入数据。这很糟糕,因为攻击者很容易对代码和数据库发起SQL注入攻击,特别是当您直接使用来自控件的数据时。您应该考虑至少使用参数化查询。

        5
  •  0
  •   gg4    17 年前

    您尝试将其添加到查询distinct子句中。因为如果没有显示它,您的查询就使用了笛卡尔积。

    oledbdataadapter adapter=new oledbdataadapter(“选择不同的任务。任务,任务。优先级,任务。完成,任务a.hours from projects,tasks where tasks.username='+uname+”'和tasks.project='+label1.text+”',myconnection);

    推荐文章