Добавить запись, только если не существует в Access 2007 - PullRequest
4 голосов
/ 07 октября 2009

У меня есть таблица, скажем, она хранит имена сотрудников (это не совсем та ситуация, но концепция та же самая), и первичный ключ имеет значение autonumber. При добавлении нового сотрудника я хочу проверить, существует ли это имя в базе данных перед его добавлением, и, возможно, выдать ошибку, если оно уже существует. Как я могу сделать это из обычной формы добавления для таблицы?

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

Есть ли простой способ сделать это?

Ответы [ 6 ]

2 голосов
/ 07 октября 2009

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

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

В этих случаях вам нужно написать свой интерфейс, чтобы он не был напрямую связан с таблицей (в терминах доступа создайте форму с пустым источником записи), соберите информацию в различных элементах управления, выполните проверки в коде (часто используя DCOUNT и DLOOKUP), а затем выполните серию операторов INSERT и UPDATE в коде с использованием DoCmd.RunSQL.

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

2 голосов
/ 07 октября 2009

В представлении дизайна таблицы можно сделать столбец Имя проиндексированным без дубликатов

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

1 голос
/ 09 октября 2009

Я поставлю свой голос на стороне использования несвязанной формы для сбора обязательных полей и представления возможных дубликатов. Вот пример из недавнего приложения:


(источник: dfenton.com )

(я отредактировал имена реальных людей и вставил поддельные, а сглаживание моей графической программы отличается от ClearType, отсюда и странность)

Идея здесь заключается в том, что пользователь помещает данные в любое из четырех полей (не требуется для всех из них) и нажимает кнопку ДОБАВИТЬ. В первый раз он заполняет возможные совпадения. Затем пользователь должен решить, является ли одно из совпадений предполагаемым лицом или нет, и либо снова щелкнуть «ДОБАВИТЬ» (чтобы добавить его, даже если это дубликат), либо нажать кнопку внизу, чтобы перейти к выбранному клиенту.

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

В дополнение к этому, есть сопоставление с использованием Soundex, Soundex2 и Simil, а также подстрок и подстрок в сочетании с Soundex / Soundex2 / Simil. В этом случае вторая запись является дубликатом, но Soundex и Soundex2 не улавливают его, в то время как Simil возвращает сходство на 67%, и я установил чувствительность более 50%, поэтому «Wightman» отображается как закрытый Матч с "Whiteman". Последний из всех. Я не уверен, почему последние два в списке, но, очевидно, есть некоторые причины для этого (вероятно, Simil и инициалы).

Я управляю именами, компанией и электронной почтой через процедуры подсчета очков, а затем использую комбинацию для вычисления окончательного результата. Я храню значения Soundex и Soundex2 в каждой записи о человеке. Simil, конечно, нужно вычислять на лету, но он работает нормально, потому что оптимизатор запросов Jet / ACE знает, что нужно ограничивать другие поля, и, таким образом, вызывает Simil для значительно сокращенного набора данных (это на самом деле первое приложение Я использовал Simil для, и пока он отлично работает).

Требуется небольшая пауза для загрузки возможных совпадений, но она не слишком медленная (приложение, из которого взята эта версия, имеет около 8K существующих записей, с которыми тестируется). Я создал этот дизайн для приложения, имеющего 250 тыс. Записей в таблице person, и оно работало очень хорошо, когда серверная часть была все еще Jet, и все еще прекрасно работает после того, как серверная часть была обновлена ​​до SQL Server несколько лет назад.

0 голосов
/ 12 октября 2009

Спасибо за всю информацию здесь. Это отличная информация, и я бы использовал ее, как самоучка.

Самый простой способ, который я нашел здесь, - использовать индекс для всех полей, которые я хочу (без дубликатов). Хитрость заключается в том, чтобы действительно использовать несколько индексов (это в основном позволяет составной индекс или «виртуальный» индекс, который состоит из более чем одного поля).

Метод можно найти здесь: http://en.allexperts.com/q/Using-MS-Access-1440/Creating-Unique-Value-check.htm,, но я бы повторил его в случае удаления ссылки.

Из справки Access: Предотвращение ввода повторяющихся значений в комбинацию полей

Создать индекс с несколькими полями, используя поля, для которых вы хотите запретить повторяющиеся значения. Оставьте окно индексов открытым, когда вы закончили определение индекса.

Как?

  1. Открыть таблицу в режиме конструктора.
  2. Нажмите Индексы на панели инструментов.
  3. В первой пустой строке в указателе Имя столбца, введите имя для индекс. Вы можете назвать индекс после одно из полей индекса или используйте другое имя.
  4. В столбце Имя поля щелкните стрелка и выберите первое поле для индекс.
  5. В следующем ряду в поле Имя выберите второе поле для индекс. (Оставьте имя индекса пустой столбец в этой строке.) Повторите этот шаг, пока вы не выбрали все поля, которые вы хотите включить в этом индексе. Порядок сортировки по умолчанию По возрастанию. Выберите Descending в Столбец Порядок сортировки индексов окно для сортировки соответствующего данные поля в порядке убывания.
  6. В верхней части указателей щелкните новое имя индекса.
  7. В нижней части индексов щелкните по уникальному свойству и нажмите кнопку Да.

Теперь вы должны иметь возможность не вводить записи с одинаковыми значениями в индексах. У меня возникли проблемы, когда я все еще мог вводить значения, если в одном из проиндексированных полей есть пробел (есть возможность проверить / игнорировать нулевые значения при настройке индекса), но у меня это не сработало, но решение сработало, потому что В любом случае у меня не будет нулевых значений.

0 голосов
/ 12 октября 2009

В мире SQL это называется 'UPSERT'. Стандарт ISO / ANSI SQL-99 определяет синтаксис MERGE, который был недавно добавлен в SQL Server 2008 с собственными расширениями стандарта. К счастью, именно так движется мир SQL, следуя по пути, проложенному MySQL.

К сожалению, движок базы данных Access - это совсем другая история. Даже простой UPDATE не поддерживает скалярный синтаксис подзапроса SQL-92, вместо этого имеет свой собственный, запатентованный с произвольными (непредсказуемыми? Безусловно недокументированными) результатами. Команда Windows пресекла попытки SQL Server исправить это в Jet 4.0. Даже сейчас, когда у команды Access есть собственный формат ACE, они, похоже, не заинтересованы вносить изменения в синтаксис SQL. Таким образом, вероятность того, что продукт, использующий стандарт SQL-99, или даже собственную альтернативу, очень мала: (

Один очевидный обходной путь, предполагающий, что производительность не является проблемой (как всегда, должно быть проверено), - это выполнить INSERT, игнорируя любые ошибки при сбое ключа, затем сразу после выполнения UPDATE. Даже если вы придерживаетесь (очень сомнительно IMO) «автономного номера PK на каждом столе», у вас должен быть уникальный ключ к естественному ключу, поэтому все должно быть в порядке.

0 голосов
/ 08 октября 2009

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

В каждом городе всегда будет два Джона Смита или Джейн Джонс.

Я читал о ситуации, когда две женщины с одинаковыми именем, отчеством и фамилией и датами рождения находились в больнице в самом центре. Действительно страшно это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...