Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 04.04.2009, 22:18
BetaCoder BetaCoder вне форума
Прохожий
 
Регистрация: 03.03.2009
Сообщения: 16
Репутация: 10
Печаль Удаление дубликатов в ADO, Что сделать чтобы в базе данных...

Всем доброго времени суток.
Вот какая проблема:

Работаю в delphi 7
данные хранятся в файле .mdb, через ADOgrid, ADOTable и остальные компоненты ADO.

в таблице rss есть поле link
мне нужно чтобы по этому полю искались дубликаты, проще говоря чтобы в этой таблице не было повторяющихся записей, а проверять это получится только по полю link, потому что ссылка уникальна, а остальные поля, такие как Тема - не уникальны

Не могу понять как это сделать

помогите... толи свойство для таблицы задать нужно, толи запрос какой написать... не понимаю я... в программе просто этот кусок кода не мой, я ни с Адо, ни с запросами не знаком...
Ответить с цитированием
  #2  
Старый 04.04.2009, 23:59
Аватар для Страдалецъ
Страдалецъ Страдалецъ вне форума
Гуру
 
Регистрация: 09.03.2009
Адрес: На курорте, из окна вижу теплое Баренцево море. Бррр.
Сообщения: 4,723
Репутация: 52347
По умолчанию

Отобрать все дубликаты в таблице rss можно так:
Код:
select Link from rss group by link having Count(Link)>1
А вот для правильного удаления дубликатов, надо отталкиваться от уникального ключа в rss. Если таковым является id, то запрос на удаление повторов будет таким:
Код:
delete Link where id in (select Max(id) from rss group by Link having Count(Link)>1)
__________________
Жизнь такова какова она есть и больше никакова.
Помогаю за спасибо.
Ответить с цитированием
  #3  
Старый 05.04.2009, 00:05
BetaCoder BetaCoder вне форума
Прохожий
 
Регистрация: 03.03.2009
Сообщения: 16
Репутация: 10
По умолчанию

Огромное мерси, сейчас попробую что нить сотворить с этим
__________________
www.forumforall.net - Мы создаем общение!
Ответить с цитированием
  #4  
Старый 05.04.2009, 00:11
BetaCoder BetaCoder вне форума
Прохожий
 
Регистрация: 03.03.2009
Сообщения: 16
Репутация: 10
По умолчанию

блин, не получается....
Как написать нужно?
ADOTable1.SQL := select Link from rss group by link having Count(Link)>1
или как?
__________________
www.forumforall.net - Мы создаем общение!
Ответить с цитированием
  #5  
Старый 05.04.2009, 00:25
Аватар для Страдалецъ
Страдалецъ Страдалецъ вне форума
Гуру
 
Регистрация: 09.03.2009
Адрес: На курорте, из окна вижу теплое Баренцево море. Бррр.
Сообщения: 4,723
Репутация: 52347
По умолчанию

Ну вы хоть с синтаксисом немножко ознакомьтесь.
Код:
ADOTable1.SQL.text := 'select Link from rss group by link having Count(Link)>1';
ADOTable1.Open;
__________________
Жизнь такова какова она есть и больше никакова.
Помогаю за спасибо.
Ответить с цитированием
  #6  
Старый 05.04.2009, 00:50
BetaCoder BetaCoder вне форума
Прохожий
 
Регистрация: 03.03.2009
Сообщения: 16
Репутация: 10
По умолчанию

неа, в обоих примерах выдает ошибку
[Error] Unit1.pas(362): Incompatible types: 'TStrings' and 'String'

Пишу так:
Код:
ADOQuery1.SQL := 'delete Link where id in (select Max(id) from rss group by Link having Count(Link)>1)';
   ADOTable1.Open;
__________________
www.forumforall.net - Мы создаем общение!
Ответить с цитированием
  #7  
Старый 05.04.2009, 01:24
Аватар для Страдалецъ
Страдалецъ Страдалецъ вне форума
Гуру
 
Регистрация: 09.03.2009
Адрес: На курорте, из окна вижу теплое Баренцево море. Бррр.
Сообщения: 4,723
Репутация: 52347
По умолчанию

Вы сравните, то что вы написали и что я предложил. Найдите отличие.
__________________
Жизнь такова какова она есть и больше никакова.
Помогаю за спасибо.
Ответить с цитированием
  #8  
Старый 05.04.2009, 01:32
BetaCoder BetaCoder вне форума
Прохожий
 
Регистрация: 03.03.2009
Сообщения: 16
Репутация: 10
По умолчанию

А у меня по другому не работает,
когда я пишу
ADOTable1.SQL.text
дельфи выдает ошибку, что SQL необъявленная переменная, а как ее объявить я не знаю, ничего похожего на ADOSQL нет, зато есть ADOQuery...
__________________
www.forumforall.net - Мы создаем общение!
Ответить с цитированием
  #9  
Старый 05.04.2009, 02:06
Аватар для Страдалецъ
Страдалецъ Страдалецъ вне форума
Гуру
 
Регистрация: 09.03.2009
Адрес: На курорте, из окна вижу теплое Баренцево море. Бррр.
Сообщения: 4,723
Репутация: 52347
По умолчанию

Давайте так. Вы сюда код свой выложите и содержимое dfm-файла. Тогда будем дальше разбираться.
__________________
Жизнь такова какова она есть и больше никакова.
Помогаю за спасибо.
Ответить с цитированием
  #10  
Старый 05.04.2009, 02:22
BetaCoder BetaCoder вне форума
Прохожий
 
Регистрация: 03.03.2009
Сообщения: 16
Репутация: 10
По умолчанию

Хорошо =)
код:
Код:
   adotable1.Insert;
   title.value:=_node.selectnodes('//item').item[i].selectSingleNode('title').Text;
   link.value:=_node.selectnodes('//item').item[i].selectSingleNode('link').Text;
   description.Value:=_node.selectnodes('//item').item[i].selectSingleNode('description').Text;
   pubDate.Value:=_node.selectnodes('//item').item[i].selectSingleNode('pubDate').Text;
   adotable1.Post;
    countF :=  ADOTable1.RecordCount;   //  подсчет
    label1.caption := IntToStr(countF)    //   сообщений

dfm
Код:
  object DBMemo1: TDBMemo
    Left = 0
    Top = 360
    Width = 640
    Height = 97
    Align = alBottom
    DataField = 'description'
    DataSource = DataSource1
    ReadOnly = True
    TabOrder = 2
  end

  object DataSource1: TDataSource
    DataSet = ADOTable1
    Left = 480
    Top = 56
  end
  object ADOTable1: TADOTable
    Active = True
    ConnectionString = 
      'Provider=Microsoft.Jet.OLEDB.4.0;Data Source=rssbase.mdb;Persist' +
      ' Security Info=False'
    CursorType = ctStatic
    TableName = 'rss'
    Left = 512
    Top = 56
    object title: TWideStringField
      DisplayLabel = #1058#1077#1084#1072
      DisplayWidth = 48
      FieldName = 'title'
      Size = 100
    end
    object link: TWideStringField
      DisplayLabel = #1057#1089#1099#1083#1082#1072
      DisplayWidth = 48
      FieldName = 'link'
      Size = 50
    end
    object description: TMemoField
      DisplayLabel = #1054#1087#1080#1089#1072#1085#1080#1077
      FieldName = 'description'
      Visible = False
      BlobType = ftMemo
    end
    object author: TWideStringField
      DisplayLabel = '/'
      FieldName = 'author'
      Size = 15
    end
    object pubDate: TWideStringField
      DisplayLabel = #1044#1072#1090#1072
      FieldName = 'pubDate'
      Size = 50
    end
    object ADOTable1id: TAutoIncField
      FieldName = 'id'
      ReadOnly = True
      Visible = False
    end
  end
  object ADOConnection1: TADOConnection
    Connected = True
    ConnectionString = 
      'Provider=Microsoft.Jet.OLEDB.4.0;Data Source=rssbase.mdb;Persist' +
      ' Security Info=False'
    LoginPrompt = False
    Mode = cmShareDenyNone
    Provider = 'Microsoft.Jet.OLEDB.4.0'
    Left = 552
    Top = 56
  end
 
  object ADOQuery1: TADOQuery
    Parameters = <>
    Left = 584
    Top = 56
  end
end
__________________
www.forumforall.net - Мы создаем общение!
Ответить с цитированием
  #11  
Старый 05.04.2009, 02:23
BetaCoder BetaCoder вне форума
Прохожий
 
Регистрация: 03.03.2009
Сообщения: 16
Репутация: 10
По умолчанию

Всем спокойной ночи! До завтра
__________________
www.forumforall.net - Мы создаем общение!
Ответить с цитированием
  #12  
Старый 05.04.2009, 03:03
Аватар для Страдалецъ
Страдалецъ Страдалецъ вне форума
Гуру
 
Регистрация: 09.03.2009
Адрес: На курорте, из окна вижу теплое Баренцево море. Бррр.
Сообщения: 4,723
Репутация: 52347
По умолчанию

1. Ваш AdoQuery1 надо связать с ADOConnection1
2. В вашей ADOTable1 вы используете ConnectionString, у вас есть уже один AdoConnection1 его и надо использовать для ADOTable1. Так у вас получается запрос в одной сессии, а таблица в другой.
3. Мой косяк - скопировал неглядя. Вместо ADOTable1.SQL.text надо писать ADOQuery1.SQL.Text
__________________
Жизнь такова какова она есть и больше никакова.
Помогаю за спасибо.
Ответить с цитированием
  #13  
Старый 05.04.2009, 08:59
BetaCoder BetaCoder вне форума
Прохожий
 
Регистрация: 03.03.2009
Сообщения: 16
Репутация: 10
По умолчанию

Спасибо, сейчас исправлю и отпишусь
__________________
www.forumforall.net - Мы создаем общение!
Ответить с цитированием
  #14  
Старый 05.04.2009, 09:36
BetaCoder BetaCoder вне форума
Прохожий
 
Регистрация: 03.03.2009
Сообщения: 16
Репутация: 10
По умолчанию

Вот что получилось:
1. Сначала я понял, что, как вы написали (и я сам тоже заметил), АДОТаблица уже использует параметры подключения, значит АДОКоннект вообще не нужен. Проверил - удалил АДОКоннект - программа осталась в работоспособности. Значит он ни на что не влиял. Мой косяк - видимо когда-то добавил коннект и забыл зачем добавил...

2. Добавляю на форму программы ADOQuery из вкладки АДО.
- В свойствах АДОзапроса нахожу параметр connection и настраиваю его (Provider=Microsoft.Jet.OLEDB.4.0;Data Source=rssbase.mdb;Persist Security Info=False)
- Теперь в коде вставляю после ADOTable1.Post;
Код:
ADOQuery.SQL.Text := 'select Link from rss group by link having Count(Link)>1';
ADOQuery.Open;
Результат: не работает... Все равно дубликаты добавляются =(

Пробую по другому запросу:
Код:
ADOQuery.SQL.Text := 'delete Link where id in (select Max(id) from rss group by Link having Count(Link)>1)';
ADOQuery.Open;
И опять ноль =( ...
Но еще и ошибку выдает при выполнении программы:
Цитата:
Ошибка синтаксиса (пропущен оператор) в выражении запроса ' Link where id in (select Max(id) from rss group by Link having Count(Link)>1)'

Что тут может быть не так? (я использую ваш второй запрос "delete Link where id in (select Max(id) from rss group by Link having Count(Link)>1)")
__________________
www.forumforall.net - Мы создаем общение!
Ответить с цитированием
  #15  
Старый 05.04.2009, 12:30
Аватар для Страдалецъ
Страдалецъ Страдалецъ вне форума
Гуру
 
Регистрация: 09.03.2009
Адрес: На курорте, из окна вижу теплое Баренцево море. Бррр.
Сообщения: 4,723
Репутация: 52347
По умолчанию

Цитата:
Сообщение от BetaCoder
Всем доброго времени суток.
в таблице rss есть поле link
мне нужно чтобы по этому полю искались дубликаты, проще говоря чтобы в этой таблице не было повторяющихся записей, а проверять это получится только по полю link, потому что ссылка уникальна, а остальные поля, такие как Тема - не уникальны
Вот что вы попросили. Найти дубликаты. Я вам и дал код для поиска дубликатов:
Код:
ADOQuery.SQL.Text := 'select Link from rss group by link having Count(Link)>1';
ADOQuery.Open;
В итоге вы получите в ADOQuery набор данных с которыми что-то надо делать, как минимум имеет смысл посмотреть их.

Что-бы удалить уже имеющиеся дубликаты я вам дал второй код:
Код:
ADOQuery.SQL.Text := 'delete Link where id in (select Max(id) from rss group by Link having Count(Link)>1)';
ADOQuery.ExecSQL;
НО для выполнения второго запроса надо уже использовать метод ADOQuery.ExecSQL т.к. запросы на удаление,вставку,изменение данных невозвращает никакого набора данных.

Теперь вы уже хотите проверять данные перед вставкой на дубликаты, а это уже третий запрос. Третьего запроса можно избежать, если вы на таблицу rss построите уникальный индекс по полю Link, но создать уникальный индекс на данные содержащие повторяющиеся значения невозможно, поэтому прежде чем его создать пропустите свои данные через запрос на удаление, о котором я писал чуть выше. Об этом я писал вам в теме из раздела БД.
__________________
Жизнь такова какова она есть и больше никакова.
Помогаю за спасибо.

Последний раз редактировалось Страдалецъ, 05.04.2009 в 12:42.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 23:38.


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2025