为什么我不能在dynamicSQL中的DDL / SCL语句中使用绑定variables?

我正在尝试使用绑定variables在dynamicSQL中执行SQL命令:

-- this procedure is a part of PL/SQL package Test_Pkg PROCEDURE Set_Nls_Calendar(calendar_ IN VARCHAR2) IS BEGIN EXECUTE IMMEDIATE 'ALTER SESSION SET NLS_CALENDAR = :cal' USING IN calendar_; END Set_Nls_Calendar; 

然后在客户端,我试图调用该过程:

 Test_Pkg.Set_Nls_Calendar('Thai Buddha'); 

但是这得到了我ORA-02248: invalid option for ALTER SESSION

而我的问题是: 为什么我不能在dynamicSQL中的DDL / SCL语句中使用绑定variables?

在DDL语句中不允许绑定variables。 所以下面的语句会导致错误:

  • 示例#1:DDL语句 。 将导致ORA-01027:绑定variables不允许进行数据定义操作

     EXECUTE IMMEDIATE 'CREATE TABLE dummy_table ( dummy_column NUMBER DEFAULT :def_val )' USING 42; 
  • 示例#2:DDL语句 。 会导致ORA-00904::无效的标识符

     EXECUTE IMMEDIATE 'CREATE TABLE dummy_table ( :col_name NUMBER )' USING var_col_name; 
  • 示例#3:SCL语句 。 将导致ORA-02248:ALTER SESSION无效选项

     EXECUTE IMMEDIATE 'ALTER SESSION SET NLS_CALENDAR = :cal' USING var_calendar_option; 

问题

要理解为什么发生这种情况,我们需要看看如何处理dynamicSQL语句 。

通常,应用程序会提示用户inputSQL语句的文本以及语句中使用的主机variables的值。 然后OracleparsingSQL语句。 也就是说,Oracle检查SQL语句以确保它遵循语法规则并引用有效的数据库对象。 parsing还包括检查数据库访问权限 1 ,预留所需的资源,并find最佳访问path。

1 回答者强调

请注意,parsing步骤将任何variables绑定到dynamic语句之前发生。 如果您检查以上四个示例,您将意识到parsing器没有办法确保这些dynamicSQL语句的语法有效性,而无需知道绑定variables的值。

  • 示例#1 :parsing器无法判断绑定值是否有效。 如果不USING 42 ,程序员用USING 'forty-two' USING 42写了什么?
  • 示例#2 :parsing器无法确定:col_name是否是有效的列名称。 如果绑定的列名是'identifier_that_well_exceeds_thirty_character_identifier_limit'怎么办?
  • 例#3NLS_CALENDAR值是build立在常量(对于给定的Oracle版本?)。 parsing器不能分辨绑定variables是否有有效值。

所以答案就是你不能在dynamicSQL中绑定schema元素,比如表名,列名。 你也可以绑定build立在常量


实现dynamic引用模式元素/常量的唯一方法是在dynamicSQL语句中使用string连接。

  • 示例#1:

     EXECUTE IMMEDIATE 'CREATE TABLE dummy_table ( dummy_column NUMBER DEFAULT ' || to_char(42) || ')'; 
  • 示例#2:

     EXECUTE IMMEDIATE 'CREATE TABLE dummy_table (' || var_col_name || ' NUMBER )'; 
  • 示例#3:

     EXECUTE IMMEDIATE 'ALTER SESSION SET NLS_CALENDAR = ''' || var_calendar_option || ''''; 
Interesting Posts