【发布时间】:2021-10-27 19:56:20
【问题描述】:
我正在尝试使用动态 SQL 将表达式传递到我的查询的 WHERE 子句中。表达式可以包含多个过滤器/列。
与 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 在第 8 行返回错误:ORA-00920: invalid relational operator(EXEC 语句)。
我在示例 2 中做错了什么以及使用占位符的正确方法是什么?
【问题讨论】:
-
你不能那样做。 :a 只是传递了一个字符串。它没有得到评估。如果需要完全控制,则需要使用 DBMS_SQL 包。
-
我明白了。用 DBMS_SQL 包怎么做?
-
您需要将输入拆分为带有占位符的表达式以及这些占位符的值。如果您有可变数量的占位符,那么它会变得复杂,因为您将不得不使用具有不同数量的参数和逻辑的多个动态 SQL 语句来执行一个。或者您可以使用
cursor_sharing=force的惰性选项。无论您做什么,这都极易受到 SQL 注入的影响,您需要验证输入 - 您最好使用带有允许过滤器的静态 SQL。
标签: oracle plsql dynamic-sql