Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

SQL ADO connection и Access. Проблема вставки данных [D6, Access]


dalamar ©   (2004-01-08 04:10:00) 

Помогите пожалуйста решить задачу. Имеется подключение по ADO к Access DB. Также имеется ADOCommand в котором выполняется запрос:
INSERT INTO TableA
SELECT * FROM TableB
В TableA имеется индекс на поле code не допускающий дубликатов. При выполнении этого запроса в Access
Возникает prompt с сообщением о том что некоторые записи не уникальны и предлагает отменить операцию, или продолжить при условии, что неуникальные запи буду удалены.
Мне собсно и нужен такой результат - чтобы дублирующиеся записи были удалены из таблицы.
Теперь опишу проблему в Delphi. Дело в том что при выполнении этого запроса в ADOCommand Delphi ругается следующим образом:

"EOleException with message "Изменения не были успешно внесены из-за повторяющихся значений в индексе, ключевых полях или связях...""

Так вот вопрос. Как можно в Delphi игнорировать сообщения от Access или на крайний случай подавлять их?


dalamar   (2004-01-11 04:13:00) [1]

Спасибо большое всем мастерам, которые проявили интерес к данной проблеме!
Прошу простить меня за долгое молчание, вызванное отсутствием коннекта, а вовсе не из-за отсутствия интереса к проблеме.
Ваша дискуссия мне будет очень полезна.
Правда, за время с момента публикации сообщения, я уже решил данную проблему, написанием программы в Access, которая делает именно то что я хотел, и которая игнорирует сообщения аксеса на тему дубликатов. Но тем не менее, это было скорее быстрое, и может быть не очень эффективное решение, но зато задача с дубликатами решена, а это главное (...дороги которые мы выбираем...).
Вашт же предложения очень мне помогут, пори решении подобной задачи уже в другой среде.
Еще раз большое всем спасибо!


sniknik   (2004-01-10 18:49:00) [2]

логику никто менять не будет она правильная, и куча запросов уже под нее написано.

наконецто правильный запрос (похоже, проверять не буду), осталось ответить на уже поднимавшийся вопрос, какое значение считать правильным для записи первое (как у тебя) а может последнее (last)? или максимальное/минимальное?
и вопрос решон, даже вопреки желаниям автора. ;о)) (не отвечает значит уже ничего не хочет)


BlackTiger   (2004-01-10 17:29:00) [3]

Да, не работает. И я даже знаю почему. И не будет работать, пока кто-нить не изменит логику обработки вложенных запросов. Аксесс, кстати пытается (при вышеописанных условиях!) вставить все 3 записи. А вот, если на момент записка запроса, запись (MyTable1.F1=1) уже есть, то... ИДЕЯ!!!

INSERT INTO MyTable1(F1, F2)
SELECT MyTable2.F1, First(MyTable2.F2) AS FirstOfF2
FROM MyTable2
WHERE MyTable2.F1 NOT IN (SELECT F1 FROM MyTable1)
GROUP BY MyTable2.F1


sniknik   (2004-01-09 16:18:00) [4]

> 2 sniknik: :) зануда ты... :)
> теперь должно быть правильно (для Аксесса):
...
а вот и нет!!! ;о)))) (меня уже обуревает дикая радость ;о), без всякого повода. с ума схожу?)

допустим в MyTable1 F1 поле с уникальным индексом, допустим таблица пустая совсем.
в MyTable2 значения
f1, f2
1, 2
1, 3
1, 4
....
что будет? 1 в первой таблице нет (допустили что она пустая).
и какое значение f2 правильное?
(не кажется что мы начали повторятся?)


BlackTiger   (2004-01-09 16:04:00) [5]

2 sniknik: :) зануда ты... :)

теперь должно быть правильно (для Аксесса):

INSERT INTO MyTable1 (F1, F2)
SELECT F1, F2
FROM MyTable2
WHERE MyTable2.F1 NOT IN (SELECT F1 FROM MyTable1)


А удаление немного покурит всторонке.

2 АВТОР:
В TableA имеется индекс на поле code не допускающий дубликатов. При выполнении этого запроса в Access
Возникает prompt с сообщением о том что некоторые записи не уникальны и предлагает отменить операцию, или продолжить при условии, что неуникальные запи буду удалены.


Начнем с того, что ЭТО действительно ТОЛЬКО для самого Аксесса! К тому же записи будут НЕ УДАЛЕНЫ, а ПРОИГНОРОРОВАНЫ! А в догонку - Аксесс не использует запросы в этом случае, а обрабатывает каждую запись через Jet/ADO.

Аналог для Дельфи:

//...
ADOTable1.First();
while not ADOTable1.EOF do
begin
try
ADOTable2.Insert();
ADOTAble2.FieldValues[0] := ADOTable1.FieldValues[0];
ADOTAble2.FieldValues[1] := ADOTable1.FieldValues[1];
ADOTable2.Post();
except
end;
ADOTable1.Next();
end;
//...

Вот это аналог того, что делает Аксесс


sniknik   (2004-01-09 14:58:00) [6]

да нет и так не правильно
первое
проверяеш одни поля вставляеш другие а если вставляемое значение уже есть?
второе
удаления у тебя нет, и одним запросом не сделаеш, а нужна перезапись а не запись только того чего в ней нет.
третье см. > sniknik © (08.01.04 11:36) [2] значение при дистинкте, это у тебя тоже неотслеживается.

p.s. зачем паришся? пока нет ответа на > sniknik © (08.01.04 13:01) [4] это бессмысленно. потому как предполагается 2 в корне отличающихся варианта. обсуждать оба на всякий случай при полном отсутствии интереса от автора ломает.


BlackTiger   (2004-01-09 14:07:00) [7]

2sniknik: :)

кАрочИ, правильно будет так (4й раз, блин...)

INSERT INTO MyTable1 (MyField1a, MyField2a)
SELECT DISTINCT MyField1b, MyField2b
FROM MyTable2
WHERE MyTable2.MyField1a NOT IN (SELECT MyField1a FROM MyTable1)


sniknik   (2004-01-08 19:07:00) [8]

сдается мне что условие
[7]
WHERE MyTable2.MyField1a NOT IN (SELECT MyField1a FROM MyTable2)
никогда не выполнится, по русски "значение поля таблици не входит в выборку значений этого поля этой же таблицы" это как?
[6]
а если проверять на вхождение в записываемую таблицу то как с перезаписью быть старых на новые и + если значения в первой нет а во второй их 2? тотже глюк будет.


BlackTiger   (2004-01-08 18:42:00) [9]

Да что ж такое! Опять ошибка.


INSERT INTOMyTable1 (MyField1a, MyField2a)
SELECT DISTINCTMyField1b, MyField2b
FROMMyTable2
WHEREMyTable2.MyField1a NOT IN (SELECTMyField1a FROMMyTable2)


Вроде так


BlackTiger   (2004-01-08 18:41:00) [10]

Упс! Ошибочка


INSERT INTOMyTable1 (MyField1a, MyField2a)
SELECT DISTINCTMyField1b, MyField2b
FROMMyTable2
WHEREMyTable2.MyField1b NOT IN (SELECTMyField1a FROMMyTable1)


Вроде так


BlackTiger   (2004-01-08 18:40:00) [11]


INSERT INTOMyTable1 (MyField1a, MyField2a)
SELECT DISTINCTMyField1b, MyField2b
FROMMyTable2
WHERE MyTable2.MyField1b NOT IN (SELECT MyField1a FROM MyTable2)


Вроде так


sniknik   (2004-01-08 13:01:00) [12]

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


DCoder   (2004-01-08 12:06:00) [13]

Согласен, тогда пусть построчно вставляет, а не одним запросом
и обрабатывает исключения
try
втавить
except
отругаться в лог
end
при этом будет в результирующей таблице только первые строки
с одинаковым значением в поле code


sniknik   (2004-01-08 11:36:00) [14]

см
> DCoder © (08.01.04 11:12) [1]
угу, почти правильно (почти потому как будет давать уникальный по всему списку, а в нем могут быть повторения одного поля
code prompt
1111, "Test"
1111, "Job"
....
уникально не так ли, а коде повторяется
)
причем если записи в таблице уже есть то выполняй еще и запрос на удаление записей с code сушествующими во вставляемой таблице.


DCoder   (2004-01-08 11:12:00) [15]

INSERT INTO TableA (<список полей>)
SELECT distinct<список полей> FROM TableB


Наверх

Титульная страница Поиск, карта сайта Написать письмо