Как удалить повторяющиеся строки из базы данных доступа MS (C #) - PullRequest
2 голосов
/ 08 апреля 2011

Я просматривал различные сайты и коды, но, похоже, ничто не положило конец моим страданиям.Либо они помогают найти и удалить дубликаты для определенного столбца, либо они удаляют только данные, а не саму базовую базу данных.Я хочу удалить повторяющиеся строки из таблицы "table1" моего файла MDB.

Чтобы прояснить мои требования:

  1. для любого столбца таблицы не задан первичный ключ (и я не могу себе этого позволить)
  2. Я хочу удалить всеповторяющиеся строки, но один!(порядок не имеет значения)
  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 ]

3 голосов
/ 09 апреля 2011

Если вы еще этого не поняли, движки баз данных склонны мыслить абсолютно.Если вы хотите удалить строку, вы должны указать ей, как идентифицировать эту строку.Итак, первичные ключи.

Сказав, что, как правило, но не всегда, есть два (2) способа сделать это:

  1. Узнайте, поддерживает ли Access синтаксис, сообщающий DELETE толькорассмотрим «первые N строк», аналогично DELETE TOP 1 FROM ...
  2. Извлечение отдельного набора данных из таблицы, удаление всех строк в нем и вставка в него отдельных строк

Первое может быть возможным, но это зависит от того, поддерживает ли Access какой-либо синтаксис, который делает это возможным.Например.Microsoft SQL Server поддерживает выполнение оператора SET ROWCOUNT 1 перед DELETE, а затем DELETE удалит только 1 строку и затем остановится.Я не знаю, будет ли это делать Access.

Вторым будет больно, если у вас есть внешние ключи, но я собираюсь выйти на конечность и предположить, что, поскольку у вас нетпервичные ключи, у вас нет внешних ключей, поэтому целостность данных здесь не является реальной проблемой.

3 голосов
/ 09 апреля 2011

Вот статья, в которой обсуждается несколько подходов к удалению дублирующихся строк в SQL Server, но я подозреваю, что это применимо и к MS Access: Удаление дубликатов из таблицы в SQL Server

2 голосов
/ 09 апреля 2011

Хорошо, это полный взлом, но похоже, что это единственный вариант ...

Сделайте SELECT DISTINCTROW со своего стола. Удалить все записи из вашей таблицы. Вставьте отдельные строки обратно в.

Синтаксис DISTINCTROW .

0 голосов
/ 09 апреля 2011

Поскольку ни один из ответов не был для меня удовлетворительным (я просто слишком новичок, чтобы понять скупую и слегка технически понятную манеру, использованную здесь более знающими и опытными людьми), я попробовал свой собственный вариант, чтобы сделать это.Я не мог понять, что делать с такими командами, как distinct или set 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();
    }

Редактировать: Извините, я пропустил, чтобы сказать, что я использовал уникальный столбец с первичным ключом, чтобы сделать это.Тем не менее, это может быть сделано и без этого.Просто вопрос выбора.И по неизвестным причинам этот метод кажется слишком быстрым ..

...