过程包体中的 Oracle Merge 语句错误

Posted

技术标签:

【中文标题】过程包体中的 Oracle Merge 语句错误【英文标题】:Oracle Merge statement error in procedure package body 【发布时间】:2016-03-08 03:18:39 【问题描述】:

我正在努力使这个过程正常工作,我的包体内有以下代码:

PACKAGE BODY PKG_DM_TRANS_DIMENSIONES AS

          PROCEDURE SP_DM_TRANS_DIM_CUENTA AS

        vNumRegistrosDimCuentas NUMBER; 

          BEGIN
            SELECT COUNT(*) INTO vNumRegistrosDimCuentas
            FROM DIM_CUENTAS;

            IF (vNumRegistrosDimCuentas <> 0) THEN

              MERGE INTO DIM_CUENTAS DIMC
              USING (
                SELECT * FROM (
                  SELECT 
                    DIM.FNT_CUENTA_ID AS DIM_CUENTA_ID,
                    C.CUE_ID AS FNT_CUENTA_ID,
                    R.REG_REGION AS REGION, 
                    P.PAI_PAIS AS PAIS, 
                    E.EDI_NOMBRE_EDIFICIO AS EDIFICIO,
                    C.CUE_CUENTA, 
                    TIC.TIC_TIPO_CONTACTO,
                    C.CUE_STATUS,
                    CASE 
                      WHEN DIM.FNT_CUENTA_ID IS NULL THEN 1
                      WHEN 
                        R.REG_REGION <> DIM.REGION OR
                        P.PAI_PAIS <> DIM.PAIS OR
                        E.EDI_NOMBRE_EDIFICIO <> DIM.EDIFICIO OR
                        C.CUE_CUENTA <> DIM.CUENTA OR
                        TIC.TIC_TIPO_CONTACTO <> DIM.TIPO_CONTACTO
                      THEN 2
                      ELSE 0
                    END AS TIPO_FILA

                  FROM STA_EDIFICios_EXTRACCION E

                    LEFT JOIN 
                    STA_PAISES_EXTRACCION P ON E.EDI_PAI_ID = P.PAI_ID
                    LEFT JOIN
                    STA_REGIONES_EXTRACCION R ON P.PAI_REG_ID = R.REG_ID
                    LEFT JOIN 
                    EUB_EDIFICIO_UBICACION EUB ON EUB.EUB_EDI_ID = E.EDI_ID
                    LEFT JOIN 
                    STA_CUENTAS_EXTRACCION C ON C.CUE_EUB_ID = EUB.EUB_ID
                    LEFT JOIN 
                    STA_TIPOS_CONTACTO_EXTRACCION TIC ON TIC.TIC_ID = C.CUE_TIC_ID
                    LEFT JOIN
                      DIM_CUENTAS DIM ON
                    (C.CUE_ID = DIM.FNT_CUENTA_ID AND DIM.CUENTA_STATUS = 1)
                  )
              ) Q
              ON (DIMC.FNT_CUENTA_ID = Q.TIPO_FILA)
              WHEN MATCHED THEN
                INSERT (DIMC.REGION, DIMC.PAIS, DIMC.EDIFICIO, DIMC.CUENTA, DIMC.TIPO_CONTACTO, DIMC.CUENTA_FECHA_CREACION, DIMC.FNT_CUENTA_ID)
                VALUES (Q.REGION, Q.PAIS, Q.EDIFICIO, Q.CUE_CUENTA, Q.TIC_TIPO_CONTACTO, TO_TIMESTAMP(sysdate, 'MM/DD/YYYY HH24:MI:SS'), Q.FNT_CUENTA_ID)
              WHEN NOT MATCHED THEN

                 UPDATE SET DIMC.CUENTA_STATUS = 0 WHERE DIMC.CUENTA_STATUS = 1 -- <- dummy update stmt 

            ELSE ..... -- else statement code working fine...
        END IF;
      END SP_DM_TRANS_DIM_CUENTA;

END PKG_DM_TRANS_DIMENSIONES;

我在线路上遇到错误

MERGE INTO DIM_CUENTAS DIMC

说“声明被忽略”

然后,另一个错误:

INSERT (DIMC.REGION, DIMC.PAIS, DIMC.EDIFICIO, DIMC.CUENTA, DIMC.TIPO_CONTACTO, DIMC.CUENTA_FECHA_CREACION, DIMC.FNT_CUENTA_ID)
        VALUES (Q.REGION, Q.PAIS, Q.EDIFICIO, Q.CUE_CUENTA, Q.TIC_TIPO_CONTACTO, TO_TIMESTAMP(sysdate, 'MM/DD/YYYY HH24:MI:SS'), Q.FNT_CUENTA_ID)

说“缺少关键字”。是否可以在 SP 中使用合并语句?我是 Oracle 的新手,所以我真的不知道我正在尝试做的事情是否可行,或者我的代码是否有问题。

感谢您的帮助,我真的很感激。

【问题讨论】:

【参考方案1】:

我认为你交换了命令 - 在 when matched 之后你应该把 update 语句和 not matched 之后 - insert。 类似的例子对我有用,但在交换语句后我得到了ORA-00905 missing keyword。所以正确的版本是:

merge into t1 
using (select * from t2) t2 on (t1.id = t2.id)
when matched then update set t1.name = t2.name
when not matched then insert (id, name) values (t2.id, t2.name)

【讨论】:

以上是关于过程包体中的 Oracle Merge 语句错误的主要内容,如果未能解决你的问题,请参考以下文章

如何从 oracle pl sql 中的包主体内的 select 语句中捕获特定列

包和包体简介

PL/SQL Oracle 包错误

PLSQL——08包

达梦数据库的过程包使用

如何使用 out sys_refcursor 参数执行 oracle 过程?