【问题标题】:How to prevent update statement from setting some records to null?如何防止更新语句将某些记录设置为空?
【发布时间】:2018-06-12 00:26:45
【问题描述】:

我正在尝试使用下面的查询在一个包含现有表的表上运行更新。代码列记录需要更新,但只更新其中的一部分。我的查询似乎有效,但任何应该留在代码列中的记录最终都被设置为 NULL。如何修改此查询以保持这些记录不变?

查询

update t1 x
set x.code =
(select code from
(select distinct address, city, prov, aflag, rcode from t2) y
where x.address = y.address and x.city = y.city and x.state = y.state and x.flag = y.flag)
where x.aflag like '%b%';

表 1:要更新的代码

   t1               
address city    state   flag    code
123      aaa      il     b       400
567      bbb      il     b       400
345      bbb      il     b      -500
789      ddd      il     b       600
546      ccc      il     b       700

表 2:用于更新 T1 的代码列

t2              
address city    state   flag    code
   123   aaa      il      b     -555
   444   bbb      il      b     -555
   345   bbb      il      b     -555
   888   kkk      il      b     -555
   546   ccc      il      b     -555



What the query currently outputs

     current output             
    address city    state   flag    code
       123   aaa      il      b     400
       444   bbb      il      b     NULL
       345   bbb      il      b     -500
       888   kkk      il      b     NULL
       546   ccc      il      b     -700

我希望查询保留与更新表中没有匹配项的记录保持不变,如下所示

  What I want               
address city    state   flag    code
  123    aaa      il      b     400
  444    bbb      il      b    -555
  345    bbb      il      b    -500
  888    kkk      il      b    -555
  546    ccc      il      b    -700

谢谢!

【问题讨论】:

  • 和 where 子句说明代码不为空的地方
  • 你说你想更新 t1 但你显示的地址来自 t2 ??

标签: sql oracle sql-update


【解决方案1】:

最好的办法是在where子句中使用exists

update t1 x
    set x.code = (select code
                  from t2 y
                  where x.address = y.address and x.city = y.city and x.state = y.state and x.flag = y.flag and rownum = 1
                 )
    where x.aflag like '%b%' and
          exists (select code
                  from t2 y
                  where x.address = y.address and x.city = y.city and x.state = y.state and x.flag = y.flag and rownum = 1
                 );

【讨论】:

    【解决方案2】:

    t2 都会告诉您要更新哪些行以及使用哪个值。为此,请编写一个可更新的查询:

    update
    (
      select t1.code, t2.code as new_code
      from t1
      join t2 on  t2.address = t1.address
              and t2.city    = t1.city city 
              and t2.state   = t1.state
              and t2.flag    = t1.flag
      where t1.flag like '%b%'
    )
    set code = new_code;
    

    为此,address, city, state, flagt2 中必须是唯一的,因此 DBMS 知道它正在获取一条包含更新数据的记录。

    顺便说一下,对于要更新多个列的情况,可更新表查询特别有用。

    【讨论】:

      【解决方案3】:

      有些人喜欢,有些人不喜欢。它看起来与您最初的更新声明惊人地相似:

      MERGE INTO t1 x
      USING (SELECT DISTINCT address, city, state, flag, code from t2) y
         ON (x.address = y.address AND x.city = y.city AND x.state = y.state AND x.flag = y.flag)
       WHEN MATCHED THEN 
            UPDATE SET x.code = y.code
             WHERE x.flag LIKE '%b%';
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多