Возможно ли проверить на наличие ошибок компиляции на этапе сборки CI?
Tолько что "убил" наш CI, потому что в Git commit был SQL файл с ошибкой. Проверил его в SQL Developer, но забыл скопипастить в файл. Ошибка была только в одном символе, вместо elsif осталось elsеif. Но сборка завершилась успешно, и проявилась только во время тестов.
Сборка проводится с SQL*Plus, упрощенно это выглядит так:
-- pack.sql
create or replace package pack as
procedure proc;
end pack;
/
create or replace package body pack as
procedure proc (par int) is
begin
if par = 1 then null;
elseif par = 2 then null;
end if;
end proc;
end pack;
/
Если запустить этот файл в SQL*Plus, то возникнет ошибка компиляции, но процес в итоге, завершается нормально:
Package created.
Warning: Package Body created with compilation errors.
$ echo $?
0
Как можно в SQL*Plus, или возможно в другом инструменте, проверить на наличие ошибок компиляции во время сборки?
Свободный перевод вопроса Is it possible to validate sql and pl/sql syntax on compile time? от участника @Maxim Ostrovsky
Ответы (1 шт):
Возможно с SQL*Plus, или с его приемником - SQLcl. Надо сделать следующее:
Принудить командой
WHENEVERк прекращению выполнения скрипта (exit) с кодом возврата сбой (failure) при первой встретившейся SQL ошибке (sqlerror).Ошибка компиляции не вызывает SQL ошибку, это только предупереждение. В конце создания/обновления компилируемых объектов, надо проверить их статус и вызвать пользовательское исключение, если стаус не валиден.
Пример SQL файла из вопроса будет выглядеть так:
whenever sqlerror exit failure
set verify off
define objects="'PACK','PACK2'"
create or replace package pack as
procedure proc;
end pack;
/
create or replace package body pack as
procedure proc (par int) is
begin
if par = 1 then null;
elseif par = 2 then null;
end if;
end proc;
end pack;
/
<<check_status>>
begin
for r in (
select * from user_objects
where object_name in (&objects) and status != 'VALID') loop
raise_application_error (-20000, r.object_type||' '||r.object_name||' is '||r.status);
end loop;
end;
/
Его выполнение завершится с кодом failure, если один из объектов, указанных в переменной objects, был скомпилирован с ошибкой:
Package created.
Warning: Package Body created with compilation errors.
<<check_status>>
*
ERROR at line 1:
ORA-20000: PACKAGE BODY PACK is INVALID
ORA-06512: at line 5
ORA-06512: at line 5
$ echo $?
1