Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2011.11.13;
Скачать: CL | DM;

Вниз

Почему вставляются пустые поля?   Найти похожие ветки 

 
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;
Скачать: CL | DM;

Наверх




Память: 0.55 MB
Время: 0.009 c
2-1311147342
xtd
2011-07-20 11:35
2011.11.13
Ускорить отсчет времени указанному приложению


2-1311149076
Scott Storch
2011-07-20 12:04
2011.11.13
ошибка при работе с параметрами запроса


2-1311252544
petka
2011-07-21 16:49
2011.11.13
Инициализация записей в массиве


15-1310773444
Kerk
2011-07-16 03:44
2011.11.13
Google Docs Viewer Supports ZIP and RAR Archives


2-1311246212
arturich
2011-07-21 15:03
2011.11.13
Вопрос по DevExpress