oracle dynamic sql 计算 where 子句中的表达式

oracle dynamic sql evaluate expression in where clause

我正在尝试使用动态 SQL 将表达式传递到查询的 WHERE 子句中。表达式可以包含多个filters/columns.

与 SO 上的其他帖子类似,以下(示例 1)有效:


DECLARE
    where_expression VARCHAR2(40) := q'[filter_column = 'some_value')]';
    plsql_block VARCHAR2(500);

BEGIN
    plsql_block := 'SELECT column FROM mytable';

    EXECUTE IMMEDIATE plsql_block || ' WHERE ' || where_expression;

END;
/

并且这种使用占位符的方法(示例 2)不起作用:


DECLARE
    where_expression VARCHAR2(40) := q'[filter_column = 'some_value')]';
    plsql_block VARCHAR2(500);

BEGIN
    plsql_block := 'SELECT column FROM mytable WHERE :a';

    EXECUTE IMMEDIATE plsql_block USING where_expression;

END;
/

Oracle returns 错误:ORA-00920: invalid relational operator 第 8 行(EXEC 语句)。

我在示例 2 中做错了什么?使用占位符的正确方法是什么?

What am I doing wrong in example 2 and what's the correct way with placeholders?

占位符语法用于在执行语句时传递要检查的值。预期的用法是这样的:

DECLARE
    v_out_1     varchar2(32);
    v_out_2     varchar2(32);
    plsql_block VARCHAR2(500);

BEGIN
    plsql_block := 'SELECT column FROM mytable WHERE filter_column = :a';

    EXECUTE IMMEDIATE plsql_block INTO v_out_1 USING 'some value';

    EXECUTE IMMEDIATE plsql_block INTO v_out_2 USING 'another value';
END;
/

CASE 表达式中可能的过滤列列入白名单:

DECLARE
  v_out        VARCHAR2(32);
  column_name  VARCHAR2(30) := 'COLUMN1';
  column_value VARCHAR2(30) := 'value1';
  sql          VARCHAR2(500);
BEGIN
  sql := 'SELECT column
          FROM   mytable
          WHERE  CASE :name
                 WHEN ''COLUMN1'' THEN column1
                 WHEN ''COLUMN2'' THEN column2
                 WHEN ''COLUMN3'' THEN column3
                 END = :value';

  EXECUTE IMMEDIATE sql INTO v_out USING column_name, column_value;
END;
/