2

私はさまざまなサイトやコードを調べてきましたが、私の悲惨さを終わらせるものは何もないようです. 特定の列の重複を見つけて削除するのに役立つか、基になるデータベース自体ではなく、データテーブルからのみ削除します。mdb ファイルのテーブル "table1" から重複する行を削除したいと考えています。

私の要件をより明確にするために:

  1. テーブル内のどの列にも主キーが設定されていません (そして、余裕がありません)
  2. 重複する行を 1 つだけ残してすべて削除したい! (順番は関係ありません)
  3. データベース自体を更新する前に、そのような行が存在するかどうかを最初に確認するよりも、データベースから重複を削除することを好みます(それが最後の手段である場合は、そうではありませんが、それは大歓迎です)
  4. 重複行とは、明確でない行を意味します。たとえば、次の例では、3 行目と 5 行目だけが重複しています。そして、それらのいずれかを削除したいと思います。

          Name1  Name2    Name3
          tom    dick   harry
          tom    dick   mike
          ann    sara   mike
          sara   ann    mike
          ann    sara   mike
    

重複行は、次のようにボタンをクリックしてデータベースから削除する必要があります

     private void button1_Click(object sender, EventArgs e)
     {
         deletedupes();
     }

    private void deletedupes()
    {
        OleDbConnection con = new OleDbConnection("PROVIDER=Microsoft.Jet.OLEDB.4.0; Data Source=C:\\hi.mdb");

        DataSet ds = new DataSet();
        OleDbDataAdapter da = new OleDbDataAdapter("select * from table1", con);
        con.Open();
        da.Fill(ds, "table1");

        // what could be rest of the code??
    }

前もって感謝します。はい、私は初心者です..

4

4 に答える 4

3

まだ気づいていないかもしれませんが、データベース エンジンは絶対的に考える傾向があります。行を削除する場合は、その行を識別する方法を指定する必要があります。したがって、主キー。

そうは言っても、一般的に、常にではありませんが、これを行うには 2 つの方法があります。

  1. Access がDELETE次のような「最初の N 行」のみを考慮するように指示する構文をサポートしているかどうかを調べます。DELETE TOP 1 FROM ...
  2. テーブルから個別のデータセットを取得し、その中のすべての行を削除して、個別の行を挿入して戻します

前者は可能かもしれませんが、それを可能にする構文が Access でサポートされているかどうかによって異なります。例えば。Microsoft SQL Server は、 のSET ROWCOUNT 1前のステートメントの実行をサポートしておりDELETEDELETE1 行だけを削除してから停止します。アクセスがそれを行うかどうかはわかりません。

2 つ目は、外部キーがある場合は面倒ですが、ここで手足を踏み出して、主キーがないため外部キーがないため、データの整合性は問題ではないと仮定します。ここで本当の問題。

于 2011-04-08T20:03:13.907 に答える
2

わかりました、これは完全なハックですが、それが唯一の選択肢のようです...

あなたのSELECT DISTINCTROWテーブルから行います。テーブルからすべてのレコードを削除します。個別の行を挿入して戻します。

DISTINCTROW 構文.

于 2011-04-08T20:12:57.460 に答える
2

これは、SQL Server で重複行を削除するためのいくつかのアプローチについて説明している記事ですが、MS Access にも当てはまると思います。SQL Server のテーブルから重複を削除する

于 2011-04-08T20:00:07.737 に答える
0

私にとって満足のいく答えはなかったので(私は少し初心者なので、ここでより知識が豊富で経験豊富な人々によって話されている簡潔で少し技術的な方法を理解できません)、これを行うために独自のバリエーションを試しました。distinctorset rowcountなどのコマンドで何をすべきかを理解できませんでしdelete fromた。例で完全に展開されたコードを見つけることができませんでした。だから私はこれを試しました。最初から。

    int id, k;
    private void button2_Click(object sender, EventArgs e)
    {
        OleDbConnection con = new OleDbConnection("PROVIDER=Microsoft.Jet.OLEDB.4.0; Data Source=C:\\hi.mdb");

        DataSet ds = new DataSet();

        OleDbDataAdapter da = new OleDbDataAdapter("select * from table2", con);
        con.Open();
        da.Fill(ds, "table2");


        for (int i = 0; i < ds.Tables["table2"].Rows.Count; i++)
        {
            DataRow row = ds.Tables["table2"].Rows[i];
            k++;
            for (int j = k; j < ds.Tables["table2"].Rows.Count; j++)
            {
                DataRow row2 = ds.Tables["table2"].Rows[j];
                if (row.ItemArray.GetValue(1).ToString() == row2.ItemArray.GetValue(1).ToString())
                {
                    if (row.ItemArray.GetValue(3).ToString() == row2.ItemArray.GetValue(3).ToString())
                    {
                        id = int.Parse(row2.ItemArray.GetValue(0).ToString());
                        deletedupes(id);
                    }
                }
            }
        }

        con.Close();
    }


    private void deletedupes(int num)
    {
        OleDbConnection con = new OleDbConnection("PROVIDER=Microsoft.Jet.OLEDB.4.0; Data Source=C:\\hi.mdb");

        con.Open();

        OleDbCommand c = new OleDbCommand("Delete from table2 where id =?", con);
        c.Parameters.AddWithValue("id", num);
        c.ExecuteNonQuery();

        con.Close();
    }

編集:申し訳ありませんが、これを行うために主キーを持つ一意の列を使用したと言い忘れました。それにもかかわらず、これはそれなしでも行うことができます。選択の問題です。そして、理由は不明ですが、この方法も非常に高速に思えます..

于 2011-04-08T23:54:08.860 に答える