sam*_*ris 14 oracle plsql dynamic-sql execute-immediate
我试图在动态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;
Run Code Online (Sandbox Code Playgroud)
然后在客户端,我试图调用该过程:
Test_Pkg.Set_Nls_Calendar('Thai Buddha');
Run Code Online (Sandbox Code Playgroud)
但这就是我ORA-02248: invalid option for ALTER SESSION.
我的问题是:为什么我不能在动态SQL中的DDL/SCL语句中使用绑定变量?
sam*_*ris 24
DDL语句中不允许绑定变量.因此以下语句将导致错误:
示例#1:DDL语句.将导致 ORA-01027:绑定变量不允许进行数据定义操作
EXECUTE IMMEDIATE
'CREATE TABLE dummy_table ( dummy_column NUMBER DEFAULT :def_val )'
USING 42;
Run Code Online (Sandbox Code Playgroud)示例#2:DDL语句.会导致 ORA-00904 ::标识符无效
EXECUTE IMMEDIATE
'CREATE TABLE dummy_table ( :col_name NUMBER )'
USING var_col_name;
Run Code Online (Sandbox Code Playgroud)示例#3:SCL语句.将导致 ORA-02248:ALTER SESSION的无效选项
EXECUTE IMMEDIATE
'ALTER SESSION SET NLS_CALENDAR = :cal'
USING var_calendar_option;
Run Code Online (Sandbox Code Playgroud)要理解为什么会发生这种情况,我们需要查看如何处理动态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) || ')';
Run Code Online (Sandbox Code Playgroud)示例#2:
EXECUTE IMMEDIATE
'CREATE TABLE dummy_table (' || var_col_name || ' NUMBER )';
Run Code Online (Sandbox Code Playgroud)示例#3:
EXECUTE IMMEDIATE
'ALTER SESSION SET NLS_CALENDAR = ''' || var_calendar_option || '''';
Run Code Online (Sandbox Code Playgroud)| 归档时间: |
|
| 查看次数: |
12245 次 |
| 最近记录: |