【问题标题】:ORA-01407: cannot update ("SYSADM"."PS_LM_ENRLMT"."LM_ACT_ID") to NULLORA-01407: 无法将 ("SYSADM"."PS_LM_ENRLMT"."LM_ACT_ID") 更新为 NULL
【发布时间】:2015-04-01 09:21:12
【问题描述】:

大家好,

我在尝试运行以下查询时收到此错误。

Update PS_LM_ENRLMT A
Set A.LM_ACT_ID = (Select B.LM_ACT_ID FROM PS_LM_ACT B                                                                                 
               where B.LM_ACT_ID = A.LM_ACT_ID                     
               And B.LM_ROW_ADDED_DTTM < '09-DEC-13 05.35.35.000000 PM'        
               AND A.LM_ACT_ID = 1166            
               And A.LM_CI_ID!= 1196)

为避免 Null 错误,我将查询更新如下:

Update PS_LM_ENRLMT A                                

Set A.LM_ACT_ID = (Select B.LM_ACT_ID FROM PS_LM_ACT B       
               where B.LM_ACT_ID = A.LM_ACT_ID        
               And B.LM_ROW_ADDED_DTTM < '09-DEC-13 05.35.35.000000 PM'          
               AND A.LM_ACT_ID = 1166           
               And A.LM_CI_ID!= 1196)           
where exists      
(Select B.LM_ACT_ID FROM PS_LM_ACT B                              
               where B.LM_ACT_ID = A.LM_ACT_ID         
               And B.LM_ROW_ADDED_DTTM < '09-DEC-13 05.35.35.000000 PM'          
               AND A.LM_ACT_ID = 1166          
               And A.LM_CI_ID!= 1196)

查询成功运行,但没有更新任何数据。我无法找到原因。谁能帮忙。

谢谢, 阿杰

【问题讨论】:

  • 您的子查询没有返回行。我会从那里开始
  • PS_LM_ENRLMT 是如何创建的?我猜A.LM_ACT_ID 列不能为空...注意:您的第一条语句将更改表中的所有值;第二个要么全部要么没有

标签: sql oracle


【解决方案1】:

听起来主表中没有子查询为其返回结果的行。因此,您的第一条语句尝试将所有行更新为 NULL,可能违反了对表的约束;并且您的第二条语句没有更新任何行,因为所有行都被 EXISTS 条件过滤掉了。

基本上,您需要查看数据和查询并找出出现这种情况的原因。但是,您的查询中存在一个明显的潜在问题:

And B.LM_ROW_ADDED_DTTM < '09-DEC-13 05.35.35.000000 PM'

这看起来像是在将 DATE 或 TIMESTAMP 列与字符串进行比较,这意味着列值将隐式转换为字符串,使用会话的 NLS_DATE_FORMAT 进行比较。如果 NLS_DATE_FORMAT 与您用于字符串的格式不匹配,则结果将相当不可预测。在这种情况下,即使使用的格式是您所期望的,我怀疑结果是否会是您想要的,因为比较该格式的字符串不会产生与比较等效日期相同的结果。 (例如,“08-DEC-14”在词汇上小于“09-DEC-13”,尽管它表示几乎一年后的日期。

最好使用日期或时间戳字面量,这样就不会发生类型转换:

And B.LM_ROW_ADDED_DTTM < TIMESTAMP '2013-13-09 17:35:35.000'

(如果该列实际上是一个字符串,采用所需的格式,那么字符串的比较与等效日期值的比较仍然是不一样的。)

编辑添加 仔细看了一下,更新完全没有意义。子查询需要B.LM_ACT_ID = A.LM_ACT_ID,然后如果找到一行,则将 A.LM_ACT_ID 更新为 B.LM_ACT_ID 中的值 - 根据定义,该值是相同的值。因此,如果这确实更新了任何行,它只会将它们设置为它们已经拥有的相同值。看起来你需要重新评估你想要做什么。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-01-19
    • 2021-03-19
    • 1970-01-01
    • 2019-12-31
    • 2010-12-26
    • 2012-07-16
    • 2017-09-01
    • 2014-08-17
    相关资源
    最近更新 更多