Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Delphi Новый топик    Ответить
 FIBPlus blob default значение не NULL  [new]
melbis
Member

Откуда: Харьков
Сообщений: 115
Приветствую!

Подскажите есть домен для FB:

CREATE DOMAIN D_BIGTEXT	AS 	BLOB SUB_TYPE 1 DEFAULT '';


И почему-то FIBPlus Dataset не хочет для него по умолчанию (для других типов данных типов данных все работает) брать дефолтное значение и подставлять его для sql-запросов датасета. Вместо пустого значения которое заданно для умолчания, почему-то подставляется NULL. Причем, даже если я вручную пытаюсь задать FN('CONTENT').AsString:=''; То все равно FIBPlus делает запрос к базе с NULL значением... опция pfImportDefaultValues:=True И собственно для всех других типов дефолтное значение успешно подставляется.
6 мар 19, 21:19    [21826768]     Ответить | Цитировать Сообщить модератору
 Re: FIBPlus blob default значение не NULL  [new]
Док
Member

Откуда: Казань
Сообщений: 6058
melbis,

в ФИБах это отключено?
+
Картинка с другого сайта.

В крайнем случае, создай на сервере триггер
+
CREATE TABLE TEST_BLOB (
    ID                   INTEGER NOT NULL,
    BLOB_TEXT            BLOB SUB_TYPE 1 SEGMENT SIZE 80,
    STR_FLD              VARCHAR(10),
    BLOB_TEXT_WITH_NULL  BLOB SUB_TYPE 1 SEGMENT SIZE 16384
);

/* Trigger: TEST_BLOB_BIU0 */
CREATE OR ALTER TRIGGER TEST_BLOB_BIU0 FOR TEST_BLOB
ACTIVE BEFORE INSERT OR UPDATE POSITION 1
AS
begin
    IF (NEW.BLOB_TEXT IS NULL) THEN
      NEW.BLOB_TEXT = '';

end
^

Картинка с другого сайта.
6 мар 19, 21:56    [21826788]     Ответить | Цитировать Сообщить модератору
 Re: FIBPlus blob default значение не NULL  [new]
melbis
Member

Откуда: Харьков
Сообщений: 115
Док,

спасибо за быстрый ответ!

psSetEmptyStrToNull конечно тоже стоит False; И собственно с типом данных VARCHAR все работает - нет никого NULL при попытки сохранить пустую строку. А вот с BLOB такой фокус не работает! и вот причина здесь именно в обработке BLOB.

Сейчас сделал пробный тип BLOB SUB_TYPE 1 DEFAULT 'TEST' и обнаружил что дефолтное значение все-таки подхватывается!!! и подставляется по умолчанию, НО вот причина в том, что если значение пустая строка, то тогда оно почему-то конвертируется в NULL. И все это именно для BLOB, с VARCHAR такого нету. Проблема не в компоненте редакторе, проверил тоже. Если задавать в ручную FN('FIELD').AsString=''; то опять на выходе ошибка из-за NULL.

P.S. Создавать тригеры очень не хочу, у меня порядка сотни таблиц.
6 мар 19, 22:09    [21826796]     Ответить | Цитировать Сообщить модератору
 Re: FIBPlus blob default значение не NULL  [new]
Док
Member

Откуда: Казань
Сообщений: 6058
melbis
тогда оно почему-то конвертируется в NULL

Результат, часом, не IBE смотришь? Если так, то попробуй затри <null> здесь
+
Картинка с другого сайта.
получишь
+
Картинка с другого сайта.

и ничего менять не придется :)
6 мар 19, 23:47    [21826839]     Ответить | Цитировать Сообщить модератору
 Re: FIBPlus blob default значение не NULL  [new]
Док
Member

Откуда: Казань
Сообщений: 6058
melbis
Если задавать в ручную FN('FIELD').AsString=''; то опять на выходе ошибка из-за NULL.

кстати, а что за ошибка и что за "выход"?
6 мар 19, 23:48    [21826840]     Ответить | Цитировать Сообщить модератору
 Re: FIBPlus blob default значение не NULL  [new]
melbis
Member

Откуда: Харьков
Сообщений: 115
Обычна ошибка Validation, к FB претензий нету, непонятно вот почему FIB+ тулит NULL вместо ""

===== ErrorHandler FIBErrorEvent =====
Sender.ClassName = TFIBQuery
Sender.Name = UpdateQuery
Owner.Name = FDSProvider
ConstraintName = 
ExceptionNumber = -1
Lasterror = keOther
SQLCode = -625
IBErrorCode = 335544347
Message = FProvider.FDSProvider.UpdateQuery:
The insert failed because a column definition includes validation constraints.Validation error for column NOTICE, value "*** null ***".

IBMessage = Validation error for column NOTICE, value "*** null ***".

SQLMessage = The insert failed because a column definition includes validation constraints.
KindIBError = keOther

SQL Query = UPDATE PROVIDER
SET 
    SKEY = :SKEY,
    GROUP_ID = :GROUP_ID,
    NAME = :NAME,
    KIND_KEY = :KIND_KEY,
    STATE_KEY = :STATE_KEY,
    PARAMS = :PARAMS,
    MANAGER = :MANAGER,
    PHONES = :PHONES,
    EMAILS = :EMAILS,
    STORE = :STORE,
    SERV_ADDR = :SERV_ADDR,
    SERV_PHONE = :SERV_PHONE,
    NOTICE = :NOTICE,
    POS = :POS
WHERE
    ID = :OLD_ID
    

SKEY : ""
GROUP_ID : "1"
NAME : "Новый поставщик 1"
KIND_KEY : "kDefault"
STATE_KEY : "kDefault"
PARAMS : ""
MANAGER : ""
PHONES : ""
EMAILS : ""
STORE : ""
SERV_ADDR : ""
SERV_PHONE : ""
NOTICE : NULL
POS : "1"
OLD_ID : "1"
7 мар 19, 01:38    [21826875]     Ответить | Цитировать Сообщить модератору
 Re: FIBPlus blob default значение не NULL  [new]
Док
Member

Откуда: Казань
Сообщений: 6058
melbis,

Тогда уж показывай DDL таблицы, где поле NOTICE. И заодно код на клиенте, каким образом ты в это поле значения суешь.
7 мар 19, 10:43    [21827035]     Ответить | Цитировать Сообщить модератору
 Re: FIBPlus blob default значение не NULL  [new]
Док
Member

Откуда: Казань
Сообщений: 6058
Навскидку, в запросе для NOTICE используй coalesce
7 мар 19, 10:49    [21827045]     Ответить | Цитировать Сообщить модератору
 Re: FIBPlus blob default значение не NULL  [new]
Gator
Member

Откуда: Москва
Сообщений: 14084
По правилам SQL NULL сравнивать нельзя. (иногда это включается настройками set).
Для сравнения используется
 some IS NULL
или соотв. функции
7 мар 19, 11:10    [21827061]     Ответить | Цитировать Сообщить модератору
 Re: FIBPlus blob default значение не NULL  [new]
Док
Member

Откуда: Казань
Сообщений: 6058
Gator
По правилам SQL NULL сравнивать нельзя. (иногда это включается настройками set).

У ТС в DDL домена NOT NULL, похоже, воткнут. Вот и ругается птиц :)

melbis,
+ Ы?
CREATE DOMAIN DMN_BLOBTXT_NOT_NULL AS
BLOB SUB_TYPE 1 SEGMENT SIZE 80 CHARACTER SET UTF8
DEFAULT ''
NOT NULL
COLLATE UTF8;

CREATE TABLE TEST_BLOB (
    ID                   INTEGER NOT NULL,
    BLOB_TEXT            BLOB SUB_TYPE 1 SEGMENT SIZE 80,
    STR_FLD              VARCHAR(10),
    BLOB_TEXT_WITH_NULL  BLOB SUB_TYPE 1 SEGMENT SIZE 16384,
    BLOB_TEXT_WO_NULL    DMN_BLOBTXT_NOT_NULL
);

INSERT INTO TEST_BLOB (ID,
                       BLOB_TEXT,
                       STR_FLD,
                       BLOB_TEXT_WITH_NULL,
                       BLOB_TEXT_WO_NULL)
VALUES (NULL,
        'trtrtrtrtr',
        '123456789',
        NULL,
        COALESCE(:BLOB_TEXT_WO_NULL,''))


Картинка с другого сайта.
7 мар 19, 12:20    [21827174]     Ответить | Цитировать Сообщить модератору
 Re: FIBPlus blob default значение не NULL  [new]
Gator
Member

Откуда: Москва
Сообщений: 14084
Док,

Ну пусть юзает не пустую строку, а пробел или 0х00
7 мар 19, 12:32    [21827188]     Ответить | Цитировать Сообщить модератору
 Re: FIBPlus blob default значение не NULL  [new]
Док
Member

Откуда: Казань
Сообщений: 6058
Gator,

подождем, пока выскажется "начальник транспортного цеха" © :)
7 мар 19, 14:46    [21827373]     Ответить | Цитировать Сообщить модератору
 Re: FIBPlus blob default значение не NULL  [new]
Gator
Member

Откуда: Москва
Сообщений: 14084
Док, завтра ведь пятницаааа
7 мар 19, 14:48    [21827376]     Ответить | Цитировать Сообщить модератору
 Re: FIBPlus blob default значение не NULL  [new]
Arioch
Member

Откуда:
Сообщений: 10598
Gator,

не только
7 мар 19, 15:34    [21827458]     Ответить | Цитировать Сообщить модератору
 Re: FIBPlus blob default значение не NULL  [new]
melbis
Member

Откуда: Харьков
Сообщений: 115
CREATE DOMAIN D_BIGTEXT	AS 	BLOB SUB_TYPE 1 DEFAULT ''	NOT NULL;     

CREATE TABLE provider (
   id 		D_PK,
   skey		D_VC32,
   group_id	D_FK,
   name 	D_VC,
   kind_key	D_VC100,
   state_key	D_VC100,
   params	D_VC,
   manager 	D_VC,
   phones 	D_VC,
   emails	D_VC,
   store 	D_VC,
   serv_addr 	D_VC,
   serv_phone 	D_VC,
   notice 	D_BIGTEXT,
   pos 		D_INT,
   CONSTRAINT PK_provider PRIMARY KEY (id),
   CONSTRAINT FK1_provider FOREIGN KEY (group_id) 
   	REFERENCES provider_group(id) 
   		ON DELETE CASCADE
);


да, есть вариант с coalesce, но это все как и триггера - надо много чего править... Есть ли вариант настроить FIB+ таким образом чтобы он не пытался подставить NULL вместо пустой строки?
10 мар 19, 21:50    [21828799]     Ответить | Цитировать Сообщить модератору
 Re: FIBPlus blob default значение не NULL  [new]
Док
Member

Откуда: Казань
Сообщений: 6058
melbis
Есть ли вариант настроить FIB+ таким образом чтобы он не пытался подставить NULL вместо пустой строки?

кроме той опции, я про другие не знаю. Кстати, как ты узнаёшь, что вместо пустой строки там NULL?
10 мар 19, 23:18    [21828815]     Ответить | Цитировать Сообщить модератору
 Re: FIBPlus blob default значение не NULL  [new]
melbis
Member

Откуда: Харьков
Сообщений: 115
Док,

Через FibErrorHandler. Я привел выше 21826875 отчет по ошибке где четко видно, что для поля BLOB FIBPlus вместо "" подставляет NULL
10 мар 19, 23:46    [21828822]     Ответить | Цитировать Сообщить модератору
 Re: FIBPlus blob default значение не NULL  [new]
Док
Member

Откуда: Казань
Сообщений: 6058
melbis
отчет по ошибке где четко видно, что для поля BLOB FIBPlus вместо "" подставляет NULL

имхо, у тебя два выхода: либо править исходники ФИБов (т.е. включить поведение psSetEmptyStrToNull и для текстовых блобов), либо править ручками исходники своего приложения (или ковыряться в базе).

Боюсь, тут "понадобится программист" © :)
11 мар 19, 10:41    [21828937]     Ответить | Цитировать Сообщить модератору
 Re: FIBPlus blob default значение не NULL  [new]
melbis
Member

Откуда: Харьков
Сообщений: 115
Док,

так и есть! И чтобы не изобретать велосипед, может у кого-то уже есть исправленный блок ФИБов для работы с BLOB NULL?
11 мар 19, 11:30    [21828972]     Ответить | Цитировать Сообщить модератору
 Re: FIBPlus blob default значение не NULL  [new]
Разрабоччик
Member

Откуда:
Сообщений: 21
melbis
CREATE DOMAIN D_BIGTEXT	AS 	BLOB SUB_TYPE 1 DEFAULT '';


И почему-то FIBPlus Dataset не хочет для него по умолчанию (для других типов данных типов данных все работает) брать дефолтное значение и подставлять его для sql-запросов датасета. Вместо пустого значения которое заданно для умолчания, почему-то подставляется NULL. Причем, даже если я вручную пытаюсь задать FN('CONTENT').AsString:=''; То все равно FIBPlus делает запрос к базе с NULL значением... опция pfImportDefaultValues:=True И собственно для всех других типов дефолтное значение успешно подставляется.


Тут дело не в Fib+. Тут дело в Delphi, скорее. Дело в том, что данные для blob-поля пишутся в буфер
Код
датасет.FBN('блоб').Value := ''

в итоге вызовет метод TBlobField.SetAsString('') модуля db.pas:

procedure TBlobField.SetAsString(const Value: string);
begin
  with DataSet.CreateBlobStream(Self, bmWrite) do
    try
      WriteBuffer(Pointer(Value)^, Length(Value));
    finally
      Free;
    end;
end;

При Value равном "Пустая строка" операция WriteBuffer(Pointer(Value)^, Length(Value)) в реальности не сделает никаких изменений.
Автоматиче кое назначение Default value для поля вызовет то же действие.
В итоге на сервер в качестве значения уедет Null.
---
Вместо TpFIBDataSet используй TpFIBQuery. :)
11 мар 19, 13:12    [21829079]     Ответить | Цитировать Сообщить модератору
 Re: FIBPlus blob default значение не NULL  [new]
melbis
Member

Откуда: Харьков
Сообщений: 115
Разрабоччик,

Спасибо! Да есть такой вариант, я нашел в FIBDataset обертку для работы с мемо

procedure TFIBMemoField.SetAsString(const Value: string); 
begin
 with  TFIBDataSet(DataSet).Database do
  if NeedUTFEncodeDDL
   and IsUnicodeConnect or (FCharSetID in UnicodeCharSets) then
    inherited SetAsString(UTF8Encode(Value))
   else
   inherited SetAsString(Value)
end;


как вариант можно исправить на
    if Length(Value) > 0 then
       inherited SetAsString(Value)
       else
       inherited SetAsString(' ');


ну или в db.pas там где Вы указали. Но мне не очень нравится этот вариант, все-таки FIB+ общается с СУБД с помощью SQL-запросов как я понимаю? Как отправляется непосредственно блоб в БД? Если с помощью SQL, то правильнее найти тот код в котором формируется этот SQL (точнее подставляются значения в SQL-запрос вместо :FIELD) и там скорее всего происходит анализ, если значение нулевой длины, то подставляется константа NULL, которую и заменить собственно на пустую строку. Но вот не могу найти только где это происходит...
11 мар 19, 13:35    [21829118]     Ответить | Цитировать Сообщить модератору
 Re: FIBPlus blob default значение не NULL  [new]
Разрабоччик
Member

Откуда:
Сообщений: 21
melbis,
для редактирования блоб - полей никогда не использовал датесет, только TpFIBQuery, и проблем не было.

Может, действительно добавишь триггер OnBeforeInsert/OnBeforeUpdate?
if new.txt is null  
  new.txt = '';

И заодно not null к ddl домена. Чтобы ошибочно не навтыкать лишнего.
Все же, контроль на сервере надежнее. И никакой головной боли на клиенте, в данном случае - с fib+.
11 мар 19, 14:37    [21829217]     Ответить | Цитировать Сообщить модератору
 Re: FIBPlus blob default значение не NULL  [new]
Разрабоччик
Member

Откуда:
Сообщений: 21
melbis
P.S. Создавать тригеры очень не хочу, у меня порядка сотни таблиц.

Сие легко автоматизировать. Например, в генераторе скрипта дизайнера IbExpert. Для каждой таблички, в составе полей которой есть соотв. домен, и т.д. - создать триггер.
11 мар 19, 14:42    [21829223]     Ответить | Цитировать Сообщить модератору
Все форумы / Delphi Ответить