尝试使用合并更新表时出现ORA-38104

时间:2019-09-12 07:54:01

标签: sql oracle sql-merge

我有一个存储过程,我想在其中更新一些列,所以我写了下面的代码:

PROCEDURE UPDATE_MST_INFO_BKC (
    P_SAPID IN   NVARCHAR2
) AS
BEGIN
    MERGE INTO tbl_ipcolo_billing_mst I 
    USING (
            SELECT
                R4G_STATE,                        -- poilitical state name
                R4G_STATECODE,                    -- poilitical state code
                CIRCLE,                           -- city name                                                            
                NE_ID,
                LATITUDE,
                LONGITUDE,
                SAP_ID

            FROM
                R4G_OSP.ENODEB
            WHERE
                SAP_ID = P_SAPID
                AND ROWNUM = 1
            )
    O ON ( I.SAP_ID = O.SAP_ID )
    WHEN MATCHED THEN 
    UPDATE SET I.POLITICAL_STATE_NAME = O.R4G_STATE,
               I.POLITICAL_STATE_CODE = O.R4G_STATECODE,
                I.CITY_NAME = O.CIRCLE,
                I.NEID = O.NE_ID,
                I.FACILITY_LATITUDE = O.LATITUDE,
                I.FACILITY_LONGITUDE = O.LONGITUDE,
                I.SAP_ID = O.SAP_ID;               

END UPDATE_MST_INFO_BKC;

但这给了我错误

  

ORA-38104:不能更新ON子句中引用的列:“ I”。“ SAP_ID”

我在做什么错了?

2 个答案:

答案 0 :(得分:4)

您正在将源表连接到I.SAP_ID = O.SAP_ID上的目标表,然后在匹配时尝试更新它们并设置I.SAP_ID = O.SAP_ID。您无法更新联接中使用的列...以及为什么要这样做,因为您已经确定值相等。

只需删除UPDATE的最后一行:

...
O ON ( I.SAP_ID = O.SAP_ID )
WHEN MATCHED THEN 
UPDATE SET I.POLITICAL_STATE_NAME = O.R4G_STATE,
           I.POLITICAL_STATE_CODE = O.R4G_STATECODE,
           I.CITY_NAME = O.CIRCLE,
           I.NEID = O.NE_ID,
           I.FACILITY_LATITUDE = O.LATITUDE,
           I.FACILITY_LONGITUDE = O.LONGITUDE;

答案 1 :(得分:3)

错误消息告诉您问题是什么-MERGE语句无法更新ON子句中使用的列-甚至告诉您问题出在哪一列:"I"."SAP_ID"

由于在您的WHEN MATCHED分支中有此行,因此Oracle催促ORA-38104

I.SAP_ID = O.SAP_ID; 

将其删除,您的问题就消失了。幸运的是,该行是不必要的:I.SAP_ID已经等于O.SAP_ID,否则该记录就不会在MATCHED分支下进行。

原因很简单:事务一致性。 MERGE语句对由USING子句和ON子句定义的一组记录进行操作。更新ON子句中使用的列会威胁到该集合的完整性,因此Oracle禁止这样做。