вставка большого количества строк в базу данных firebird

#sql #firebird #firebird2.5

#sql #firebird #firebird2.5

Вопрос:

Firebird 2.5 с IB Expert.

У меня есть SQL-скрипт для добавления большого количества строк в базу данных

 execute block as declare ID2 int; begin
EXECUTE PROCEDURE NEW_PROCEDURE('1', '33001', 'be0ad759-ee6a-4a21-b5f9-ed71f1eba54c00', 'Новое оборудование') returning_values :ID2;
EXECUTE PROCEDURE NEW_PROCEDURE2('1', :ID2, '13.10.2016', 'От 13.10.2016 № 1', 'Поступления');
EXECUTE PROCEDURE NEW_PROCEDURE2('1', :ID2, '13.10.2016', 'В составе Новое оборудование, в составе Новое оборудование', 'В составе');
EXECUTE PROCEDURE NEW_PROCEDURE('1', '3200', '91403ed6-56af-4acf-b66e-50c10118e4e60', 'Новое оборудование') returning_values :ID2;
EXECUTE PROCEDURE NEW_PROCEDURE2('1', :ID2, '13.10.2016', 'От 13.10.2016 № 1', 'Поступления');
EXECUTE PROCEDURE NEW_PROCEDURE2('1', :ID2, '13.10.2016', 'В составе Новое оборудование', 'В составе');
EXECUTE PROCEDURE NEW_PROCEDURE('1', '33010', 'be0ad759-ee6a-4a21-b5f9-ed71f1eba54c01', 'Новое оборудование') returning_values :ID2;
EXECUTE PROCEDURE NEW_PROCEDURE2('1', :ID2, '13.10.2016', 'От 13.10.2016 № 1', 'Поступления');
EXECUTE PROCEDURE NEW_PROCEDURE2('1', :ID2, '13.10.2016', 'В составе Новое оборудование, в составе Новое оборудование', 'В составе');
 100K
end
  

как видно из примера кода, данные практически идентичны, но вывод ошибки

 Invalid token.
Dynamic SQL Error.
SQL error code = -104.
Unexpected end of command - line 489, column 87.
  

Комментарии:

1. Не знаю Firebird, но если каждая процедура выполняется правильно одна за другой, я бы предположил, что вы столкнулись с ошибкой памяти. У меня было это на другом сервере с огромной вставкой. Транзакция заняла много места, одна из временных таблиц была заполнена (не помню, какая именно). Мне пришлось сократить это на меньшую транзакцию (10 тыс. вставок на транзакцию).

Ответ №1:

Учитывая указанное вами количество строк (100 КБ), размер вашего оператора превышает 64 килобайта (что является максимальным размером оператора в Firebird 2.5 и более ранних версиях). An execute block — это один оператор, поэтому вам нужно уменьшить количество операторов в блоке выполнения, чтобы он поместился в 64 килобайта.

Firebird 3 допускает большие операторы, но только при выполнении с новым API, так что это не поможет при выполнении из IB Expert.

Кроме того, та же ошибка может быть вызвана, когда ваш инструмент запроса использует точку с запятой в качестве завершителя оператора по умолчанию. Firebird выполняет каждый оператор, поэтому большинство инструментов запроса разделяются точкой с запятой, чтобы отправлять операторы один за другим. Однако execute block внутри также используются точки с запятой. Это означает, что вместо полного execute block он отправляет только

 execute block as declare ID2 int
  

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

Чтобы иметь возможность выполнить это, вам необходимо указать вашему инструменту запроса переключить оператор terminator . Для большинства инструментов Firebird это set term , например set term #; , переключит терминатор оператора tools на # .

Вам необходимо выполнить как:

 set term #;

execute block as 
  declare ID2 int; 
begin
  EXECUTE PROCEDURE NEW_PROCEDURE('1', '33001', 'be0ad759-ee6a-4a21-b5f9-ed71f1eba54c00', 'Новое оборудование') returning_values :ID2;
  ...
end#

set term ;#
  

См. Также SET TERM разделитель или завершающий символ.

Комментарии:

1. Учитывая номер строки в сообщении об ошибке (489), я бы сказал, что это, скорее всего, размер оператора … если причиной будет терминатор оператора, убедитесь, что номер строки будет равен 1 (или 2 или 3, зависит от того, как на самом деле отформатирован оператор).

2. Я попытался использовать предложенный вами вариант, но он по-прежнему выдает ошибку

3. общее количество добавленных записей 3700

4. Я уменьшил количество строк до 190, и мои скрипты выполняются

5. @fedormoore Тогда это мой последний комментарий: вы превышаете максимальный размер инструкции своим блоком выполнения.