Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2003.05.01;
Скачать: [xml.tar.bz2];

Вниз

Как проверить при добавлении уникальность поля   Найти похожие ветки 

 
Begginer   (2003-04-11 01:40) [0]

Вот такая вот беда...
У меня Таблица1 (Поле1 - ключевое, Поле2), есть Индекс1 (Поле2), в свойствах индекса указана его уникальность.
При добавлении новой записи мне нужно предупредить пользователя, что Поле2 с таким значением
уже существует.
Если нигде ничего не прописывать, то сама Delphi выдает "ошибка в индексе Индекс1" или что-то в этом роде, а мне нужно определить именно для какого поля было нарушено свойство уникальности, потому что в других таблицах таких полей много.
Запись добавляется в отдельной форме, то есть таблица уже в состоянии Edit (пустая запись создана и я её модифицирую), осталость только грамотно заPost"ить. Но как?
Как это сделать? Кому не лень ответте, plz.


 
ЮЮ   (2003-04-11 03:34) [1]

В той кнопочке на форме перед Post сделать запрос к БД по заполненным во вставляемой записи ключевым полям и если запрос вернёт запись сообщить об этом пользоавтелю


 
Жук   (2003-04-11 08:20) [2]

А вообще-то изврат - давать юзверю возможность редактирования ключевого поля...


 
Anatoly Podgoretsky   (2003-04-11 08:23) [3]

Жук © (11.04.03 08:20)
Уникальный индекмс <> ключевое поле!


 
NAlexey   (2003-04-11 08:32) [4]

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

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

>Beginer
Объясни конкретней, если я правильно догнал то у тебя дело обстоит следующим образом у тебя поле имеющее уникальность, множество таблиц в которых есть поля названия которых могут совпадать с этим полем. На момент вставки тебе известно какую таблицу редактирует пользователь, и название поля в редактируемой таблице. Если в блоке try except возникает ошибка редактирования уникального ключа то выкидывать его говоря название таблицы и название редактируемого поля. Вроде так...


 
Johnmen   (2003-04-11 09:17) [5]

>NAlexey © (11.04.03 08:32)
>, хотя может я ошибаюсь.

Ага. Разговор о редактировании полей, входящих в уникальный индекс.

>...ошибка редактирования уникального ключа...

Индекса ! А это - Anatoly Podgoretsky © (11.04.03 08:23)

>...и название редактируемого поля. Вроде так...

А если их несколько ?




 
Mike Kouzmine   (2003-04-11 09:18) [6]

Или на OnChange поля поиск по дубликату НД и сообщение или переход на это поле или обработка OnPostError


 
Begginer   (2003-04-11 10:15) [7]

Table1 в ней поля: Field1(ключевое, autoinc), Field2, Field3.
Index1 в нем поля: Field2 ...допустим так.
И вот я уже ввел записи:
Field1 Field2 Field3
1 A1 a
2 B2 a
3 A2 a
и т.д.
И теперь я ввожу: x (это autoinc поле),"B2","a". Index1 не пропустит значение Field2="B2".
Так, как мне !граматно! узнать, что значение "B2" уже существует в момент добавления записи?
Пробижаться по всем записям и сравнить, я не могу, потому что потеряю новую (текущую, с которой работаю). Можно написать обработчик события OnPostError, но код ошибки вернет только имя индекса, а не поле в нем.


 
Mike Kouzmine   (2003-04-11 10:20) [8]

А зачем вводить х?
Так значение поля в состоянии dsInsert не измениться (при ошибке сохранения). Берешь его, делаешь кацель и ищешь


 
Johnmen   (2003-04-11 10:25) [9]

Тебе же уже ответили ! ЮЮ © (11.04.03 03:34)


 
AlexSerp   (2003-04-11 10:40) [10]

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

try
post;
except
// Сообщим о том, что непорядок;
ShowMessage("Невозиожно сохранить, т.к. .........");
Abort; // запретим сохранение
end;{try}


 
Johnmen   (2003-04-11 10:54) [11]

>AlexSerp © (11.04.03 10:40)

Не надо забывать :

>>...и название редактируемого поля. Вроде так...
>А если их несколько ?


>ShowMessage("Невозиожно сохранить, т.к. .........");

И вот здесь, где точки, поподробней...


 
AlexSerp   (2003-04-11 11:26) [12]

Вместо многоточия надо подставить строку, которую надо получить из разбора EXCEPTION, в котором будет имя индекса.
Соответственно, после исправления ошибки в одном поле, если есть ошибки в других уникальных полях, перед сохранением будем попадать на try-блок столько раз сколько будет ошибок.
Можно сделать внешний файл с описанием ошибок.
Номер ошибки будет один и тот же, а имя индекса разное.
Имя индекса и выступит как определитель в каком поле произошла ошибка.
Т.е. имеем во внешнем файле EXCEPTION-текст, а к нему русский текст, понятный для юзера.
Если непонятно объяснил - скажите, попробую яснее выразиться.


 
MsGuns   (2003-04-11 11:34) [13]

Для того, чтобы посмотреть есть ли в таблице некоторые значения ЛЮБЫХ полей, не надо ни постить новую (измененную) запись, ни тем более "левые" запросы. Метод LookUp класса TBDEDataSet и придуман для этого ! (Если, конечно, используются компоненты BDE)


 
Johnmen   (2003-04-11 11:37) [14]

>Имя индекса и выступит как определитель в каком поле произошла ошибка.

Индекс может быть и не по одному полю...


 
AlexSerp   (2003-04-11 11:49) [15]

LookUp это хорошо.
Но если создается новый индекс без участия разработчика?
Исходники править и слать заказчику?
Я считаю, что иметь внешнее управление для таких случаев, будет более подходящим.
При создании новых индексов и новых ошибок соответствующая запись добавляется во внешний файл (можно и спец.таблицу конечно сделать с интерфейсом ведения ее) и в дальнейшем имеем приемлемый отклик от системы.
Т.е. пока не внесли запись в таблицу программа ругается непонятным языком на юзера. Добавили русский текст и обработчик найдя соответствие выдаст удобоваримое предупреждение об ошибке.
Во нагородил.
Еще раз с начала.
Перед сохранением в try-блоке получаем ошибку.
Ищем текст ошибки в нашей внешней/внутренней таблице ошибок.
Не нашли - даем текст об ошибке AS IS. (После можно добавить этот текст в нашу таблицу ошибок)
Нашли - подменили системный текст на наше описание ошибки для юзера.


 
AlexSerp   (2003-04-11 11:52) [16]

2Johnmen ©
Индекс может быть и не по одному полю...

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


 
Johnmen   (2003-04-11 11:58) [17]

>AlexSerp © (11.04.03 11:52)
>разбор системного сообщения с его занесением в таблицу ошибок с
>расшифровкой/переводом на русский может решить эту проблему.

Поясни, я не понял как это решит проблему...


 
AlexSerp   (2003-04-11 12:02) [18]

AlexSerp © (11.04.03 11:49)
Еще раз с начала.
Перед сохранением в try-блоке получаем ошибку.
Ищем текст ошибки в нашей внешней/внутренней таблице ошибок.
Не нашли - даем текст об ошибке AS IS. (После можно добавить этот текст в нашу таблицу ошибок)
Нашли - подменили системный текст на наше описание ошибки для юзера.


 
MsGuns   (2003-04-11 12:05) [19]

>AlexSerp © (11.04.03 11:52)

Я тоже не врубаюсь, как переведенная мессага об ошибке поможет отцу русской демократии ? Ведь проблема в том, что надо КНТЕКСТНО и ПРОГРАММНО реагировать на такие ситуации.


 
AlexSerp   (2003-04-11 13:12) [20]

А я тоже не понимаю.
Тут фиг построишь искусственный интеллект.
А приведенный мною способ доступно укажет пользователю на его ошибки. Не системным языком.
Допутим ввели нового работника с ФИО, днем рождения, полом и реквизитами адреса. А такой уже есть. Ну типа два работника отдела кадров вводят одного и того же. Один до обеда, другой после. Не проверив, что такой уже есть.
Будете программно человеку фамилию/имя/отчество и т.д. менять?
Или даже по одному уникальному полю подставлять свое значение лишь бы в уникальность попасть?
Какая нафиг программная реакция? Пардон.
Эта контекстная выдача сообщения об ошибке и должна помочь юзеру понять что он сделал не так.
Может я действительно чего-то не понимаю?


 
NAlexey   (2003-04-11 13:38) [21]

Информация, которая описывает ошибки, возникающие при работе BDE, может быть получена приложением с помощью обработки исключения EDBENGINEERROR конструкцией try..except.
Когда возникает исключение EDBENGINEERROR, создается объект EDBEngineError и различные поля в этом объекте используются, чтобы программно определить какая именно некорректная ситуация произошла. Также, для данного исключения, может быть сгенерировано больше чем одно сообщение об ошибке. Таким образом необходимо выполнения итераций, чтобы получить всю необходимую информацию.

Поля объекта, которые наиболее интересны в этом контексте:

ErrorCount: type Integer; Определяет количество ошибок, которые
содержит свойство Errors, отсчет начинается с нуля.

Errors: type TDBError; Структура типа Record, которая содержит
информацию о каждой сгенерированной специфической ошибке.
Обращаться к каждой записи через нумерованный индекс.

Errors.ErrorCode: type DBIResult; Определяет код ошибки, которая
содержится в текущей записи.

Errors.Category: type Byte; Категория ошибки.

Errors.SubCode: type Byte; Дополнительный код для значения ErrorCode.

Errors.NativeError: type LongInt; Код удаленной ошибки , возвращается сервером.
Из он равен нулю, ошибка произошла не на сервере; в этом поле появляется
код возврата SQL-выражения.

Errors.Message: type TMessageStr; Если произошла ошибка на сервере, то это строка-сообщение
сервера об ошибке в текущей записи Errors, если нет, то сообщение BDE .



Объект EDBEngineError создается непосредственно в конструкции try..except в секции except. Однажды созданный, объект может передаваться другим процедурам для обработки ошибок.
Пример использования конструкции try..except для обработки исключения DBEngineError:
procedure TForm1.Button1Click(Sender: TObject);
var
i: Integer;
begin
if Edit1.Text > " " then begin
Table1.FieldByName("Number").AsInteger := StrToInt(Edit1.Text);
try
Table1.Post;
except on E: EDBEngineError do
ShowError(E);
end;
end;
end;


В данной процедуре происходит попытка записать значение в поле таблице и при возникновении ошибки BDE, обработка ее перехватывается. Объект типа EDBEngineError передается как параметр процедуре ShowError. Обратите внимание, что в данном примере обрабатывается только ошибка BDE, что на самом деле недостаточно. В реальных условиях необходимо проверять все типы исключительных ситуаций.
Процедура ShowError, в свою очередь, отображает весь список сообщений, которые содержатся в переданной ей переменной:
procedure TForm1.ShowError(AExc: EDBEngineError);
var
i: Integer;
begin
Memo1.Lines.Clear;
Memo1.Lines.Add("Number of errors: " + IntToStr(AExc.ErrorCount));
Memo1.Lines.Add("");
{Iterate through the Errors records}
for i := 0 to AExc.ErrorCount - 1 do begin
Memo1.Lines.Add("Message: " + AExc.Errors[i].Message);
Memo1.Lines.Add(" Category: " +
IntToStr(AExc.Errors[i].Category));
Memo1.Lines.Add(" Error Code: " +
IntToStr(AExc.Errors[i].ErrorCode));
Memo1.Lines.Add(" SubCode: " +
IntToStr(AExc.Errors[i].SubCode));
Memo1.Lines.Add(" Native Error: " +
IntToStr(AExc.Errors[i].NativeError));
Memo1.Lines.Add("");
end;
end;



 
NAlexey   (2003-04-11 13:39) [22]

Источник:
http://www.delphikingdom.ru/treasury/bdetry.htm


 
MsGuns   (2003-04-11 15:16) [23]

>NAlexey © (11.04.03 13:38)

О, боже ! Целый трактат. А ведь в данном случае всего-то и требуется, что ОПРЕДЕЛИТЬ АЛГОРИТМ ОБРАБОТКИ КОНКРЕТНОЙ СИТУАЦИИ, а именно повтора значения в некотором поле таблицы.
На фига, простите дурака, городить здесь огород с подробным анализом ошибки BDE ?



Страницы: 1 вся ветка

Форум: "Базы";
Текущий архив: 2003.05.01;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.52 MB
Время: 0.006 c
3-414
yurikon
2003-04-11 14:00
2003.05.01
Св-во наследника TFrame в Object Inspector`е


14-714
Мазут Береговой Рюрикович
2003-04-13 04:07
2003.05.01
Эй, питерцы! Я же прожил в Питере 4 года.


3-376
dums
2003-04-08 18:13
2003.05.01
выборка из БД в win98 - работает, а в win2k нет...


3-452
alive
2003-04-13 00:02
2003.05.01
Interbase commit


1-559
alexvan
2003-04-18 08:49
2003.05.01
Помогите с типом





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский