Подавляет ли MS Access нарушения первичных ключей на вставках? - PullRequest
5 голосов
/ 19 августа 2011

Я перезаписываю базу данных MS Access на SQL-сервер и обнаружил странную проблему в Access, с которой, я надеюсь, кто-то может помочь.

У меня есть таблица, назовем ее «Главная» с первичным ключом учетной записи, который проиндексирован и не допускает дубликатов.Кажется достаточно простым, но моя проблема возникает, когда данные вставляются.

Мой запрос INSERT (количество полей было ограничено для краткости)

INSERT INTO Main (Account, SentDate, Amount)
SELECT C.Account, C.SentDate, C.Amount
FROM 
    (CALLS C LEFT JOIN Bals B ON C.Account = B.ACCT_ID) 
LEFT JOIN AggAnt A ON C.Account = A.Account

Проблема заключается в том, еслиЯ выполняю часть запроса SELECT, получаю 2365 записей, но когда я запускаю INSERT, я получаю 2364 записи.Поэтому я проверил некоторые данные и обнаружил, что одна учетная запись дублирована, разница между записями - SentDate и Amount.Но Access вставляет только одну из записей и не выдает никаких сообщений об ошибках или чего-либо еще.В запросе ничего не говорится о выборе самой последней даты и т. Д.

Образцы данных:

Account    SentDate   Amount
12345678   8/1/2011   123.00
23456789   8/1/2011   45678.00
34567890   8/1/2011   7850.00
45678912   8/1/2011   635.00
45678912   5/1/2011   982.00
56789123   8/1/2011   2639.00

В примере у меня есть одна учетная запись, которая дублируется 45678912 при запуске INSERTЯ не получаю ошибок, и я получаю запись от 01.08.2011.

Почему Access не выдает ошибку, когда это нарушает PK на столе?Есть ли какая-то особенность в Access, чтобы выбрать одну запись и просто пропустить другую?

Я полностью озадачен этой проблемой, поэтому любая помощь будет полезна.

Ответы [ 3 ]

5 голосов
/ 19 августа 2011

Как вы выполняете запрос? Если вы используете DoCmd.RunSQL, переключитесь на метод .Execute объекта базы данных DAO и используйте dbFailOnError.

Dim db As DAO.Database
Dim strInsert As String
strInsert = "your insert statement"
Set db = CurrentDb
db.Execute strInsert, dbFailOnError
Set db = Nothing

Редактировать : Если Main является ссылкой ODBC на таблицу SQL Server, я бы рассмотрел Коллекция ошибок (DAO) после db.Execute strInsert, dbFailOnError

2 голосов
/ 19 августа 2011

После того, как HansUp указал мне направление проверки SetWarnings = false. Я обнаружил, что он похоронен в моем коде, поэтому не было предупреждений о том, что записи не вставляются из-за нарушений первичного ключа.

Следует предостеречь, что вы хотите, чтобы эти сообщения подавлялись.

2 голосов
/ 19 августа 2011

Есть ли какая-то особенность в Access для [обновления] одной записи и просто пропуска другой?

Да, вы можете контролировать это поведение на уровне двигателя (также на уровне набора записей)при использовании OLE DB).

Для OLE DB (например, ADO) значение Jet OLEDB:Global Partial Bulk Ops:

определяет поведение ядра базы данных Jet при сбое массовых операций SQL DML.Если задано разрешение частичного завершения массовых операций, могут возникать противоречивые изменения, поскольку операции с некоторыми записями могут быть успешными, а другие - с ошибками.Если установлено, чтобы частичное выполнение массовых операций не выполнялось, все изменения откатываются, если возникает одна ошибка.Параметр Jet OLEDB: глобальные частичные операции можно переопределить для каждого набора записей , установив свойство Jet OLEDB: частичные операции в Свойства коллекция Recordset объекта.

Обратите внимание, что по умолчанию не разрешается частичное завершение массовых операций.

...