Как элегантно обрабатывать столбцы SQL Server NOT NULL в формах доступа? - PullRequest
0 голосов
/ 02 марта 2019

У меня интерфейс MS Access, связанный с базой данных SQL Server.

Если требуется какой-либо столбец, то естественным является включение NOT NULL в определение этого столбца (на уровне базы данных).Но это, кажется, создает проблемы на стороне доступа.Когда вы связываете форму с этой таблицей, поле, связанное с этим столбцом, оказывается довольно неудобным для пользователя.Если пользователь удалит текст из этого поля, он не сможет покинуть поле, пока не введет что-либо.Каждый раз, когда они пытаются покинуть поле, пока оно пустое, они получают эту ошибку:

Вы пытались присвоить нулевое значение переменной, которая не является типом данных Variant.

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

Private Sub Form_Error(DataErr As Integer, Response As Integer)
    If DataErr = 3162 Then
        Response = acDataErrContinue
        <check which field is blank>
        MsgBox "<some useful message>"
    End If
End Sub

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

Я опубликую два обходных пути, которые я нашел в качестве ответа, но я надеюсь, что есть лучшие способы, которые я пропустил.

Ответы [ 3 ]

0 голосов
/ 03 марта 2019

Вместо того, чтобы изменять определения бэкэнд-таблицы или пытаться «обмануть» доступ с несинхронизированными определениями связанных таблиц, вместо этого просто измените элементы управления для любого столбца «НЕ НУЛЬ» с привязки к несвязанномуполе (т. е. Очистите свойство ControlSource и измените имя элемента управления, например, добавив префикс, чтобы избежать раздражающих коллизий с именем базового поля.).

Это решение определенно будет менее «хрупким», но для этого потребуется вручную добавить код привязки для ряда других событий формы.Чтобы обеспечить единообразное взаимодействие с другими элементами управления и формами доступа, я бы по крайней мере реализовал Form_AfterInsert(), Form_AfterUpdate(), Form_BeforeInsert(), Form_BeforeUpdate(), Form_Current(), Form_Error(), Form_Undo().


PS. Хотя я не помню, чтобы раньше видел такое плохо сформулированное сообщение об ошибке, описанное общее поведениеидентичен для столбца таблицы Access с Required = True, который является эквивалентом интерфейса доступа * критерия NOT NULL.

0 голосов
/ 04 марта 2019

Я хотел бы предложить, если вы можете просто изменить все таблицы на сервере SQL, чтобы разрешить пустые значения для этих текстовых столбцов.Для битовых числовых столбцов по умолчанию их значение равно 0 sql на стороне сервера.В то время как наша отрасль склонна предлагать избегать нулевых значений, многие разработчики также хотят избегать нулевых значений, поэтому они отменяют проверку разрешенных пустых значений на стороне SQL-сервера.Проблема в том, что вы никогда не сможете убежать и избежать множества нулей.Возьмите простой запрос, скажем, клиенты и их последний номер счета + общая сумма счета.Но, конечно, ОЧЕНЬ распространенным было бы включение клиентов, которые ничего не купили в этом списке (клиенты без пока еще не выставленных счетов) или клиенты без какого-либо из миллиарда возможных случаев, когда дочерние записи еще не существуют. Я нахожу около 80%или БОЛЬШЕ из моих запросов в типичном приложении - ЛЕВЫЕ объединения. Это означает, что любая родительская запись без дочерних записей вернет ВСЕ ИЗ этих дочерних столбцов как ноль. Вы будете работать с, видеть, и ДОЛЖНЫ иметь дело с тоннами и тоннамиnull в приложении ДАЖЕ, если вы разрабатываете таблицы, НИКОГДА не допускаете нулевые значения. Вы не можете избежать их - вы просто не можете убежать от этих неприятных нулей.

Поскольку можно увидеть множество нулевых значений в коде и любом SQL-запросе (эти ОЧЕНЬобычные левые соединения), тогда, безусловно, лучшим решением будет просто разрешить и установить все текстовые столбцы как разрешающие нули. Я также могу много заявить, что если разработчик приложения не опустит ногу и сделает сильный выбор ВСЕГДА использоватьNULL, то вкрадывание NULLS и ZLS даЭто гораздо более серьезная проблема.

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

В конце дняAccess просто не работает с SQL сервером и разрешением выбора столбцов ZLS.

Для перехода на sql-сервер (а я занимался ими более 10 лет), без сомнения, нулевые значения для всех текстовых столбцов - безусловно, самый легкий выбор здесь.

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

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

Я также отмечу, что это предложение не является хорошим предложением, но это просто лучшее предложение, учитывая ограничения того, как Access работает с сервером SQL.Некоторые системы баз данных (oracle) действительно имеют общую настройку, которая говорит, что каждый ноль должен быть преобразован в ZLS, и поэтому вам не нужно заботиться о том, чтобы сказать следующее:

select * from tblCustomers where (City is null) or (City is = "")

Как показано выше, в тот момент, когда выРазрешить ZLS и NULL в ваше приложение - ЖЕ мгновение, когда вы создали огромный беспорядок.А научная дискуссия о неопределенности нулей - это просто дискуссия о другом дне.

Если вы разрабатываете с сервером Access + SQL, тогда нужно принять стандартный подход - я рекомендую, чтобы этот подход просто заключался в том, чтодля всех текстовых столбцов установлены пустые столбцы и столбцы даты.Для чисел и битовых столбцов по умолчанию их значение равно 0.

Это сводится к тому, что требует меньше усилий и работы.Либо попытайтесь внести некоторые ОСНОВНЫЕ изменения в приложение и произнесите открепление текстовых столбцов (это может быть огромным трудом).

Или

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

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

0 голосов
/ 02 марта 2019

Обдуманные мной два обходных пути:

  1. Не делайте столбец базы данных NOT NULL и полагайтесь исключительно на формы доступа для целостности данных, а не на базу данных.Читатели этой таблицы будут обременены неоднозначным столбцом, который на практике не будет содержать нулевые значения (пока код проверки формы является надежным), но теоретически может содержать нулевые значения из-за способа определения столбца в базе данных.Отсутствие этой 100% гарантии мешает, но в действительности может быть достаточно.

    Вердикт : легко, но небрежно - действуйте осторожно

  2. Злоупотребление тем, что ссылки Access на внешние таблицы должны обновляться вручную.Сделайте столбец NULL в SQL Server, обновите ссылку в Access, а затем снова сделайте столбец NOT NULL в SQL Server - но на этот раз не обновляйте ссылку в Access.

    Результатв том, что Access не поймет, что поле равно NOT NULL и, следовательно, оставит пользователя в покое.Они могут перемещаться по форме по своему усмотрению, не получая загадочную ошибку 3162 или не имея ограниченного фокуса.Если они попытаются сохранить форму, пока поле остается пустым, они получат ошибку ODBC, возникающую из базовой базы данных.Хотя это нежелательно, этого можно избежать, проверив пустые поля в Form_BeforeUpdate() и предоставив пользователю понятное сообщение об ошибке.

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

...