我正在尝试使用绑定变量在动态SQL中执行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
。
我的问题是:为什么不能在动态SQL的DDL / SCL语句中使用绑定变量?
DDL语句中不允许绑定变量。因此,以下语句将导致错误:
示例1:DDL语句。会导致ORA-01027:数据定义操作不允许绑定变量
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;
要了解为什么会发生这种情况,我们需要查看如何处理动态SQL语句。
通常,应用程序会提示用户输入SQL语句的文本以及该语句中使用的主机变量的值。然后,Oracle解析SQL语句。也就是说,Oracle检查SQL语句以确保它遵循语法规则并引用有效的数据库对象。解析还涉及检查数据库访问权限1,保留所需的资源以及找到最佳访问路径。
1 答题者添加的重点
请注意,解析步骤是在将任何变量绑定到动态语句之前发生的。如果检查以上四个示例,您将意识到,解析器无法在不知道绑定变量值的情况下保证这些动态SQL语句的语法有效性。
USING 42
程序员写的USING 'forty-two'
怎么办?:col_name
为有效的列名。如果绑定的列名是'identifier_that_well_exceeds_thirty_character_identifier_limit'
?NLS_CALENDAR
内置于常量中(对于给定的Oracle版本?)。解析器无法确定绑定变量是否将具有有效值。因此,答案是您无法在动态SQL中绑定架构元素,例如表名,列名。也不能绑定内置常量。
实现动态引用架构元素/常量的唯一方法是在动态SQL语句中使用字符串连接。
范例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 || '''';
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句