在 Oracle 中执行立即选择语句

Posted

技术标签:

【中文标题】在 Oracle 中执行立即选择语句【英文标题】:Execute immediate select statement in Oracle 【发布时间】:2014-07-28 08:07:26 【问题描述】:

我在其中一个查询中使用了立即执行语句。

    procedure p1 (p_pk1_column, p_pk2_column , p_conv_table_name ,p_MODUE_NAME )
    is
    v_select_string   := 'SELECT'''||p_MODUE_NAME||''',''' ||p_pk1_column || ''',''' || p_pk2_column ||''' FROM ' ||p_conv_table_name || v_where_condition;
    execute immediate v_select_string  ;
    dbms_output.put_line('string:'||v_select_string  );
    end p1;

这里我在另一个过程 p2 中调用 p1 过程

PROCEDURE P2 IS
v_pk1_column:='a';
v_pk2_columnm:='b';
v_mod_name:='mOD1';
p1(v_pk1_column,v_pk2_columnm);
end p2;
/

在 p2 过程 a, b 是 p_conv_table_name 的列名。我想执行 select p_mod_name, a, b from p_conv_table_name where condition;因此它应该为 p_conv_table_name 中的 a 和 b 列提供值。

但它的执行就像 select p_mod, p_pk1_col,p_pk2_col from p_conv_table_name where condition; 所以只是选择列名而不是该列中的值。

请建议一些方法来实现该列中的值。

提前致谢

【问题讨论】:

在我看来单引号太多了?您正在执行“SELECT 'a', 'b'”等而不是“SELECT a, b”等。 只要检查脚本的输出,你就会发现它就像SELECT'z','zz','zzz' FROM zzzz。使用语法正确的示例提供问题是一种很好的做法 为什么不想使用 DBMS_SQL 包和绑定变量?当您像这样构建动态查询时,可能会出现 SQL 注入,DBMS_SQL 和绑定变量可以帮助您避免这种情况。 作为per the documentation;如果你正在执行一个 SELECT 语句,你需要 SELECT INTO something... 【参考方案1】:

在构建SELECT 语句时,列名用单引号括起来,这会将它们转换为字符串文字。将您的程序更改为:

CREATE OR REPLACE PROCEDURE P1 (p_pk1_column      IN VARCHAR2,
                                p_pk2_column      IN VARCHAR2,
                                p_conv_table_name IN VARCHAR2,
                                p_MODUE_NAME      IN VARCHAR2)
IS
  v_select_string    VARCHAR2(2000);
  v_where_condition  VARCHAR2(2000) := ' WHERE SOMETHING = SOMETHING_ELSE';
  csr                SYS_REFCURSOR;
  v_val_1            VARCHAR2(2000);
  v_val_2            VARCHAR2(2000);
  v_mod_name         VARCHAR2(2000);
BEGIN
  v_select_string   := 'SELECT ' || p_MODUE_NAME || ',' ||
                                    p_pk1_column || ',' ||
                                    p_pk2_column ||
                       ' FROM ' || p_conv_table_name ||
                       v_where_condition;

  dbms_output.put_line('string:' || v_select_string);

  OPEN csr FOR v_select_string;

  LOOP
    FETCH csr INTO v_mod_name, v_val_1, v_val_2;

    EXIT WHEN csr%NOTFOUND;         

    DBMS_OUTPUT.PUT_LINE('v_mod_name=''' || v_mod_name || '''  ' ||
                         'v_val_1=''' || v_val_1 || '''  ' ||
                         'v_val_2=''' || v_val_2 || '''');
  END LOOP;

  CLOSE csr;
END P1;

我还将代码更改为 OPENFETCH 光标,而不是使用 EXECUTE IMMEDIATEOPENFETCH 通常更适合与动态 SELECT 语句一起使用。

分享和享受。

【讨论】:

以上是关于在 Oracle 中执行立即选择语句的主要内容,如果未能解决你的问题,请参考以下文章

执行立即选择不返回任何值

ORACLE 在立即执行中批处理 DDL 语句

如何在执行立即语句中包含变量?

无法运行两个单独的选择语句 Oracle / Toad ORA-00933

Oracle 立即执行 DDL 和嵌套表

如何使用plsql导出oracle数据建表语句,存储过程,视图.以及表中数据