powered by simpleCommunicator - 2.0.59     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Восстановление БД из резервной копии приводит к проблемам с процедурами (IB XE7)
10 сообщений из 10, страница 1 из 1
Восстановление БД из резервной копии приводит к проблемам с процедурами (IB XE7)
    #38933575
Калям
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Имеется БД, изначально созданная в IB XE3 Update 4, которая прекрасно неоднократно восстанавливалась из копий без каких-либо неожиданностей.

После перехода на IB XE7 Update 1 перестали проходить некоторые тесты хранимых процедур, которые до этого, разумеется, не падали. Вся соль в том, что это происходит только на базе, восстановленной из резервной копии, другими словами есть два сценария:

1 - с падением тестов.
Берётся БД с XE3-сервера, с помощью XE7 создаётся её копия.

База тут же восстанавливается из только что созданной копии.

Запускаются тесты - некоторые не проходят.

2 - без падения тестов.

Берётся БД с XE3-сервера, в IBExpert создаётся SQL-скрипт на получение её полного дубликата (благо данных в ней мало).

Скрипт отрабатывает на сервере XE7 - получаем новую БД.

Запускаются тесты - все проходят.

Выполняем создание резервной копии этой новой базы и тут же восстанавливаем из неё.

Запускаются тесты - некоторые не проходят (ровно те же, что и в первом сценарии).

Попытки перекомпиляции всех процедур (с отключением пользователей, чтобы кеш метаданных стал актуальным) и обновления индексов ничего не дают. Хотя, один раз удалось каким-то образом восстановить работу тестов, но последовательность действий забылась, т. к. перебиралось всё, что приходило в голову (например, никак не влияющие на логику процедуры правки - добавление лишнего пробела в комментарии, удаление тела и возврат кода обратно...).

Буду рад любым советам по поиску причины такого поведения.
...
Рейтинг: 0 / 0
Восстановление БД из резервной копии приводит к проблемам с процедурами (IB XE7)
    #38933625
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Калям,

я думаю что скрипт сюда вряд ли будет уместным. можете к нам в саппорт, или прямо мне на email - что за тесты, что значит "не проходят".
...
Рейтинг: 0 / 0
Восстановление БД из резервной копии приводит к проблемам с процедурами (IB XE7)
    #38934325
Калям
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Выяснилось, что описанная проблема возникает только на последней версии ODS - 16; если в ibconfig уменьшить её до 15 (это версия сервера XE3), то всё работает как надо.

Всё больше склоняюсь в сторону ошибки в самом Interbase, либо в gbak.
...
Рейтинг: 0 / 0
Восстановление БД из резервной копии приводит к проблемам с процедурами (IB XE7)
    #38934333
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Калям,

жду деталей на kdv@ibase.ru.
...
Рейтинг: 0 / 0
Восстановление БД из резервной копии приводит к проблемам с процедурами (IB XE7)
    #38949937
Калям
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Удалось обнаружить причину ошибки - в блоке for в выборке использовалась та же таблица (TABLE_1), что и в блоке do, где она обновлялась:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
FOR
  SELECT
    REC_ID, /* Первичный ключ. */
    ...
  FROM
    TABLE_1
    ...
  WHERE
    ...
  INTO
    REC_ID,
    ...
DO
BEGIN
  UPDATE TABLE_1
  SET ...
  WHERE REC_ID = :REC_ID;
 
  ...
END


Чтобы избежать побочных эффектов такого использования for-блока, приводивших к проблеме, я предварительно сохранил данные в буферную временную таблицу TMP_TABLE:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
INSERT INTO TMP_TABLE
  SELECT
    REC_ID,
    ...
  FROM
    TABLE_1
    ...
  WHERE
    ...;
 
FOR
  SELECT
    REC_ID,
    ...
  FROM
    TMP_TABLE
  INTO
    REC_ID,
    ...
DO
BEGIN
  UPDATE TABLE_1
  SET ...
  WHERE REC_ID = :REC_ID;
 
  ...
END


В результате такой код корректно работает на обеих версиях ODS (15 и 16). Теперь у меня возникли сомнения, а является ли первоначальная проблема ошибкой IB - ведь если недопустимо применять одну и ту же таблицу в for, где её данные меняются (хотя в документации и на ibase.ru я подобных ограничений не нашёл), то вина только моя.

Есть ещё момент. Удивительно, но именно в документации Firebird почему-то нашлась недокументированная возможность IB, которая в моём случае теоретически может помочь обойтись без временной таблицы - http://www.firebirdsql.org/refdocs/langrefupd21-psql-forselect.html#langrefupd21-psql-forselect-ascursor (раздел "AS CURSOR clause"). Но мне не удалось скомпилировать код примера, адаптированный к моему случаю, ошибка такая:

Код: plaintext
1.
2.
3.
Unknown cursor.
Dynamic SQL Error.
SQL error code = -504.
Cursor unknown.

Есть люди, которым что-то известно об этой возможности?
...
Рейтинг: 0 / 0
Восстановление БД из резервной копии приводит к проблемам с процедурами (IB XE7)
    #38949946
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Калям,

есть несколько моментов
1. для того, чтобы получить корректные обновления в for этой же таблицы, нужно сделать курсор стабильным. А делается он только через plan sort.
и есть другие варианты, которые описаны тут
http://www.ibase.ru/devinfo/updsame.htm

2. функциональность as cursor, насколько я помню, в IB не была доделана и поэтому не документирована.
В Langref Update по Firebird добавлено то, чего не было в InterBase 6.0. В документации по InterBase as cursor не фигурирует вообще, это значит что он не поддерживается.

p.s. описанный вами баг (про ODS 16) так и не смог отрапортовать, не было времени, приношу извинения. Попытаюсь после майских.
...
Рейтинг: 0 / 0
Восстановление БД из резервной копии приводит к проблемам с процедурами (IB XE7)
    #38949947
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
КалямТеперь у меня возникли сомнения, а является ли первоначальная проблема ошибкой IB - ведь если недопустимо применять одну и ту же таблицу в for, где её данные меняются (хотя в документации и на ibase.ru я подобных ограничений не нашёл), то вина только моя.

Является. Вообще говоря любые модификации той же таблицы которая используется в курсоре является причиной так называемой ошибки нестабильного курсора. Когда данные изменённые в курсоре были видны в самом этом курсоре. Эта ошибка исправлена только в Firebird 3. Если в IB тупо запретили компилировать такие процедуры, то это весьма странное решение, точнее не решение, а просто уход от проблемы.

КалямUnknown cursor.
Dynamic SQL Error.
SQL error code = -504.
Cursor unknown.

Приведи текст этой процедуры
...
Рейтинг: 0 / 0
Восстановление БД из резервной копии приводит к проблемам с процедурами (IB XE7)
    #38949979
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Калямв документации Firebird почему-то нашлась недокументированная возможность IB,
которая в моём случае теоретически может помочь обойтись без временной таблицы
Не может. Если у тебя в SELECT план ORDER, а ты изменяешь поля так, что запись
"перемещается" по индексу вперёд и таким способом встречается дважды, то тебе update по
rdb$db_key (что и делается с помощью курсора) не поможет.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Восстановление БД из резервной копии приводит к проблемам с процедурами (IB XE7)
    #38949998
Калям
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов ДенисПриведи текст этой процедуры
Минимальный код для воспроизведения:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
CREATE TABLE NEW_TABLE (
    REC_ID   INTEGER NOT NULL,
    FIELD_1  INTEGER
);

ALTER TABLE NEW_TABLE ADD CONSTRAINT PK_NEW_TABLE PRIMARY KEY (REC_ID);

CREATE PROCEDURE PROCEDURE_NAME
AS
  DECLARE VARIABLE REC_ID INTEGER;
BEGIN
  FOR
    SELECT
      REC_ID
    FROM
      NEW_TABLE T1
      JOIN NEW_TABLE T2 ON T2.REC_ID = T1.REC_ID /* Причина ошибки при компиляции. */
    WHERE
      FIELD_1 > 10
    INTO
      :REC_ID
    AS CURSOR CUR
  DO
    UPDATE NEW_TABLE
    SET FIELD_1 = FIELD_1 * 10
    WHERE CURRENT OF CUR;
END


Без соединения с T2 процедура скомпилируется.

Но, как понятно из других ответов, мне это использовать смысла нет.
...
Рейтинг: 0 / 0
Восстановление БД из резервной копии приводит к проблемам с процедурами (IB XE7)
    #38950005
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Калям,

это и в FB нельзя сделать. Ибо позиционное обновление возможно только для курсора по той же таблице. При соединении таблиц это уже другой курсор.
...
Рейтинг: 0 / 0
10 сообщений из 10, страница 1 из 1
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Восстановление БД из резервной копии приводит к проблемам с процедурами (IB XE7)
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]