2009-07-23 7 views
0

私は奇妙な問題があります。 C#/ ASP.NETでの私のクエリは、結果を5回返します。ブレーキポイントを試しましたが、エラーが見つかりません。関連する2つのテーブルがあります。 1つのテーブルがPAGE_LOADにロードされ、ユーザーがセルをクリックすると、そのセルに関連する別のテーブルの内容が表示されます。それはとても簡単です。クエリは結果を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回どんなにを行いますGridView2(第2テーブル)のコンテンツを常に5回連続して表示します。何が問題なの?

+1

2番目のSELECT文(taska)にタイプミスがあるようです。ところで、 – Svante

+2

この種類のクエリはスクリプト攻撃の簡単なターゲットです。検証なしでページの編集可能なフィールドのコンテンツを使用しないようにしてください。 –

+0

誰かが小さなボビーテーブルについて読む必要があります... –

答えて

4

あなたの質問に間違いがあるようです。 、の代わりにINNER JOINを使ってみてください。

の代わりにこの:

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しやすい

SELECT tasks.Task, tasks.Priority, tasks.Done, tasks.Hours 
FROM projects, tasks 
WHERE tasks.Username='" + uname + "' AND tasks.Project='" + Label1.Text + "' 

これを試してみてください。

+0

うわー、それは完璧に動作します!どうもありがとうございました!私はあなたに投票することができればいいと思うが、別の14レッスンが欠けている。ありがとうございました! SQLインジェクション防止について検討します。みんなありがとう。 – user134570

0

このクエリが複数のレコードを返す可能性があります。使用しているテーブルにプライマリキーを列挙できますか?

0

2番目のクエリでは、並べ替えがあります。 SELECTでは、プロジェクトテーブルから何も返さないが、クエリで参照されます。私は5つのプロジェクトがあると推測しています。

また、クエリにデータを注入しています。特に、コントロールから直接データを使用している場合は、攻撃者がコードとデータベースに対するSQLインジェクション攻撃を非常に簡単に実行できるようになるので、これは悪いことです。少なくともパラメータ化されたクエリの使用を検討する必要があります。

+0

私はそれを理解しています。私はSQLインジェクションについてもっと読む予定です。ありがとう。 – user134570

0

クエリDISTINCT句に追加してみます。なぜなら、それが提示されなければ、あなたのクエリーはデカルト積をとったからです。

OleDbDataAdapterアダプタ=新しいOleDbDataAdapter( "SELECT DISTINCT tasks.Task、tasks.Priority、tasks.Done、taska.Hours FROM projects、tasks WHERE tasks.Username = '" + uname + "' AND tasks.Project = ' "+ Label1.Text +" '"、myConnection);

+0

私はすでにこれを解決しましたが、私はそれを考慮に入れます。ありがとう。 – user134570

1

projectsテーブルとtasksテーブルの間でクロス結合を行っているため、選択したプロジェクトの各タスクにすべてのプロジェクトが参加します。 5つのプロジェクトがあるので、各タスクを5回取得します。

projectsテーブルと tasksテーブル間の関係を指定するJOINを使用:

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テーブルではなくprojectsテーブル内の[ユーザー名]フィールドを使用
注意してください。テーブルに冗長性があるか、フィールドが異なることを意味します。他のユーザーがプロジェクトにタスクを追加できる場合は、自分で追加したタスクだけを表示したい場合でも、tasks.Usernameフィールドの条件が必要です。

+0

Guffyありがとうございます、私はすでにAdrianのソリューションを使用していました。 – user134570

+0

私が追加した注記を参照してください。Adrianが提案したクエリとはいくつかの違いがあります。 – Guffa