我有一个 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注入所以我没有使用它。
我认为你的方法只针对结果,而不是原因。
如果您提前(或至少在执行之前)知道您不需要条件,我会直接跳过其他所有内容:
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
可能是唯一的方法。
您也可以在一条语句中执行此操作,无需 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;
/