如何在合并语句中插入子查询的值

How to insert values from a subquery in merge sentence

我想在 ORACLE 的存储过程的合并语句中插入一个来自子查询的值。我怎样才能做到这一点?这是我设计的,但它不起作用。

CREATE OR REPLACE PROCEDURE P_FORMULARIO
IS
BEGIN 
    MERGE INTO HT_FORMULARIO d
    USING
    (SELECT id, METODO_ID, TIPO_ID, DEPARTAMENTO_ID, EQUIPAMEINTO_ID, FECHAINICIO 
        FROM ODS_FORMULARIO) o
    ON  (d.ID_CAMPO = o.id)
    WHEN MATCHED THEN
        UPDATE SET d.SK_METODO_MUEST = o.METODO_ID,
        d.SK_TIPO_MUESTRA = o.TIPO_ID,
        d.SK_DEPARTAMENTO = o.DEPARTAMENTO_ID,
        d.SK_EQUIPAMIENTO = o.EQUIPAMEINTO_ID
    WHEN NOT MATCHED THEN
        INSERT (ID_CAMPO, SK_METODO_MUEST, SK_TIPO_MUESTRA, SK_DEPARTAMENTO, SK_EQUIPAMIENTO)
        VALUES (o.id, o.METODO_ID, o.TIPO_ID,o.DEPARTAMENTO_ID, o.EQUIPAMEINTO_ID, 
            (select SK_FECHA from dt_fecha where mes = MONTH( o.FECHAINICIO) and anio = YEAR(o.FECHAINICIO));
    COMMIT;
END P_EQUIPAMIENTO;

不知道可不可以,谢谢帮助

你的程序有些问题

  • 插入下方的 subselect 没有任何意义,因为插入子句中只有五个字段,values 部分中只有五个值。
  • 您正在从 ODS_FORMULARIO 获取与目标 table HT_FORMULARIO 匹配的所有记录,基于 ID,然后使用该部分获取值那里的年月。​​
  • 不清楚您是否要使用 yearmonth。这些是 java 内置函数,而不是 SQL。
  • 插入遗漏了一个字段。

您的函数在 SQL 中不起作用:

SQL> select month(sysdate) from dual ;
select month(sysdate) from dual
       *
ERROR at line 1:
ORA-00904: "MONTH": invalid identifier

SQL> select year(sysdate) from dual ;
select year(sysdate) from dual
       *
ERROR at line 1:
ORA-00904: "YEAR": invalid identifier

请记住从 dt_fecha table 获取今年和月份的方法,您可能有一些选择:

SQL> select to_char(sysdate,'Month') from dual ;

TO_CHAR(SYSDATE,'MONTH')
------------------------------------
October

SQL> select to_char(sysdate,'YYYY') from dual ;

TO_C
----
2021

SQL> select extract(month from sysdate) from dual ;

EXTRACT(MONTHFROMSYSDATE)
-------------------------
                       10

SQL>  select extract(year from sysdate) from dual ;

EXTRACT(YEARFROMSYSDATE)
------------------------
                    2021

然后您在 table DT_FECHA 中有列 MES。如果你有名字的月份商店,你需要使用 NLS_LANGUAGE 来根据你的语言获得正确的名字。例如,德语

SQL> select TO_CHAR(SYSDATE,'fmDay, DD Month YYYY', 'NLS_DATE_LANGUAGE=''GERMAN''') from dual;

TO_CHAR(SYSDATE,'FMDAY,DDMONTHYYYY','NLS_DATE_LANGUAGE=''GERMAN''')
--------------------------------------------------------------------------------
Samstag, 16 Oktober 2021

话虽如此,您想重构合并并在语句的源部分使用联接来获得 sk_fecha 值。

重要提示:请记住,我假设了一些事情,比如月份以西班牙语存储,而不是以大写形式存储。如果是大写存储,在to_char之前使用函数upper。如果是另一种语言,请使用正确的 nls_language。如果月份存储为数字,则可以将 to_char'MM'extract 一起使用,如我上面的示例

CREATE OR REPLACE PROCEDURE P_FORMULARIO
IS
begin 
    MERGE INTO HT_FORMULARIO d
    USING
    (SELECT 
       odsf.id, 
       odsf.METODO_ID, 
       odsf.TIPO_ID, 
       odsf.DEPARTAMENTO_ID, 
       odsf.EQUIPAMEINTO_ID, 
       odsf.FECHAINICIO, 
       to_char(odsf.FECHAINICIO,'Month', 'NLS_DATE_LANGUAGE=''SPANISH''') as Month, 
       to_char(odsf.FECHAINICIO,'YYYY') as Year , 
       dtf.sk_fecha 
        FROM ODS_FORMULARIO odsf 
                    join dt_fecha dft on dtf.mes = odsf.mes and dtf.anio = odsf.year ) o
    ON  (d.ID_CAMPO = o.id)
    WHEN MATCHED THEN
        UPDATE SET d.SK_METODO_MUEST = o.METODO_ID,
        d.SK_TIPO_MUESTRA = o.TIPO_ID,
        d.SK_DEPARTAMENTO = o.DEPARTAMENTO_ID,
        d.SK_EQUIPAMIENTO = o.EQUIPAMEINTO_ID
    WHEN NOT MATCHED THEN
        INSERT (ID_CAMPO, SK_METODO_MUEST, SK_TIPO_MUESTRA, SK_DEPARTAMENTO, SK_EQUIPAMIENTO , --a field here is missing--)
        VALUES (o.id, o.METODO_ID, o.TIPO_ID,o.DEPARTAMENTO_ID, o.EQUIPAMEINTO_ID, o.SK_FECHA );
    COMMIT;
END P_EQUIPAMIENTO;