动态 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 任务。
使用 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 任务。