【问题标题】:Updating a column automatically, when another column is updated in a table当表中的另一列更新时自动更新列
【发布时间】:2013-08-26 04:49:26
【问题描述】:

表名:User_table

Uname       pwd          expire_date          update_pwd_date
-------------------------------------------------------------
aaa         aaa          30-AUG-2013           null
bbb         bbb          01-SEP-2013           null
ccc         ccc          15-sep-2013           null
ddd         ddd          29-SEP-2013           null

所以当我们要更新pwd 列时,它应该自动将update_pwd_date 列更新为当前日期(sysdate)。

我想要这样的输出:

Uname       pwd          expire_date          update_pwd_date
-------------------------------------------------------------
aaa         eee          30-AUG-2013           23-AUG-2013
bbb         fff          01-SEP-2013           23-AUG-2013
ccc         ggg          15-sep-2013           23-AUG-2013
ddd         hhh          29-SEP-2013           23-AUG-2013

实际上我正在尝试使用下面的触发器。但它不起作用。

create or replace trigger user_trg
before update of pwd
on user_tab
for each row
declare
Pragma autonomous_transaction;
begin
update user_tab set pas_update=sys date where pwd=:new.pwd;
commit;
end;

实际上我正在尝试低于触发器。但它不起作用。

创建或替换触发器用户_trg 在 user_tab 上更新 pwd 之前 对于每一行 宣布 Pragma自治事务; 开始 更新 user_tab set pas_update=sys date where pwd=:new.pwd`; 犯罪; 结束;

请问有人可以为这个查询提供解决方案吗?

【问题讨论】:

    标签: sql oracle triggers


    【解决方案1】:

    我认为其他答案将为您提供触发器所需的内容。

    我不喜欢触发器。很多。并不是说它们不起作用,而是它们经常被忽视或忘记依赖关系。简而言之,他们是魔鬼。

    也许我可以说服你尝试不同的方式。

    您已经在编写 PL/SQL,为什么不创建一个 API(包)?其实很简单。

    create or replace
    package maintain_user_table
    as
      procedure update_user_pwd( p_uname in varchar2, p_new_pwd in varchar2 );
    end;
    /
    

    假设: 1.uname是个PK

    create or replace
    package body maintain_user_table
    as
      procedure update_user_pwd( p_uname in varchar2, p_new_pwd in varchar2 )
      is
      begin
        --error checking can go here
        update user_table
          set pwd = p_new_pwd
            update_pwd_date = SYSDATE
        where uname = p_uname;
    
        if sql%rowcount = 1 then
          --update successful
        else if sql%rowcount = 0 then
          --no rows found
        else
          --more than one row updated, not good, probably rollback or something
        end if;
      end update_user_pwd;
    end;
    /
    

    这将使您能够更严格地控​​制数据的质量。将特定表从除此过程之外的任何内容中对 UPDATE/INSERT/DELETE 开放意味着您只是希望每个人都遵循此特定规则(这就是触发器是必要的原因)。卸下触发器。关闭对该表的访问并强制人员/应用程序使用 PL/SQL API。

    只是需要考虑的事情......

    【讨论】:

      【解决方案2】:

      如果您要更新同一表/行中正在更新的列,则不应使用 UPDATE 语句。只需使用新值设置列。

      :new.update_pwd_date := sysdate;
      

      此外,不需要 pragma 自主事务或 COMMIT。

      【讨论】:

        【解决方案3】:

        试试这个,

        CREATE OR REPLACE 
        TRIGGER user_trg 
             BEFORE UPDATE OF pwd ON user_tab 
             FOR EACH row 
        BEGIN
             :new.update_pwd_date := sysdate;
        END;
        

        【讨论】:

          猜你喜欢
          • 2016-11-30
          • 1970-01-01
          • 2021-06-20
          • 2011-02-10
          • 1970-01-01
          • 2018-01-12
          • 2016-05-15
          • 2019-07-25
          • 1970-01-01
          相关资源
          最近更新 更多