在Oracle 11gR2中使用条件进行多次更新

在Oracle 11gR2中使用条件进行多次更新,oracle,performance,plsql,oracle11gr2,Oracle,Performance,Plsql,Oracle11gr2,我一直在尝试在Oracle11GR2中创建过程,它所做的是根据输入动态地执行对特定表的更新。用户可以更新表的任何或全部四个属性。下面的代码成功地达到了要求 SET SERVEROUTPUT ON; CREATE OR REPLACE PROCEDURE eis_mod_user_emp_dets_proc (p_pres_add eis_employees_tb.emp_present_add%TYPE DEFAULT NULL ,p_marital_stat e

我一直在尝试在Oracle11GR2中创建过程,它所做的是根据输入动态地执行对特定表的更新。用户可以更新表的任何或全部四个属性。下面的代码成功地达到了要求

SET SERVEROUTPUT ON;
CREATE OR REPLACE PROCEDURE eis_mod_user_emp_dets_proc
(p_pres_add         eis_employees_tb.emp_present_add%TYPE     DEFAULT NULL
,p_marital_stat     eis_employees_tb.emp_marital_status%TYPE  DEFAULT NULL
,p_cont_ll          eis_employees_tb.emp_contact_ll%TYPE      DEFAULT NULL
,p_cont_mob         eis_employees_tb.emp_contact_mob%TYPE     DEFAULT NULL)
IS
BEGIN
IF  p_pres_add IS NOT NULL THEN
    UPDATE      eis_employees_tb
    SET         emp_present_add=p_pres_add
    WHERE       emp_id = sess.g_var_uid;
    dbms_output.put_line('Present Address updated Successfully');
END IF;

IF  p_marital_stat IS NOT NULL THEN
    UPDATE      eis_employees_tb
    SET         emp_marital_status=p_marital_stat
    WHERE       emp_id = sess.g_var_uid;
    dbms_output.put_line('Present Marital Status updated Successfully');
END IF;

IF  p_cont_ll IS NOT NULL THEN
    UPDATE      eis_employees_tb
    SET         emp_contact_ll=p_cont_ll
    WHERE       emp_id = sess.g_var_uid;
    dbms_output.put_line('Present Landline Number updated Successfully');
END IF;

IF  p_cont_mob IS NOT NULL THEN
    UPDATE      eis_employees_tb
    SET         emp_contact_mob=p_cont_mob 
    WHERE       emp_id = sess.g_var_uid;
    dbms_output.put_line('Present Mobile Number updated Successfully');
END IF;

END eis_mod_user_emp_dets_proc;
/
SHOW ERROR;`
编译过程后的输出

程序eis\U mod\U user\U emp\U dets\U proc已编译。
没有错误。

该程序的示例执行如下:
EXEC global_procs_pkg.login_proc('bh104','bh104');
执行环境影响报告(emp)模块用户程序(p\U pres\U add=>Bundelkhand);

样本输出:

anonymous block completed
Welcome to the system bh104

anonymous block completed
Present Address updated Successfully
Present Marital Status updated Successfully
有没有更好的方法来优化这个过程?
我希望尽可能地优化这个过程,以便尽可能减少比较的次数,并减少update语句的数量,从而提高性能。所以我需要改进这段代码的建议。

试试这个。您的方法效率不高,如果它们都不是null,那么您将触发4条update语句。它还必须在sql引擎和pl/sql引擎之间执行4个上下文切换。您可以使用通用dbms_输出语句来表示更新成功。但是,将dbms_输出作为包的一部分是不好的做法

IF  p_pres_add IS NOT NULL OR p_marital_stat IS NOT NULL OR p_cont_ll IS NOT NULL OR p_cont_mob IS NOT NULL
THEN 
  UPDATE      eis_employees_tb
    SET         emp_present_add=nvl(p_pres_add, emp_present_add),
                emp_marital_status=nvl(p_marital_stat, emp_marital_status),
                emp_contact_ll=nvl(p_cont_ll, emp_contact_ll),
                emp_contact_mob=nvl(p_cont_mob, emp_contact_mob)
    WHERE       emp_id = sess.g_var_uid;
END IF;

您的方法效率低下,因为您正在进行4次更新

您可以使用NVL在单个UPDATE语句中执行此操作

UPDATE eis_employees_tb
SET emp_present_add     = NVL(p_pres_add, emp_present_add),
    emp_marital_status  = NVL(p_marital_stat, emp_marital_status),
    emp_contact_ll      = NVL(p_cont_ll,emp_contact_ll),
    emp_contact_mob     = NVL(p_cont_mob , emp_contact_mob)
WHERE emp_id            = sess.g_var_uid;

另一方面,生产系统不使用DBMS\u输出。如果确实需要将输出推送到调用方,则可能需要一个OUT参数。

我认为不需要
如果
构造,
NVL
将处理它。如果所有值都为null,则不需要执行update语句。在大多数情况下,它不是必需的,但在某些情况下,它可以派上用场。最好不要在声明本身中将默认值设为NULL。或者,如果逻辑比示例更复杂,您可以根据输入参数编写动态sql,并在单个sql语句中执行。我修改了代码,尝试实现动态sql,你能看看这个链接,告诉我这是不是一个更好的方法吗@RajorshiMukherjee不,不,不。不要(ab)使用EXECUTE IMMEDIATE来处理这些琐碎的事情。您应该以静态sql进行更新,而不需要动态sql。它不仅会破坏性能,而且很难维护。你为什么不试试提供的答案,它很短,效率更高。我试过使用你的代码,不用说它工作得很完美,但是,我想显示一条消息,当没有数据要更新时,需要通知用户。我如何做到这一点?我是否应该使用AND将其插入一个IF条件,然后执行其余语句?比如说。在这里,我添加了来自另一个过程的代码,并正在检查是否有任何数据丢失。我应该使用IF和AND来检查数据的有效性吗?@RajorshiMukherjee您希望所有属性都不能为NULL,并且所有四个属性都必须始终有一个值?因为,
条件将得到满足,即使其中一个为null。如果您的要求是所有字段都必须有一个值,那么您的方法很好。为什么不删除默认的NULL并将它们改为notnull呢?