PL/SQL:使用条件变量立即执行

问题描述 投票:0回答:2

我有一个 PL/SQL 函数是这样写的

IF p_class IS NOT NULL
THEN
v_conditions := ' WHERE class = :p_class '
ELSE
v_conditions := ' WHERE 1 = :p_class '
p_class := 1
END IF;

我想用给定的

p_class
执行查询:

v_query := v_query || v_conditions;
EXECUTE IMMIDIATE v_query USING p_class

现在我想检查我的

p_class
是否不存在,我的查询中不会有
v_conditions
。 除了使用
WHERE 1 = :p_class
之外,还有更好的方法吗?

我尝试重构我的函数来检查

p_class
是否为空,我不必添加
v_conditions
来查询,但出现错误:

bind variable does not exists
.

我也尝试过

v_conditions := ' WHERE class = ' || p_class
但是我担心它会受到SQL注入所以我没有使用它。

oracle plsql oracle-sqldeveloper
2个回答
1
投票

我认为你的方法只针对结果,而不是原因。

如果您提前(或至少在执行之前)知道您不需要条件,我会直接跳过其他所有内容:

 IF p_class IS NULL THEN
     EXECUTE IMMEDIATE v_query;
 ELSE
     v_query := v_query || v_conditions;
     EXECUTE IMMEDIATE v_query USING p_class;
 END IF;

一般来说,我更喜欢直接从“触发”或需要它们的条件中过滤掉此类特殊情况。

如果您确实想要一个内联方法来执行此操作,则不能,因为

USING
并且
1=1
可能是唯一的方法。


0
投票

您也可以在一条语句中执行此操作,无需 IF:

DECLARE
  l_ename VARCHAR2(100);
  l_statement VARCHAR2(500) := 'SELECT COUNT(*) FROM emp WHERE ename = :ename or :ename IS NULL';
  l_result NUMBER;
BEGIN
  l_ename := 'KING';
  --l_ename := NULL
  EXECUTE IMMEDIATE l_statement INTO l_result USING l_ename, l_ename;
  dbms_output.put_line(l_result);
END;
/
© www.soinside.com 2019 - 2024. All rights reserved.