Проблема с обработкой BLOB-параметра в ХП

Запросы, планы, оптимизация запросов, ...

Модераторы: kdv, CyberMax

Ответить
golkanavt
Сообщения: 82
Зарегистрирован: 10 янв 2006, 13:57

Проблема с обработкой BLOB-параметра в ХП

Сообщение golkanavt » 28 сен 2007, 15:48

Перегоняю базу из под MS SQL под Firebird. Среди кучи таблиц и процедур есть такая (привожу часть, где и возникает проблема):

Код: Выделить всё

CREATE PROCEDURE ML_ADD_PROPERTY (
    comp_name varchar(64),
    prop_set_name varchar(64),
    prop_name varchar(64),
    prop_value blob sub_type 1 segment size 80)
as
declare variable p_name varchar(128);
begin
  if (prop_value is null) then
    begin
      delete from ml_property
      where component_name  = :comp_name
      and property_set_name = :prop_set_name
      and property_name     = :prop_name;
    end
  else
<..>
При трассировке (значение параметра prop_value = yes) на самой первой строке выдает ошибку:

Код: Выделить всё

Column does not belong to referenced table.
Dynamic SQL Error.
SQL error code = -206.
Column unknown.
YES.
At line 1, column 29.
Пытался объехать проверку на Null с помощью определения размера блоба - те же яйца, вид с боку:

Код: Выделить всё

CREATE PROCEDURE ML_ADD_PROPERTY (
    comp_name varchar(64),
    prop_set_name varchar(64),
    prop_name varchar(64),
    "prop_value" blob sub_type 1 segment size 80)
as
declare variable p_name varchar(128);
declare variable i integer;
begin
  i = b_total_length("prop_value");
  if (i = 0) then
    begin
      delete from ml_property
      where component_name  = :comp_name
      and property_set_name = :prop_set_name
      and property_name     = :prop_name;
    end
  else
<..>
Где собака порылась, что я упустил/недопонял? В других базах с BLOB-полями все нормально работает (логика другая, обновления - чтения)

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 28 сен 2007, 15:59

Вы лучше вообще двойные кавычки не используйте.
http://www.ibase.ru/ibfaq.htm#dtproblem

потом, ошибка не соответствует тексту процедуры. она сообщает, что нет столбца yes, а я такой переменной или столбца не вижу.

кроме того, блобы таким образом, как во втором примере, использовать не получится, imho.

golkanavt
Сообщения: 82
Зарегистрирован: 10 янв 2006, 13:57

Сообщение golkanavt » 28 сен 2007, 16:43

К сожалению, в этой базе уйти от кавычек не получится - приложение на нее ориентированное использует кучу служебных слов, таких как table, type, event и т.п.
Что касается несоответствия ошибки тексту - я и сам это понимаю, поэтому и вынес сюда вопрос на обсуждение, меня эта ошибка ставит в тупик. Столбца "YES" в базе вообще нет, это просто значение параметра. При другом значении параметра получаем другое сообщение:

Код: Выделить всё

Column does not belong to referenced table.
Dynamic SQL Error.
SQL error code = -206.
Column unknown.
IBASE.RU.
At line 1, column 35.

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Re: Проблема с обработкой BLOB-параметра в ХП

Сообщение WildSery » 28 сен 2007, 16:55

golkanavt писал(а):При трассировке (значение параметра prop_value = yes) на самой первой строке выдает ошибку:
Трассировка чем выполняется? Правильно, IBExpert.
Параметр как задаёшь? Правильно, в диалоге.
Так какого ... без кавычек строку туда пихаешь? На закладку "Last Statement" заглядывал?
Напиши 'YES' в это поле и не приставай сюда больше с особенностями IBExpert, у него свой форум есть.

golkanavt
Сообщения: 82
Зарегистрирован: 10 янв 2006, 13:57

Сообщение golkanavt » 28 сен 2007, 17:10

Указание 'YES' в диалоге на выходе дает следующее:

Код: Выделить всё

Error Message:
----------------------------------------
Unsuccessful execution caused by system error that does not preclude successful execution of subsequent statements.
feature is not supported.
BLOB and array data types are not supported for conversion operation.

[00542E1B]
[0053A67B]
[00BD7B42]
[00BD9370]
Last statement имеем такой:

Код: Выделить всё

Statement:
-----------------------------------------------------
SELECT cast(b_total_length( 'YES' ) as integer) FROM RDB$DATABASE
Был не в курсе, что это проблема IBExpert'a, ранее с подобным косяком не сталкивался, так что прошу боевым канделябром не размахивать.

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 28 сен 2007, 17:37

golkanavt писал(а):Указание 'YES' в диалоге на выходе дает следующее:
И чё? Ничего тебе это не говорит? Какой ещё b_total_length от строки?
Вертай на IS NULL.

golkanavt
Сообщения: 82
Зарегистрирован: 10 янв 2006, 13:57

Сообщение golkanavt » 28 сен 2007, 17:44

Спасибо, заработало

golkanavt
Сообщения: 82
Зарегистрирован: 10 янв 2006, 13:57

Сообщение golkanavt » 28 сен 2007, 17:52

А почему не удается выполнить без ошибки
execute procedure ml_add_property ('SIS', 'DeviceTracker(Default-DeviceTracker)', 'udp_gateway', 'Default-UDP') - по той же причине, проблема в IBExpert или я что то не так делаю?
Если напрямую запускать процедуру на выполнение с такими же параметрами - выполняется.

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 28 сен 2007, 18:17

golkanavt писал(а):А почему не удается выполнить без ошибки
Не вижу.

golkanavt
Сообщения: 82
Зарегистрирован: 10 янв 2006, 13:57

Сообщение golkanavt » 28 сен 2007, 18:23

Sorry.

Код: Выделить всё

Unsuccessful execution caused by a system error that precludes
successful execution of subsequent statements.
internal error.

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 28 сен 2007, 18:56

процедуру в IBE выполняете в SQL Editor? если нет, то в сад :)

golkanavt
Сообщения: 82
Зарегистрирован: 10 янв 2006, 13:57

Сообщение golkanavt » 28 сен 2007, 19:33

процедуру в IBE выполняете в SQL Editor?
да, конечно

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 28 сен 2007, 21:02

Полностью пример повторимый нужон.

golkanavt
Сообщения: 82
Зарегистрирован: 10 янв 2006, 13:57

Сообщение golkanavt » 29 сен 2007, 11:47

Скрипт процедуры:

Код: Выделить всё

SET TERM ^ ;

CREATE PROCEDURE ML_ADD_PROPERTY (
    comp_name varchar(64),
    prop_set_name varchar(64),
    prop_name varchar(64),
    prop_value blob sub_type 1 segment size 80)
as
declare variable p_name varchar(128);
begin
  if (prop_value is null) then
    begin
      delete from ml_property
      where component_name  = :comp_name
      and property_set_name = :prop_set_name
      and property_name     = :prop_name;
    end
  else
    begin
      select property_name
      from ml_property
      where component_name  = :comp_name
      and property_set_name = :prop_set_name
      and property_name    = :prop_name
      into :p_name;

      if (p_name is null) then
        begin
          insert into ml_property (component_name, property_set_name, property_name, property_value)
          values (:comp_name, :prop_set_name, :prop_name, :prop_value);
        end
      else
        begin
          update ml_property
          set property_value = :prop_value
          where component_name  = :comp_name
          and property_set_name = :prop_set_name
          and property_name    = :prop_name;
        end
    end
end^

SET TERM ; ^

GRANT SELECT,INSERT,DELETE,UPDATE ON ML_PROPERTY TO PROCEDURE ML_ADD_PROPERTY;

GRANT EXECUTE ON PROCEDURE ML_ADD_PROPERTY TO SYBASE;
и фигурирующей в ХП таблицы:

Код: Выделить всё

/******************************************************************************/
/***                Generated by IBExpert 29.09.07 14:45:49                 ***/
/******************************************************************************/

SET SQL DIALECT 3;

SET NAMES WIN1251;



/******************************************************************************/
/***                                 Tables                                 ***/
/******************************************************************************/



CREATE TABLE ML_PROPERTY (
    COMPONENT_NAME     VCHAR128 NOT NULL /* VCHAR128 = VARCHAR(128) */,
    PROPERTY_SET_NAME  VCHAR128 NOT NULL /* VCHAR128 = VARCHAR(128) */,
    PROPERTY_NAME      VCHAR128 NOT NULL /* VCHAR128 = VARCHAR(128) */,
    PROPERTY_VALUE     DTBLOB NOT NULL /* DTBLOB = BLOB SUB_TYPE 1 SEGMENT SIZE 80 */
);




/******************************************************************************/
/***                              Primary Keys                              ***/
/******************************************************************************/

ALTER TABLE ML_PROPERTY ADD CONSTRAINT PK_ML_PROPERTY PRIMARY KEY (COMPONENT_NAME);


/******************************************************************************/
/***                               Privileges                               ***/
/******************************************************************************/


/* Privileges of users */
GRANT ALL ON ML_PROPERTY TO SYBASE WITH GRANT OPTION;
Об индексах - даже без COLLATE не удается создать комплексный ключ по двумя полям VARCHAR(128), максимум одно влазит в первичный ключ

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 29 сен 2007, 13:29

Об индексах - даже без COLLATE не удается создать комплексный ключ по двумя полям VARCHAR(128), максимум одно влазит в первичный ключ
и правильно. 128+128 = 256. а даже для одного столбца максимум индексируемого это 254. с учетом оверхеда при двух столбцах будет еще меньше.

p.s. в FB 2 в новой ods макс размер ключа = page_size/4.

golkanavt
Сообщения: 82
Зарегистрирован: 10 янв 2006, 13:57

Сообщение golkanavt » 29 сен 2007, 13:54

и правильно. 128+128 = 256. а даже для одного столбца максимум индексируемого это 254. с учетом оверхеда при двух столбцах будет еще меньше.

p.s. в FB 2 в новой ods макс размер ключа = page_size/4.
Понятно. Раз такое дело, где можно почитать о переходе с полторашки на двойку? В какой она сейчас стадии разработки - почти год не следил за темой - релиз иль бета?

golkanavt
Сообщения: 82
Зарегистрирован: 10 янв 2006, 13:57

Сообщение golkanavt » 29 сен 2007, 14:46

Последний вопрос снимается, нашел информацию об
28.08.2007. Вышло обновление Firebird - 2.02 (билд 12964)

Ответить