Как проверить синтаксис SQL для оператора JDBC без выполнения фактического запроса?

У меня есть оператор SQL (для базы данных Oracle), который занимает много времени, если он действителен. Если он недействителен, он немедленно возвращается с ошибкой.

Я хотел бы проверить, что синтаксис действителен без запуска инструкции (через JDBC), например, за кнопкой "check statement". Есть ли независимый от поставщика способ сделать это? Моя первая мысль просто определить запрос как PreparedStatement, похоже, не вызывает какой-либо компиляции или проверки ошибок.

Ответы

Ответ 1

возможно, выдача плана объяснения для заявления даст вам полезные результаты.

другая мысль - но, возможно, сложнее изменить запрос на добавление (и rownum < 1) или что-то, чтобы ускорить его выполнение.

Ответ 2

Это скорее хак, чем реальный ответ, но вы можете запустить запрос, который всегда будет возвращать одну строку и один столбец:

SELECT ( EXISTS (SELECT 1 FROM dual)
         OR
         EXISTS (your Query here)
       ) AS result
FROM dual 

Это должно возвращать TRUE, если ваш запрос действителен и вызывает ошибку, если он недействителен.

Ответ 3

Если вы имеете дело с запросами SELECT, возможно, JDBC PreparedStatement # getMetaData будет работать?

Ответ 4

Вы можете использовать DBMS_SQL.PARSE, чтобы проверить свою инструкцию. Предупреждение: он будет просто анализировать операторы DML, но он будет выполнять и фиксировать операторы DDL, такие как create table и т.д. Вы можете создать хранимую процедуру, чтобы вернуть значение или логическое значение и обернуть блок следующим образом:

set serveroutput on
-- Example of good SQL 
declare
  c integer;
  s varchar2(50) := 'select * from dual';
begin
  c := dbms_sql.open_cursor;
  dbms_sql.parse(c,s,1);
  dbms_sql.close_cursor(c);
  dbms_output.put_line('SQL Ok');
exception
  when others then
    dbms_sql.close_cursor(c);
    dbms_output.put_line('SQL Not Ok');
end;
/

-- Example of bad SQL
declare
  c integer;
  s varchar2(50) := 'select splat from dual';
begin
  c := dbms_sql.open_cursor;
  dbms_sql.parse(c,s,1);
  dbms_sql.close_cursor(c);
  dbms_output.put_line('SQL Ok');
exception
  when others then
    dbms_sql.close_cursor(c);
    dbms_output.put_line('SQL Not Ok');
end;
/

Ответ 5

Вы можете использовать предварительный компилятор Oracle Pro * C для выполнения проверки синтаксиса (скачать здесь).

Это инструмент, предназначенный для предварительного компиляции кода C, содержащего необработанные операторы Oracle SQL, но вы можете "злоупотреблять" им для выполнения синтаксических проверок SQL.

  • Создайте файл test.pc с помощью этого кода:

    EXEC SQL SELECT * FROM DUAL WERE 1 = 1;

  • Запустите эту команду после установки инструментов прекомпилятора:

    proc INAME = test SQLCHECK = SYNTAX

  • Вы увидите этот вывод:

    Синтаксическая ошибка в строке 1, столбец 34, файл test.pc: Ошибка в строке 1, столбец 34 в файле test.pc
    EXEC SQL SELECT * FROM DUAL WERE 1 = 1;
    ................................. 1
    PCC-S-02201, встретил символ "1", ожидая одно из следующего:
     ;, for, union, connect, group, having, intersect, минус,  порядок, начало, где, с,
    Символ "having" был заменен на "1", чтобы продолжить.

Это должно быть легко интегрировать в ваше решение.

Обратите внимание, что он также может выполнять онлайн-проверки семантики, проверяя, что все используемые процедуры и таблицы действительны в конкретной схеме. Для этого вы передаете SQLCHECK = SEMANTICS USERID = youruser