PLSQL - 提高代码效率

PLSQL - Improving code efficiency

这个问题是关于 PLSQL - 用于提高代码效率和编码标准。

非常感谢任何帮助、指示、参考或建议。

问题:

我有一个 plsql 过程,其 INPUT 参数 i_flag 类型为 BOOLEAN.

基于这个 i_flag 的值(可以是真或假)我必须执行一个 sql 查询。如果值为 TRUE 则 SQL1(假设查询 1.1)否则如果值为 FALSE SQL2(假设查询 1.2)将被执行。

SQL2 与 SQL1 相同,只是增加了 where 子句。

SQL1 (1.1)

select a.user_id, a.user_name, a.dept_id, b.country from user a , contact b
where a.user_id = b.user_id;

SQL1 (1.2)

select a.user_id, a.user_name, a.dept_id, b.country from user a , contact b
where a.user_id = b.user_id
and a.user_status is not null;

不是在 plsql 中编写 IF-ELSE 是否可以在单个 SQL 查询中编写此查询?

您可以使用逻辑 or 运算符在单个查询中创建相同的行为:

select a.user_id, a.user_name, a.dept_id, b.country 
from user a , contact b
where a.user_id = b.user_id AND (i_flag = TRUE OR a.user_status IS NOT NULL)

请注意,顺便说一下,隐式连接(在 from 子句中有两个表)是一种已弃用的语法,建议切换到现代的显式语法:

SELECT a.user_id, a.user_name, a.dept_id, b.country 
FROM   user a
JOIN   contact b ON a.user_id = b.user_id
where  i_flag = TRUE OR a.user_status IS NOT NULL

首先,如果您想在 SQL 查询中使用布尔参数,您必须替换为 sql 兼容类型,例如 NUMBER,即使用 0 或 1 代替假或真。

其次,虽然 Mureinik 基于 OR 的答案可行,但如果您使用替代方案,Oracle 通常会提供更好的性能。一种选择是这样的:

SELECT a.user_id, a.user_name, a.dept_id, b.country 
FROM   user a
JOIN   contact b ON a.user_id = b.user_id
WHERE  1 = CASE WHEN i_flag = 1 THEN 1
                WHEN a.user_status IS NOT NULL THEN 1
                ELSE 0 END

它不是很漂亮,但在较大的查询中它有时会有很大帮助。

在语法方面,以上所有答案都很棒。 然而,我的两美分指的是可能有助于你表现的不同改变。 运行 PL/SQL procs 的最大瓶颈是在 PL/SQL 和 SQL 引擎(由 ORACLE 的体系结构分开)之间跳动时看到的。因此,经验法则是尽量减少对每个过程的单独调用量。

如果我们将此规则应用于您的问题 - 您应该检查是否可以将 refcursor 传递给包含所有要查询的用户及其适当的布尔值的过程。如果现在从一批用户的循环中调用该过程,那么当您扩展到大量用户时,这样做将极大地提高性能。

我认为为此写动态sql是个不错的选择。

create or replace procedure sp_..(i_flag boolean) 
as 
 sql_stmt varchar2(1000):='select a.user_id, a.user_name,'|| 
 'a.dept_id,b.country from user a , contact b '||
 'where a.user_id = b.user_id';
begin 
 if (i_flag=false) then 
   sql_stmt:=sql_stmt||' and a.user_status is not null';
end if;
 ---do some stuff with sql_stmt(i.e. refcursor)
end sp_..;  

即使我们能够在单个查询中实现 or 条件,在性能方面也可能不是一个好主意,动态 sql 可能是更好的选择。如果您希望提高代码效率,您可能需要查看类似于 https://www.youtube.com/watch?v=rWEqO-GpJ4M