动态 SQL - 检查语法和语义

Dynamic SQL - Check syntax and semantics

使用 Oracle 动态 SQL 可以执行包含 SQL 语句的字符串。例如

l_stmt := 'select count(*) from tab1';
execute immediate l_stmt;

是否可以不执行 l_stmt 但检查语法和语义是否以编程方式正确?

希望这样你可以检查执行前形成的查询。

set serveroutput on;
DECLARE
lv_sql VARCHAR2(1000);
lv_cnt PLS_INTEGER;
BEGIN
lv_sql:='select count(*) from tab1';
dbms_output.put_line(lv_sql);
--EXECUTE IMMEDIATE lv_sql INTO lv_cnt;
END

我认为唯一的"solution"就是使用DBMS_SQL.PARSE()

它并不完美,但它是你能得到的最好的

EXPLAIN PLAN 将检查几乎所有类型的 SQL 语句的语法和语义。与 DBMS_SQL.PARSE 不同,它不会隐式执行任何内容。

解释计划的重点是展示 Oracle 将如何执行一条语句。作为生成计划的副作用,它还必须检查语法、权限,并且通常会执行除实际 运行 语句之外的所有操作。解释计划本身没有意义,可以忽略,该语句只是 运行 检查是否有错误。只要没有错误,这个语句就是有效的。

例如,下面的 PL/SQL 块检查 SELECT 语句和 CREATE TABLE 语句的有效性。他们 运行 没有错误,所以语法没问题。

begin
    execute immediate 'explain plan for select * from dual';
end;
/

begin
    execute immediate 'explain plan for create table just_some_table(a number)';
end;
/

运行 错误的语句会产生错误。至少在这个测试用例中,它会产生相同的错误,就好像语句本身就是 运行 一样。

begin
    execute immediate 'explain plan for select * from this_table_does_not_exist';
end;
/
ORA-00942: table or view does not exist
ORA-06512: at line 2

手册中的语法图暗示它应该 运行 for all statements。但是,似乎至少有一些语句类型不起作用,例如 ALTER SESSION

begin
    execute immediate 'explain plan for alter session set optimizer_features_enable = ''11.2.0.4''';
end;
/
ORA-00900: invalid SQL statement
ORA-06512: at line 2

稍微偏离主题 - 您是否正在尝试构建一个完全通用的 SQL 界面,例如内置于 PL/SQL 中的私有 SQL Fiddle?您是否需要担心诸如阻止用户尝试 运行 某些语句类型以及确保没有尾随分号之类的事情?如果是这样,我可以编辑问题以帮助完成一些困难的动态 SQL 任务。