Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

проверка вводимого значения


Страницы:   1 2 3 4

kxft78 ©   (2011-02-03 12:46:00) 

Господа подскажите, дело не хитрое но "прогуглив" пол дня так ничего и не нашел дельного.
Ситуация:
При выполнении sql скрипта (insert строки), необходимо сделать проверку на наличие содержимого поля в справочной таблице и если его там нет то обругать юзера.
сделал просто - select field from spr_table where field='edit.text'
затем
perem1:= AOQuery.FieldValues['field'];
если в запросе пусто то я соответственно получаю ошибку о невозможности присвоения  строковой переменной значения null.
И все хорошо если не одно но... необходимо обругать юзера по русски и указать где он напортачил.
Пытался через try ...except наткнулся на грабли что после обработки исключения он благополучно выполняет дальнейший код, а мне это не надо!


Ega23   (2011-02-03 17:01:00) [21]


> тут нет полиморфизма

Дык вот и я о том же. Либо строго ставить пустые заглушки на все абстрактные методы и жить по правилу "0 Errors, 0 Warnings, 0 Hints".
Либо на свой страх и риск создавать абстрактный класс, у которого перекыто 5 из 5000 абстрактных методов и быть твёрдо уверенным, что твой код никогда не вызовет ни одного абстрактного метода (кроме перекрытых).


Игорь Шевченко   (2011-02-03 16:51:00) [22]


> Где тут полиморфизм?


тут нет полиморфизма


Ega23   (2011-02-03 16:39:00) [23]


> Если ты против самого создания класса с абстрактными методами


Да я не то чтобы против. Просто непонятно было, зачем. Для чего идёт warning про компиляции, а не ошибка.
Вот Макс тогда хороший пример привёл, с "биологическим деревом классов". Наглядно, так сказать, демонстрировалось, в чём удобство.


Anatoly Podgoretsky   (2011-02-03 16:36:00) [24]

> Ega23  (03.02.2011 16:05:45)  [45]

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

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


Ega23   (2011-02-03 16:32:00) [25]


> для полиморфизма ?

А какой тут полиморфизм? Ну вот я написал:
var
 strings: TStrings;
begin
 strings := TStrings.Create;


Где тут полиморфизм?
Я могу понять, когда strings := TStringList.Create;
Я могу понять, когда коллекция TMyObjectClass = class of TMyObjectи явно класс задавать при создании.


Игорь Шевченко   (2011-02-03 16:22:00) [26]


> Смысл в другом: зачем тогда вообще позволять создавать абстрактный
> класс?


для полиморфизма ?


Ega23   (2011-02-03 16:05:00) [27]


> чтобы получить Abstract Error при выполнении и Warning при
> компиляции


Не, это понятно.
Я может несколько сумбурно выразился.
Смысл в другом: зачем тогда вообще позволять создавать абстрактный класс?
Макс хороший пример привёл, чуть ли не от самого Борланда (источник не помню). Где как раз показано, довольно наглядно, для чего эта лазейка оставлена.

Собственно, это я к высказыванию
> его перекрытие в наследнике обязательно.
Может и не обязательно. Надо очень внимательно код ковырять, в том же ADODB например.


Anatoly Podgoretsky   (2011-02-03 16:01:00) [28]

> Ega23  (03.02.2011 15:53:42)  [42]

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


Игорь Шевченко   (2011-02-03 15:55:00) [29]


>  Почему нельзя обойтись просто виртуальным методом?


чтобы получить Abstract Error при выполнении и Warning при компиляции


Ega23   (2011-02-03 15:53:00) [30]


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


Вот тут недавно (месяца 2 назад) с Максом заспорил. По-поводу нужности абстрактных методов в Delphi.
Delphi допускает создание абстрактных классов (TStrings, например). Вот, собственно, вопрос: если допускается создание, то для чего нужна директива abstract? Почему нельзя обойтись просто виртуальным методом?
Взять тот же TDataLink c его ActiveChanged, RecordChangd, UpdateData.
Собственно, вполне возможно, что какая-то Высшая Цель преследовалась.
В самом DB.pas RecordCount только в одном месте используется.


Игорь Шевченко   (2011-02-03 15:51:00) [31]


> СУБД oracle10g xe, наплевать можно но не хочется :) хочется
> по уму и красиво.


а теперь задачу с начала.


Anatoly Podgoretsky   (2011-02-03 15:38:00) [32]

> Ega23  (03.02.2011 14:51:33)  [33]

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


kxft78   (2011-02-03 15:12:00) [33]

Пардон ошибся, before insert конечно.
Есть гуру оракла? :)


Ega23   (2011-02-03 15:09:00) [34]


> триггер before update?

Скорее, before insert


> Накидаете грамотный и красивый пример на plsql + отлов в
> дельфях


Не силён в Оракле. Может там есть какое-нибудь изящное решение.
Для MSSQL я бы хранимку написал.


Ega23   (2011-02-03 15:07:00) [35]


> И, похоже, именно для того, чтобы его не тронули не умеющие
> определять число строк потомки.


Да, но при этом в том же DB.pas:
procedure TDataLink.UpdateRange;
var
 Min, Max: Integer;
begin
 Min := DataSet. FActiveRecord - FBufferCount + 1;
 if Min < 0 then Min := 0;
 Max := DataSet. FRecordCount - FBufferCount;
 ...


В общем, я бы не рекомендовал DB.pas как образцово-показательный код.  :)


kxft78   (2011-02-03 15:04:00) [36]

Выходил не надолго
> Это всё зависит от ТЗ. Если мала - ну значит мала. Если
> можно наплевать - ну и хорошо. В изначальном вопросе ТЗ
> не было озвучено.Вариантов решений - море (зависит от используемой
> СУБД).Триггер, хранимая процедура, блокировка таблицы.

СУБД oracle10g xe, наплевать можно но не хочется :) хочется по уму и красиво.
надо проверить вводимое значение на совпадением со значением в некой таблице, если его там нет то обматерить и не дать сделать insert.
Вероятно правильней всего в такой ситуации будет использовать триггер before update?
Накидаете грамотный и красивый пример на plsql + отлов в дельфях - будет ОГРОМНОЕ ВАМ СПАСИБО :)


И. Павел   (2011-02-03 15:01:00) [37]

> TDataSet = class(TComponent, IProviderSupport)
> private
>   FFields: TFields;
>   .....
>   FRecordCount: Integer;


Он приватный :) И, похоже, именно для того, чтобы его не тронули не умеющие определять число строк потомки.
Похоже, что вы правы. Не удивительно, что в справке про IsEmpty нет такого же предостережения, как про RecordCount. Борландовцы как то умудрились реализовать IsEmpty на самом низком уровне!


Ega23   (2011-02-03 15:00:00) [38]


> Выходит, что FRecordCount знает, сколько записей, а потомок,
>  пеализовавший GetRecordCount - нет. Тогда зачем они его
> переопределили?...


А это потому, что вот так вот DB.pas написан.
FRecordCount - исключительно внутренний счётчик базового TDataSet.

Есть и ещё перлы. Например - DataSet.DisableControls/DataSet.EnableControls
Всё честно, по DisableControls события не передаются всем TDataSource, которые подключены к НД. А вот по EnableControls - идёт DataChanged.
Но нет никакой гарантии, что за это время НД могли изменить. Добавить туда записей, модифицировать, что-то удалить. Переоткрыть, в конце-концов.
Для DBEdit - не беда, берём активную запись и отображаем.
Для DBGrid - отображаем ровно то, что есть на экране, на остальное наплевать.
А вот для TDBTree - уже ой. Тебе всю иерархию знать надо, мало ли, ты ветки местами поменял. И считай приходится заново перестраивать.
ИМХО, уже только этой причины было достаточно для отсутствия "стандартного" TDBTreeView.


Ega23   (2011-02-03 14:51:00) [39]


> либо FRecordCount не быть равным RecordCount.


Вот. Наконец-то.
Смотрим внимательно:


 TDataSet = class(TComponent, IProviderSupport)
 private
   FFields: TFields;
   .....
   FRecordCount: Integer;


т.е. - приватное поле.

 TDataSet = class(TComponent, IProviderSupport)
 public
   ......
   property RecordCount: Integer read GetRecordCount;

Публичное read-only свойство с геттером.


 TDataSet = class(TComponent, IProviderSupport)
 protected
   ......
   function GetRecordCount: Integer; virtual;

протектед-геттер.

ну и наконец:
function TDataSet.GetRecordCount: Longint;
begin
 Result := -1;
end;


И функции IsEmpty глубоко начхать, каким макаром в ADODB перекрыт GetRecordCount и какое значение он вернул.


И. Павел   (2011-02-03 14:48:00) [40]

> с виртуальным геттером

Выходит, что FRecordCount знает, сколько записей, а потомок, пеализовавший GetRecordCount - нет. Тогда зачем они его переопределили?...


Страницы:   1 2 3 4

Наверх

Титульная страница Поиск, карта сайта Написать письмо