У меня есть следующий код, который без проблем работает в SQL Developer, но когда я добавляю изменения в liquibase и запускаю их, я получаю сообщение об ошибке.
DECLARE
seqval NUMBER;
BEGIN
SELECT MAX(id) + 1 INTO seqval FROM T_SLS_ITEMS;
execute immediate('CREATE SEQUENCE SEQ_SLS_ITEMS MINVALUE '||seqval||'');
END;
и набор изменений для него:
<changeSet author = "Cristian Marian (cmarian)" id = "2019-05-24-171101 Fix Items sequence - creting">
<sql>
DECLARE
seqval NUMBER;
BEGIN
SELECT MAX(id) + 1 INTO seqval FROM T_SLS_ITEMS;
execute immediate('CREATE SEQUENCE SEQ_SLS_ITEMS MINVALUE '||seqval||'');
END;
</sql>
</changeSet>
Ошибка выглядит следующим образом:
Reason: liquibase.exception.DatabaseException: ORA-06550: line 2, column 27:
PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following:
:= . ( @ % ; not null range default character
[Failed SQL: DECLARE
seqval NUMBER] (Liquibase Update failed.)
@htshame, конечно. Я добавил это. В идентификаторе есть небольшая опечатка, но, думаю, не столь существенная. :D
Обычно динамический SQL не требует терминатора оператора. Я не знаю Liquibase, но кажется, что делает требует этого.
Я не уверен, что понимаю, что вы имели в виду, объединяя пустую строку в конце:
execute immediate('CREATE SEQUENCE SEQ_SLS_ITEMS MINVALUE '||seqval||'');
^
empty string?
Как насчет объединения точки с запятой вместо этого, т.е.
execute immediate('CREATE SEQUENCE SEQ_SLS_ITEMS MINVALUE '||seqval||';');
^
semi-colon
На данный момент, я готов попробовать что-нибудь. Эта точка с запятой не сделала этого. Там, где эта пустая строка, были и другие параметры, но они мне больше не нужны. Во всяком случае, я заметил, что liquibase жалуется на объявление seqval
. Пишет, что там хотел бы иметь ;
, но он есть и почему-то не видит. Я уже проверил странные символы между ними, но ничего не нашел.
Было бы полезно, если бы вы включили что-то вроде <sqlFile endDelimiter = ";"/>
в свой код?
Liquibase попытается разделить «скрипт» внутри тега <sql>
с помощью разделителя операторов по умолчанию, которым является ;
. Для блока PL/SQL это явно неправильно, так как весь блок нужно рассматривать как один оператор.
Для этого используйте атрибут splitStatements
в теге <sql>
:
<sql splitStatements = "false">
DECLARE
....
END;
</sql>
Это определенно сработало для меня.
Не могли бы вы опубликовать свой набор изменений?