Форум: "Базы";
Текущий архив: 2011.11.13;
Скачать: [xml.tar.bz2];
ВнизПочему вставляются пустые поля? Найти похожие ветки
← →
macrodens © (2010-02-01 16:15) [0]Всем доброго времени суток.
Работаю с Firebird 2.0
Через IBExpert создал базу и в ней табличку с полями
ID (integer) - not null autoinc (тригер)
Name (varchar(96) - not null
Pole1 (varchar(96)
если я в IBExpert пытаюсь добавить запись не заполнив поле Name - все ок - срабатывет исключение,
однако при выполнении SQL запроса через компоненты ADO или IBX запись с пустым полем спокойно вставляется, а в IBExpert потом при редактировании этой записи (поле Name не трогаем) исключение уже не возникает.
Подскажите почему все-таки вставляются записи с пустыми полями при not null и как сделать что бы обработка все же происходила?
Пробовал спросить у гугля и яндекса, увидел только вопрос с похожей ситуацией в MySQL.
← →
Diplomat © (2010-02-01 16:41) [1]По видимому в поле Name, должно быть указано значение по умолчанию.
← →
Ega23 © (2010-02-01 16:47) [2]
> однако при выполнении SQL запроса через компоненты ADO или
> IBX запись с пустым полем спокойно вставляется
Код запроса в студию.
← →
12 © (2010-02-01 16:48) [3]Во. Спасибо.
хм..
>> почему все-таки вставляются записи с пустыми полями при not null
прикольно еще тут написано
http://alexey-rouban.livejournal.com/11984.html
дома потестю..
← →
macrodens © (2010-02-01 16:52) [4]И что даст это значение по умолчанию?
Мне нужно что бы при вставке записи осуществлялась проверка поля, что оно не пустое, и желательно что бы проверку осуществлял сервер базы данных.
Единственное пока что я понял, что пустая строка ("") не равна null
← →
Ega23 © (2010-02-01 16:56) [5]
> Единственное пока что я понял, что пустая строка ("") не
> равна null
Именно так. По крайней мере - в FireBird.
← →
Ega23 © (2010-02-01 16:57) [6]
> Мне нужно что бы при вставке записи осуществлялась проверка
> поля, что оно не пустое, и желательно что бы проверку осуществлял
> сервер базы данных.Create table test (fld varchar(32) not null default "");
← →
macrodens © (2010-02-01 16:59) [7]Код запроса в студию.
adoconnection1.BeginTrans;
with ADOQuery1 do
begin
SQL.clear;
SQL.add("INSERT INTO MYTABLE (NAME, POLE1) VALUES (:C1, :C2)");
Parameters.ParamValues["c1;c2;"]:=VarArrayOf(Edit1.test, Edit2.text);
ExecSQL;
end;
adoconnection1.CommitTrans;
запрос проходит и запись вставляется даже при Edit1.text=""
если вместо него указать null, то исключение срабатывает.
← →
macrodens © (2010-02-01 17:06) [8]to Ega23 © (01.02.10 16:57) [6]
проверка все равно не осуществляется
← →
macrodens © (2010-02-01 17:10) [9]поставил default=null и все заработало!!!
← →
macrodens © (2010-02-01 17:32) [10]ан нет не заработало.... :-(
← →
macrodens © (2010-02-01 18:06) [11]пришлось написать тригер по инсерту и апдейту и там проверять...
← →
Виталий Панасенко(дом) (2010-02-01 18:17) [12]строка "" и null - разные вещи..
← →
Виталий Панасенко(дом) (2010-02-01 18:20) [13]при значении edit1.text="" строка и будет вставляться... потому как см.. выше.. перепиши так:
adoconnection1.BeginTrans;
with ADOQuery1 do
begin
SQL.clear;
if edit1.text<>"" then
begin
SQL.add("INSERT INTO MYTABLE (NAME, POLE1) VALUES (:C1, :C2)");
Parameters.ParamValues["c1;c2;"]:=VarArrayOf(Edit1.test, Edit2.text);
end
else
begin
SQL.add("INSERT INTO MYTABLE (POLE1) VALUES (:C1)");
Parameters.ParamValues["c1"]:=VarArrayOf( Edit2.text);
end;
ExecSQL;
end;
adoconnection1.CommitTrans;
будет ругаться, как ты и предположил
← →
Anatoly Podgoretsky © (2010-02-01 19:27) [14]> Ega23 (01.02.2010 16:57:06) [6]
Откуда возьмется пустое поле, раз есть default значение.
← →
macrodens © (2010-02-02 09:24) [15]to Виталий Панасенко(дом) (01.02.10 18:20) [13]
при таком подходе можно в базе вообще не объявлять что поле должно быть не пустым, а выполнять проверки на уровне приложения.
А это будет достаточно грамоздким решением, если в таблице будет 10-15 непустых полей.
Я считаю, что обработка все же должна происходить на уровне сервера (драйвера) БД, а в приложении уже отслеживать исключения, потому как сторонний разработчик приложения под эту БД может и не знать какие поля должны заполняться обязательно - а это может привести к нарушению актуальности данных.
Пока решил вопрос на уровне тригера, который срабатывает на вставку и обновление данных, выглядит так:
if (new.Name="") then new.name=null
может конечно и не самый лучший вариант, но в приложение возвращается исключение с именем поля.
← →
Sergey13 © (2010-02-02 09:29) [16]> [15] macrodens © (02.02.10 09:24)
> при таком подходе можно в базе вообще не объявлять что поле
> должно быть не пустым, а выполнять проверки на уровне приложения.
> Я считаю, что обработка все же должна происходить на уровне
> сервера (драйвера) БД
Одно другому не мешает, а только дополняет. На сервере - последний рубеж обороны, в приложении превентивные меры.
← →
macrodens © (2010-02-02 10:15) [17]На сервере - последний рубеж обороны
если этот "рубеж" работает...
← →
Ega23 © (2010-02-02 10:24) [18]
> может и не знать какие поля должны заполняться обязательно
> - а это может привести к нарушению актуальности данных.
ХП со значениями по-умолчанию.
← →
macrodens © (2010-02-02 10:28) [19]ХП со значениями по-умолчанию.
а если это поле с уникальным значением?
← →
Ega23 © (2010-02-02 10:33) [20]Уникальное значение генерится на клиенте????
Впрочем, извращения всякие бывают.
В этом случае на поле unique index, а по-умолчанию - не знаю, чё там. Чё-нибудь.
Словишь тот же exception.
← →
Медвежонок Пятачок © (2010-02-02 11:39) [21]Откуда возьмется пустое поле, раз есть default значение.
а откуда возьмется дефолт значение, если с клиента идет инсерт в котором есть это поле?
← →
Anatoly Podgoretsky © (2010-02-02 12:18) [22]> Медвежонок Пятачок (02.02.2010 11:39:21) [21]
От туда, не может быть в этом случае пустого поля. Он вставяет не пустое поле.
← →
Медвежонок Пятачок © (2010-02-02 12:48) [23]У него в тексте инсерта поле присутствует.
При этом независимо от того, что именно туда вставляется, дефолт констрэйнт на сервере не сработает.
Он сработал бы и вставил дефолт значение, если бы в инсерте было бы опущено это поле.
то есть скажем всего в таблице есть три поля f1,f2,f3
и для f3 создано дефолт значение.
то при insert into table (f1,f2,f3) values (:f1,:f2,:f3)
дефолтное значение никогда не попадет в таблицу (имеется ввиду что оно механизмами дефолт-констрейнта не попадет туда)
← →
Sergey13 © (2010-02-02 13:36) [24]> [17] macrodens © (02.02.10 10:15)
> если этот "рубеж" работает...
Ну так проверить это можно только запросомselect * from table
where Not_Null_Field is null
← →
macrodens © (2010-02-02 14:24) [25]to Sergey13 © (02.02.10 13:36) [24]
И что это даст?
речь идет о вставке значения.
и если Not_Null_Field в делфе ="" то твой запрос ничего не даст, потому что в firebird"е ""<>null.
один способ я уже нашел и описал его в macrodens © (02.02.10 09:24) [15].
и при его работе приложение ловит exception.
Слава бога с unique index изобретать велосипед не пришлось, работает как надо.
← →
Sergey13 © (2010-02-02 14:36) [26]> [25] macrodens © (02.02.10 14:24)
> И что это даст?
Это даст уверенность в работоспособности "последних рубежей".
Эти "рубежи" и не обещают нормальности данных в этом поле.
А твой велосипед, ИМХО, заключался в Parameters.ParamValues["c1;c2;"]
честно говоря впервые увидел такое.
Если бы присваивалось по одному параметру с проверкой на пустоту едита, то и "проблемы" бы не было.
Непонятно зачем вообще формировать запрос и параметры и дергать сервак, если заранее известно, что запрос не пройдет.
← →
Виталий Панасенко(дом) (2010-02-02 14:44) [27]ты так и не понял, хотя сам в (25) и написал.. строка с нулевой длинной и значение "пусто"(null) - это разные вещи... в Edit1.Text просто НЕТУ ТАКОГО ЗНАЧЕНИЯ, КАК NULL ! там м.б. все, что угодно! строка с нулевой длинной "", в 2 гига.. все, кроме NULL...+, как вариант АДО "помогает". при использовании нативных компонент и DBAware визуальных такой проблемы не возникает.. возможно, проблема во второй части
← →
macrodens © (2010-02-03 09:32) [28]А твой велосипед, ИМХО, заключался в Parameters.ParamValues["c1;c2;"]
да не в этом "велосипед". Оно понятно, что можно проверить все нужные поля вообще еще до формирования запроса.
Можно обращаться к параметрам и через ParamByName - эти два способа формирования запросов описываются во многих книжках. Дело то собственно не в этом.
Суть собственно в том, что бы в базу не заносилось пустое значение, а до момента вставки данных может произойти что угодно -и вот это то собственно и надо отслеживать.
Непонятно зачем вообще формировать запрос и параметры и дергать сервак, если заранее известно, что запрос не пройдет.
Запрос как раз отлично проходит.
ты так и не понял, хотя сам в (25) и написал.. строка с нулевой длинной и значение "пусто"(null)
Да это-то как раз я уже понял и именно за счет этого и сделал проверку в тригере. И тем самым проблема решилась
← →
Ega23 © (2010-02-03 10:30) [29]
> Суть собственно в том, что бы в базу не заносилось пустое
> значение, а до момента вставки данных может произойти что
> угодно -и вот это то собственно и надо отслеживать.
Поставь not null, делов-то.
← →
Sergey13 © (2010-02-03 10:46) [30]> [29] Ega23 © (03.02.10 10:30)
Так он поставил, но от пустой строки, которая <> NULL это не спасает. А спастись хочется.
Но от этого ИМХО программно не спасешься. Юзеры расчухают, что можно поставить например точку в эдит и "ругаться не будет".
Намного дейсвеннее будет писать логин юзера, сделавшего последнее изменение, автоматом в тригере и наказывать периодически "шибко умных".
← →
newbie (2010-02-11 07:20) [31]В файрберде же ХП вроде есть?
Тогда какие проблемы, я не пойму - создается ХП для инсерта, в которой пишутся все необходимые проверки, и ее уже вызывай в клиенте.
P.S. Хотя не вижу смысла в том, чтобы ловить ввод строк вида "". Пускай себе пишут чо хотят, все равно ошибки при вводе будут.
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2011.11.13;
Скачать: [xml.tar.bz2];
Память: 0.54 MB
Время: 0.004 c