Обновление Firebird BLOB поля с добавлением текста - PullRequest
0 голосов
/ 07 марта 2019

Проблема

Невозможно добавить текст в поле большого двоичного объекта, если это значение равно NULL , с использованием простого concat ( || ).

База документов: https://firebirdsql.org/refdocs/langrefupd21-blob.html

Тест Env

enter image description here

Предполагаемые типы:

  • fieldTarget ~ BLOB
  • tablePk ~ VARCHAR (5)

Как это:

UPDATE tablename
SET fieldTarget = fieldTarget || :string
WHERE tablePk = :pkTarget;

После выполнения не возвращается ни одна ошибка, но поле все еще null

Ответы [ 2 ]

0 голосов
/ 08 марта 2019

Основная проблема, с которой вы столкнулись, заключается в том, что исходное значение равно NULL.Такие операции, как сложение, объединение и т. Д. Со значением NULL, приведут к NULL.Чтобы глубже погрузиться в детали NULL, прочитайте Руководство по пустым файлам Firebird .

. Решение состоит в том, чтобы использовать COALESCE для предоставления значения по умолчанию (например, пустой строки), когдастолбец равен нулю *.

UPDATE tablename
SET fieldTarget = COALESCE(fieldTarget, '') || :string
WHERE tablePk = :pkTarget;

*: это уже было в вашем удаленном ответе, но это было немного затенено приведением к varchar, которое не должно быть необходимым

0 голосов
/ 07 марта 2019

Все строковые операции (например, || -связь) связаны максимальным пределом размера VarChar (который составляет 32 КБ, что составляет менее 8200 букв в кодированном тексте UTF-8).

Однако, похоже, есть BLOB -ориентированные функции. Также не нужно экранировать NULL -значения с COALESCE.

LIST возвращает строку, состоящую из ненулевых значений аргумента в группе, разделенных запятой или предоставленным пользователем разделителем

https://firebirdsql.org/refdocs/langrefupd21-aggrfunc-list.html

Следовательно, используя derived tables:

Select LIST(ALL X, '') From
 ( Select fieldTarget as x From tablename Where tablePk = :pkTarget
      UNION ALL
   Select Cast( :string AS VarChar(8191) ) From RDB$DATABASE ) 
As TMP

Введением типов является присвоение типа данных выражению только для параметров.

P.S. в документации также утверждается, что

Порядок значений в списке не определен.

P.P.S. Готов к запуску пример, протестирован на FB 2.1.7

Select LIST(ALL X, '') From
 ( Select Cast( :str_pre AS VarChar(8191) ) as X From RDB$DATABASE
      UNION ALL
   Select /* DATA column */ RDB$TRIGGER_SOURCE
          From /* DATA table */ RDB$TRIGGERS
          Where /* PK ID */ RDB$TRIGGER_NAME  = :pkTarget
      UNION ALL
   Select Cast( :str_post AS VarChar(8191) ) From RDB$DATABASE
)

Передача имен, таких как RDB$TRIGGER_1, даст вам system trigger, у которого нет исходного текста, поэтому в поле есть значение NULL. Легко проверить, что вам не нужно COALESCE - здесь: -D

...