Форум: "Базы";
Текущий архив: 2003.09.08;
Скачать: [xml.tar.bz2];
ВнизПроверка вводимого значения на совпадение Найти похожие ветки
← →
Lexa_m (2003-08-14 23:34) [0]Привет Всем!
Выношу на суд профессионалов:
Есть форма с компонентом DBGrid на ней. Этот DBGrid связан с таблицей из модуля данных и отображает соответствующие записи. Вставка и редактирование этой таблицы осуществляется через другую форму с компонентами DBEdit. Так вот, мне необходимо проверить одно поле до записи в его в таблицу на его совпадение с уже существующими там полями!
Вот что сделал я:
До перевода таблицы в режим вставки (DM.TTable.Append;) я заношу данные полей из таблицы в динамический массив:
A[i]:=DM.TTableNumber.AsInteger(в цикле от First до EOF).
Потом разрешаю вставку и в форме редактирования с помощью DBEditOnChange проверяю на совпадение с элементами этого массива DBEdit.Text (опять в цикле). Если есть совпадение, то выдаю предупреждение и жду нового ввода.
Мне кажется, что это слишком уж сложно! Может есть что-то попроще?
← →
Johnmen (2003-08-14 23:49) [1]Самое простое и правильное - иметь уникальный индекс на указанное поле. Тогда останется лишь грамотно обработать ошибку добавления новой записи.
← →
Lexa_m (2003-08-15 09:47) [2]Да, если иметь уникальный индекс на это поле, то БД будет выдавать сообщение об ошибке, которое потом можно обработать. Но таблица уже имеет индекс. Могу ли я добавить еще один и уже его отрабатывать?
← →
Johnmen (2003-08-15 09:56) [3]Можешь. Если захочешь...:)))
← →
Жук (2003-08-15 10:01) [4]Можно при добавлении выполнить запрос к базе на выборку совпадений с вводимым. Если он пуст, то добавляем, если нет, то ругаемся.
← →
Nikolay M. (2003-08-15 10:39) [5]Создать уникальный индекс в DataSet, тогда проверка на уникальность будет производиться ДО отправки записи в БД. Но обрабатывать ошибку с сервера все равно нужно: а вдруг другой пользователь ввел такое же значение секундой раньше.
← →
Johnmen (2003-08-15 10:44) [6]>Nikolay M. © (15.08.03 10:39) [5]
>Создать уникальный индекс в DataSet...
Это как ?
>...обрабатывать ошибку с сервера ...
Ниоткуда не видно, что у автора вообще есть к.-л.сервер.
← →
Nikolay M. (2003-08-15 12:00) [7]
> >Создать уникальный индекс в DataSet...
> Это как ?
IndexDefs
> >...обрабатывать ошибку с сервера ...
> Ниоткуда не видно, что у автора вообще есть к.-л.сервер.
...обрабатывать ошибку БД при попытке вставить значение в поле, нарушающее UNIQUE INDEX по этому полю... - так корректнее, но придраться все равно можно. Чукча не читатель, чукча писатель..
← →
Johnmen (2003-08-15 12:12) [8]>Nikolay M. © (15.08.03 12:00) [7]
Я не придирался. Продолжаю непридираться :)
У TDataSet нет IndexDefs.
У TTable есть, но это не означает уникальности.
← →
MsGuns (2003-08-15 13:12) [9]Зачем, чтобы проверить на дубликат значения в поле таблицы надо обязательно попытаться всунуть в НД запись. При этом если поле не индексировано, то создавать для этого спец.индекс (плевать на правило 20% ?)
"Нехирургических" способов море:
- позиционирование Locate с восстановлением позиции курсора
- Метод датасета LookUp, не меняющий курсор
- "Левый" запрос на поиск значения
- и т.д.
Только вот я бы не делал такого поиска по каждому чиху (изменения содержимого едита) узера. Только по спец.кнопке после того, как он введет усе шо треба.
← →
Lexa_m (2003-08-15 13:33) [10]Насчет запроса-это хорошо, но у меня не Query, а Table.
А вот можно поподробнее на тему:
-"Левого" запроса (жутко интересно)?
-Метода датасета LookUp, кот. не меняет курсор?
-И вторичного индекса?
← →
paul_k (2003-08-15 13:47) [11]Левый запрос
создаеш TQuery (или TAdoQuery, или через что ты к базе конектишся)
свойству SQL присваиваеш что то типа
select count(field_name) as QQ
from table_name
where field_name = "что ты проверяеш"
окрываеш
смотриш значение QQ
если ноль то добавляеш иначе ругаешся.
но проверить так каждое из 20 полей на форме дело крайне небыстрое.
← →
MsGuns (2003-08-15 13:55) [12]>Lexa_m © (15.08.03 13:33) [10]
>А вот можно поподробнее на тему:
-"Левого" запроса (жутко интересно)?
Кидаешь в датамодуль с компонентами БД лишний ("левый" TQuery (Если BDE) или пару TIBQuery+TIBSQL (если IB) и т.д. Обзываешь их как-нить quXXX. Если надо где-нибудь выполнить какую-нибудь операцию с таблицей БД вне контекста интерфейса (в данном случае - курсора, поддерживаемого отображаемым в гриде TTable`ом), например, найти некую запись, то "на лету" формируешь и выполняешь запрос:
result := false;
with quXXX do
begin
if Active then Close;
SQL.Clear;
SQL.Add("Select * from <Tablename> ");
SQL.Add(" Where <FielName>="+QuotedStr(Edit1.Text));
try
Open;
if RecordCount>1 then result := true;
Close;
except
ShowMessage("Oooops");
exit;
end;
end;
>-Метода датасета LookUp, кот. не меняет курсор?
Почитай методы TBDEDataSet.
← →
MsGuns (2003-08-15 13:58) [13]
if RecordCount> 0 then result := true;
Сори, очепятка :(
← →
paul_k (2003-08-15 14:03) [14]2MsGuns
а черезselect count
, все же эффективнее
← →
Lexa_m (2003-08-15 17:17) [15]Да, левые запросы-это классно!!! Не видел ничего подобного в литературе. И про Lookup понятно.
А про вторичные индексы? Я так дотошно, чтоб уж совсем разобраться...
← →
MsGuns (2003-08-15 17:34) [16]Вторичный индекс создается исключительно для ускорения выборки или контроля на уникальность. Однако наряду с укорением можно получить и обратный эффект ("перебарщивание" обычно бывает если нарушено правило 20 или индекс вешается на длинное символьное поле, к примеру). А вообще-то о пользе и вреде индексов очень много написано практически в любой книге по БД. Одно могу сказать более-менее точно: создание индекса для решения локальной (клиентской) проблемы в 75% случаев не оправдано и может с успехом (в рамках общей эффективнсти системы) компенсироваться оптимизацией запросов к серверу.
Использование же вторичных в локалках вообще чревато, если БД юзается одновременно хотя бы 5 узерами. Хотя вообще-то это сильно зависит от формата БД
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2003.09.08;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.007 c