【问题标题】:Oracle: multiple table updates => ORA-01779: cannot modify a column which maps to a non key-preserved tableOracle:多个表更新 => ORA-01779:无法修改映射到非键保留表的列
【发布时间】:2023-03-20 20:22:02
【问题描述】:

我已经在表格之间建立了连接。我只是想从一些数据中获取值并放入其他列。但它不起作用。 我怎样才能重写查询? 我想用 swkf 中的值覆盖 wkfc 表中的值。

我知道这是对的,我怎样才能让 Oracle 简单地做到这一点?

UPDATE (
SELECT --FROM
       swkf.swkf_stato_workflow_id "swkf_swkf_stato_workflow_id", 
       swkf.swkf_data_ini "swkf_swkf_data_ini",
       swkf.swkf_versione "swkf_swkf_versione",
       swkf.spwkf_stato_pubblico_id "swkf_spwkf_stato_pubblico_id",
       swkf.spwkf_data_ini "swkf_spwkf_data_ini",
       swkf.spwkf_versione "swkf_spwkf_versione",
       --TO
       wkfc.swkf_stato_workflow_id "wkfc_swkf_stato_workflow_id", 
       wkfc.swkf_data_ini "wkfc_swkf_data_ini",
       wkfc.swkf_versione "wkfc_swkf_versione",
       wkfc.spwkf_stato_pubblico_id "wkfc_spwkf_stato_pubblico_id",
       wkfc.spwkf_data_ini "wkfc_spwkf_data_ini",
       wkfc.spwkf_versione "wkfc_spwkf_versione"
       --
  FROM wkfb_stati_workflow swkf, wkf_cronologia wkfc
 WHERE twkf_tipo_workflow_id =
          (SELECT twkf_tipo_workflow_id
             FROM wkf_istanze_workflow wkfi, RET_PUNTI_EROGAZIONE RPUN
            WHERE     RPUN.PUN_PUNTO_EROGAZIONE_COD = '8001375567' --codice puntero
                  AND RPUN.PUN_PUNTO_EROGAZIONE_ID = wkfi.ogg_oggetto_id
                  AND wkfi.tog_tipo_oggetto_id = 'RET_PUN1'
                  AND wkfi.WKFI_FLAG_ANN = 'N')
       AND swkf_descrizione = '(O)Occupato'
       AND wkfc.wkfc_cronologia_id = 'ApAJ0qCudNphjLxj'
  )  a1
set 
"wkfc_swkf_stato_workflow_id" =  "swkf_swkf_stato_workflow_id" ,
"wkfc_swkf_data_ini" =           "swkf_swkf_data_ini" ,
"wkfc_swkf_versione" =           "swkf_swkf_versione"  ,
"wkfc_spwkf_stato_pubblico_id" = "swkf_spwkf_stato_pubblico_id" , 
"wkfc_spwkf_data_ini" =          "swkf_spwkf_data_ini" ,
"wkfc_spwkf_versione" =          "swkf_spwkf_versione"  ;

跟follow的一样,但是他要自己找值。

UPDATE wkf_cronologia
   SET swkf_stato_workflow_id = 'o3gE1tlSdcDIC6FF',
       swkf_data_ini = TO_TIMESTAMP ('19-06-2010 18:28:10,556000000','DD-MM-RRRR HH24:MI:SS,FF'),
       swkf_versione = 0, 
       SPWKF_STATO_PUBBLICO_ID = '*1UNICOO',
       SPWKF_DATA_INI = TO_TIMESTAMP ('01-01-0001 00:00:00,000000000', 'DD-MM-RRRR HH24:MI:SS,FF'),
       SPWKF_VERSIONE = 0
 WHERE wkfc_cronologia_id = 'ApAJ0qCudNphjLxj';  --id del record di cronologia da aggiornare (estratto nella prima query)

【问题讨论】:

  • 我在您的表之间看不到任何连接条件。 wkfb_stati_workflow、wkf_cronologia、wkf_istanze_workflow 和 RET_PUNTI_EROGAZIONE 表是如何关联的?
  • 他们不是。我需要从 swkf 中获取唯一值并使用它们来更新 wkf_cronologia。哪个是最好的方法?

标签: sql oracle sql-update


【解决方案1】:

如果您想UPDATE (SELECT ... FROM A INNER JOIN B ON condition) SET A.X = ...,则连接条件必须将 B 上具有某些唯一性约束的所有列约束为单个值。

【讨论】:

    【解决方案2】:

    首先,我们不能通过连接视图使用单个查询更新两个表,在这种情况下我们可以选择 DB 过程。

     ORA-01776: cannot modify more than one base table through a join view
       01776. 00000 -  "cannot modify more than one base table through a join view"
       *Cause:    Columns belonging to more than one underlying table were either
             inserted into or updated. 
    

    但是我们可以使用连接来比较基表和参考表,我们可以更新一张表。

    UPDATE
    (
        SELECT t1.d1 x, t2.d1 y FROM t1, t2 WHERE t1.d2 = t2.d2 AND t2.d2 = 2
    ) t3
    
    SET t3.x = 6;
     -- t3.y = 1; this is wrong updating multiple table
    

    现在应该在唯一列上执行此连接 (t1.d2 = t2.d2)。 这里两个表 d2 列应该是唯一的。

    其他结果如下

     Oracle: multiple table updates => ORA-01779: 
     cannot modify a column which maps to a non key-preserved table
    


    下面的 URL 解释了如何在非唯一列上执行此连接

    Oracle - update join - non key-preserved table

    【讨论】:

      猜你喜欢
      • 2013-06-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-19
      • 1970-01-01
      • 1970-01-01
      • 2019-05-05
      相关资源
      最近更新 更多