ORA-06502 while dbms_sql.execute(<anonymous block>) 与外绑定

ORA-06502 while dbms_sql.execute(<anonymous block>) with out-binding

我在通过 dbms_sql 执行带有绑定变量(输入和输出)的动态 SQL 时遇到了一些问题。 我总是得到 ORA-06502 但无法找到原因。 到目前为止,我可以减少 SQL-snippet 以了解 out 参数发生错误。

declare
  l_cur_id NUMBER;
  l_sql    VARCHAR2(100) := 'begin :1 := ''test''; end;';
  l_res    VARCHAR2(100);
  l_dbms   NUMBER;
begin
  l_cur_id := dbms_sql.open_cursor;
  dbms_sql.parse(l_cur_id, l_sql, dbms_sql.native);
  dbms_sql.bind_variable(l_cur_id, '1', l_res);
  l_dbms := dbms_sql.execute(l_cur_id); -- ORA here
  dbms_sql.close_cursor(l_cur_id);
exception
  when others then
    dbms_sql.close_cursor(l_cur_id);
    raise;
end;
/

输入参数工作正常。 我正在使用 Oracle Database 12 企业版 12.1.0.2.0

是否必须以其他方式配置输出参数? 感谢您的帮助。

您还没有指定绑定变量的大小。默认情况下,它使用变量的当前长度; from the documentation:

Parameter Description
out_value_size Maximum expected OUT value size, in bytes, for the VARCHAR2, RAW, CHAR OUT or IN/OUT variable. If no size is given, then the length of the current value is used. This parameter must be specified if the value parameter is not initialized.

由于该变量默认初始化为空,因此该长度为零;这与说它未初始化相同。因此,当它尝试将四字符 'test' 分配给零字符变量时会出错。

您还need to call dbms_sql.variable_value 获取绑定变量值。

如果你用一个值 初始化 l_res 至少 只要你可能在动态块中分配的任何东西都可以工作:

declare
  ...
  l_res    VARCHAR2(100) := 'xxxx';
  ...
begin
  ...
  dbms_sql.bind_variable(l_cur_id, '1', l_res);
  l_dbms := dbms_sql.execute(l_cur_id);
  dbms_sql.variable_value(l_cur_id, '1', l_res);
  ...
end;
/

但这显然是理想的,因为实际上您需要提供一个 100 个字符长的值,如果以后长度发生变化,请记住进行调整;所以改为在绑定调用中指定长度:

declare
  ...
  l_res    VARCHAR2(100);
  ...
begin
  ...
  dbms_sql.bind_variable(l_cur_id, '1', l_res, 100);
  l_dbms := dbms_sql.execute(l_cur_id);
  dbms_sql.variable_value(l_cur_id, '1', l_res);
  ...
end;
/

db<>fiddle