ORA-01008:并非所有变量都绑定 - "not all variables bound"



这是我的plsql块,动态SQL。我找不到一个原因,为什么它会出现一个错误'no ORA-01008: not all variables bound ORA-06512: at line 23'。

我在EXECUTE IMMEDIATE语句中找不到错误。

DECLARE
form_name      VARCHAR2(225) := 'MUST AS';
ad_no          VARCHAR2(225) := :ad_no;
sql_stmt       VARCHAR2(4000);
sql_output     VARCHAR2(4000);
db_table       VARCHAR(225) := inp_reminder_pkg.form_db_table(form_name);
col_id         VARCHAR(225) := inp_reminder_pkg.get_col_id(form_name);
BEGIN
sql_stmt := '
SELECT :1
FROM @tableName
WHERE advno = :2
AND created = ( SELECT MAX(CREATED)
FROM @tableName
WHERE advno = :2 )'
;
sql_stmt := replace(sql_stmt, '@tableName', db_table);

EXECUTE IMMEDIATE sql_stmt
INTO sql_output
USING  col_id, ad_no;
dbms_output.put_line(sql_output);
EXCEPTION
WHEN no_data_found THEN
dbms_output.put_line('no-data');
END;
让我知道我错过了什么。谢谢你

有三个绑定变量(即使两个具有相同的名称),您需要在execute immediate语句中为它们发送3个参数。

请注意,您可能并不是要将列名作为绑定变量输入,如果您想要选择一个变量列,则必须动态执行此操作。

你的代码有两个问题:

  1. 动态查询有两个占位符:advno的实例,因此您需要在USING子句中传递两个值。是的,这是有点垃圾,但我猜Oracle觉得解析动态SQL足够困难,而不要求编译器匹配占位符名称。
  2. 我们不能传递列名或其他标识符作为参数。我们必须拆分语句以引用列名变量。出于同样的原因,您可以使用replace()调用来替换表名。

所以你需要改变你的程序,使它看起来像这样:

DECLARE
form_name      VARCHAR2(225) := 'MUST AS';
ad_no          VARCHAR2(225) := :ad_no;
sql_stmt       VARCHAR2(4000);
sql_output     VARCHAR2(4000);
db_table       VARCHAR(225) := inp_reminder_pkg.form_db_table(form_name);
col_id         VARCHAR(225) := inp_reminder_pkg.get_col_id(form_name);
BEGIN
sql_stmt := '
SELECT ' || col_id || '
FROM @tableName
WHERE advno = :2
AND created = ( SELECT MAX(CREATED)
FROM @tableName
WHERE advno = :2 )'
;
sql_stmt := replace(sql_stmt, '@tableName', db_table);

EXECUTE IMMEDIATE sql_stmt
INTO sql_output
USING  ad_no, ad_no;
dbms_output.put_line(sql_output);
EXCEPTION
WHEN no_data_found THEN
dbms_output.put_line('no-data');
END;

相关内容

最新更新