【问题标题】:Unix Sql -- Updating One table from a 2nd table -- null value issueUnix Sql——从第二个表更新一个表——空值问题
【发布时间】:2016-02-18 19:56:53
【问题描述】:

我已经在网上浏览了几个小时,试图确定我的代码有什么问题。我不断收到 ORA-01407: cannot update ("AMIOWN"."MEMBER"."LANGUAGE_X") 为 NULL。当合同表中的语言不为空时,我需要更新成员表中的语言。需要第三张表才能深入了解特定成员。下面是代码:

update member m
    set language_x =
    (select language_x
        from contract c
        where m.contract_nbr  = c.contract_nbr and
        c.language_x is not null and
        m.member_nbr =
        (select member_nbr
            from member_span ms
            where m.member_nbr = ms.member_nbr and
            ms.void     = ' ' and
            ms.carrier  = 'PM' and
            ms.prog_nbr = 'GP' and
            ms.region   = 'TR' and
            (ms.ymdeff <= 20160218 or ms.ymdeff > 20160218) and
            ms.ymdend > 20160218
        )
    );

一些帖子还建议在最后一个括号检查后添加另一行:

在哪里存在(从合约 c 中选择 1,其中 m.contract_nbr = c.contract_nbr 和 c.language_x 不为空);

我在 unix 环境中工作,表包含在 amisys 数据库中。

感谢您的任何建议。

【问题讨论】:

  • 几乎可以肯定有比使用所有这些子选择更好的方法来编写查询。如果没有看到您的数据结构或示例数据等,即使尝试也是不可能的。此外,如果没有看到任何数据,就不可能知道问题出在哪里,只能说可能没有符合您条件的行。如果根本找不到匹配项,则在子选择中使用 c.language_x is not null 将无助于避免该问题。
  • 有符合条件的记录。在编写代码之前分析了所有数据。
  • 我想每个人都必须相信你的话,

标签: sql oracle


【解决方案1】:

您需要在更新语句中添加 where 条件

update member m
    set language_x = (select language_x
                        from contract c
                       where m.contract_nbr  = c.contract_nbr 
                         and c.language_x is not null 
                         and m.member_nbr = (select member_nbr
                                              from member_span ms
                                             where m.member_nbr = ms.member_nbr 
                                               and ms.void     = ' ' 
                                               and ms.carrier  = 'PM' 
                                               and ms.prog_nbr = 'GP' 
                                               and ms.region   = 'TR' 
                                               and (ms.ymdeff <= 20160218 or ms.ymdeff > 20160218) 
                                               and ms.ymdend > 20160218)
    )
    where exists (select language_x
                        from contract c
                       where m.contract_nbr  = c.contract_nbr 
                         and c.language_x is not null 
                         and m.member_nbr = (select member_nbr
                                              from member_span ms
                                             where m.member_nbr = ms.member_nbr 
                                               and ms.void     = ' ' 
                                               and ms.carrier  = 'PM' 
                                               and ms.prog_nbr = 'GP' 
                                               and ms.region   = 'TR' 
                                               and (ms.ymdeff <= 20160218 or ms.ymdeff > 20160218) 
                                               and ms.ymdend > 20160218)
    );

下面是一个更优雅的解决方案,但取决于您的数据模型,它可能会或可能不会工作

Update    
(
select m.language_x as oldval 
       c.language_x as newval
  from member m
      ,contract c
where m.contract_nbr  = c.contract_nbr 
  and c.language_x is not null 
  and m.member_nbr = (select member_nbr
                        from member_span ms
                       where m.member_nbr = ms.member_nbr 
                         and ms.void     = ' ' 
                         and ms.carrier  = 'PM' 
                         and ms.prog_nbr = 'GP' 
                         and ms.region   = 'TR' 
                         and (ms.ymdeff <= 20160218 or ms.ymdeff > 20160218) 
                         and ms.ymdend > 20160218)
) t
set t.oldval =t.newval 

【讨论】:

  • 感谢您的帮助。我尝试了两种方法。您在第二个查询中是正确的,因为它不会在我们的环境 ORA-01779 中运行。第一个选项是运行,虽然有点慢,但这可能与我们的 DEV 环境有关,因为它比 PROD 慢得多。我将继续处理代码,看看是否可以对其进行微调。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-17
  • 1970-01-01
相关资源
最近更新 更多