Re: Merge clause retrieves ORA-00923 FROM keyword not found where expected

From: Jorge Reyes <jorg_reyes_at_hotmail.com>
Date: Wed, 22 Apr 2009 14:19:01 -0700 (PDT)
Message-ID: <3267e7f4-f71f-445c-9075-96271816bdd6_at_q19g2000vbn.googlegroups.com>



On 22 abr, 15:21, Shakespeare <what..._at_xs4all.nl> wrote:
> Jorge Reyes schreef:
>
>
>
>
>
> > Hi everyone,
>
> > Using the MERGE clause i want to be able to update/insert records each
> > 15 minutes, so i probe each segment of this code and its working, in
> > fact the segment with the MERGE works perfect replacing the
> > vPMM_DATETIME and vEND_DATETIME variables for constants, but (and its
> > driving me crazy!!!) when i probe this huge query, i get the error:
>
> > Error: ORA-00923: FROM keyword not found where expected
> > ORA-06512: at line 63, Batch 1 Line 1 Col 1
>
> > Line 63 is the MERGE INTO OM_DB.CDRS_VALIDOS "X", so whats
> > happening??? because each segment of the code works if i probe one by
> > one!!, please some help!!!
>
> > Code:
>
> > DECLARE
> > vPMM_DATETIME TIMESTAMP(3);
> > vMAX_PMM_DATETIME TIMESTAMP(3);
> > vEND_DATETIME TIMESTAMP(3);
> > v_rows_processed INT;
> > count_violated INT;
> > BEGIN
> > dbms_output.enable(40000);
> > dbms_output.put_line('Inicio de procedimiento: ' || TO_CHAR
> > (sysdate, 'YYYY-MM-DD HH24:MI:SS'));
>
> > -- Valida si existe informacion en la tabla de origen
> > --
> > *****************************************************************************
> > count_violated := 0;
> > SELECT COUNT(START_TIME) INTO count_violated FROM
> > OM_DB.CDRS_PRUEBA;
> > IF (count_violated=0) THEN
> > dbms_output.put_line('No hay informacion en la tabla de
> > origen');
> > ELSE
> > SELECT TO_DATE(TO_CHAR(MIN(START_TIME),'YYYY-MM-DD HH24') || ':
> > 00:00','YYYY-MM-DD HH24:MI:SS')
> > INTO vPMM_DATETIME
> > FROM OM_DB.CDRS_PRUEBA;
>
> > vEND_DATETIME := vPMM_DATETIME + 1/24;
>
> > SELECT TO_DATE(TO_CHAR(MAX(START_TIME),'YYYY-MM-DD HH24') || ':
> > 59:59','YYYY-MM-DD HH24:MI:SS')
> > INTO vMAX_PMM_DATETIME
> > FROM om_db.CDRS_PRUEBA;
>
> > WHILE (vPMM_DATETIME <= vMAX_PMM_DATETIME) LOOP
> > MERGE INTO OM_DB.CDRS_VALIDOS "X"
> > USING (
> > SELECT
> > DISTINCT(ESTADO) AS "ESTADO",
> > MUNICIPIO,
> > CALL_SOURCE_REGID,
> > SUM(EXITOSOS) AS "EXITOSOS",
> > SUM(NO_EXITOSOS) AS "NO_EXITOSOS",
> > SUM(NO_CONECT) AS "NO_CONECT",
> > PMM_DATETIME
> > FROM (
> > SELECT
> > COALESCE(V_EXITOSOS.ESTADO,
> > V_NO_EXITOSOS.ESTADO, V_NO_CONECT.ESTADO) AS "ESTADO",
> > COALESCE(V_EXITOSOS.MUNICIPIO,
> > V_NO_EXITOSOS.MUNICIPIO, V_NO_CONECT.MUNICIPIO) AS "MUNICIPIO",
> > COALESCE(V_EXITOSOS.CALL_SOURCE_REGID,
> > V_NO_EXITOSOS.CALL_SOURCE_REGID, V_NO_CONECT.CALL_SOURCE_REGID) AS
> > "CALL_SOURCE_REGID",
> > COALESCE(V_EXITOSOS.EXITOSOS,0) AS "EXITOSOS",
> > COALESCE(V_NO_EXITOSOS.NO_EXITOSOS,0) AS
> > "NO_EXITOSOS",
> > COALESCE(V_NO_CONECT.NO_CONECT,0) AS
> > "NO_CONECT",
> > '2009-03-17 17:00:00' AS "PMM_DATETIME"
> > FROM
> > (
> > SELECT
> > DISTINCT(ESTADO) AS "ESTADO",
> > MUNICIPIO,
> > CALL_SOURCE_REGID,
> > COUNT(CALL_SOURCE_REGID) AS "EXITOSOS"
> > FROM (
> > SELECT
> > A.CALL_SOURCE_REGID,
> > B.ESTADO,
> > B.MUNICIPIO
> > FROM OM_DB.CDRS_PRUEBA A, OM_DB.COFETEL
> > B
> > WHERE A.START_TIME BETWEEN vPMM_DATETIME
> > AND vEND_DATETIME
> > AND TO_NUMBER
> > (A.CALLED_PARTY_ON_DEST_PART3) between B.NIR_INICIAL AND B.NIR_FINAL
> > AND A.CALL_DURATION_INT >= 5
> > AND B.MODALIDAD IN ('CPP','FIJO','MPP')
> > )
> > GROUP BY
> > ESTADO,
> > MUNICIPIO,
> > CALL_SOURCE_REGID
> > ) "V_EXITOSOS"
> > FULL OUTER JOIN
> > (
> > SELECT
> > DISTINCT(ESTADO) AS "ESTADO",
> > MUNICIPIO,
> > CALL_SOURCE_REGID,
> > COUNT(CALL_SOURCE_REGID) AS "NO_EXITOSOS"
> > FROM (
> > SELECT
> > C.CALL_SOURCE_REGID,
> > D.ESTADO,
> > D.MUNICIPIO
> > FROM OM_DB.CDRS_PRUEBA C, OM_DB.COFETEL
> > D
> > WHERE C.START_TIME BETWEEN vPMM_DATETIME
> > AND vEND_DATETIME
> > AND TO_NUMBER
> > (C.CALLED_PARTY_ON_DEST_PART3) between D.NIR_INICIAL AND D.NIR_FINAL
> > AND C.CALL_DURATION_INT >= 1 AND
> > C.CALL_DURATION_INT < 5
> > AND D.MODALIDAD IN ('CPP','FIJO','MPP')
> > )
> > GROUP BY
> > ESTADO,
> > MUNICIPIO,
> > CALL_SOURCE_REGID
> > ) "V_NO_EXITOSOS"
> > ON
> > V_EXITOSOS.ESTADO = V_NO_EXITOSOS.ESTADO
> > AND V_EXITOSOS.MUNICIPIO =
> > V_NO_EXITOSOS.MUNICIPIO
> > AND V_EXITOSOS.CALL_SOURCE_REGID =
> > V_NO_EXITOSOS.CALL_SOURCE_REGID
> > FULL OUTER JOIN
> > (
> > SELECT
> > DISTINCT(ESTADO) AS "ESTADO",
> > MUNICIPIO,
> > CALL_SOURCE_REGID,
> > COUNT(CALL_SOURCE_REGID) AS "NO_CONECT"
> > FROM (
> > SELECT
> > C.CALL_SOURCE_REGID,
> > D.ESTADO,
> > D.MUNICIPIO
> > FROM OM_DB.CDRS_PRUEBA C, OM_DB.COFETEL
> > D
> > WHERE C.START_TIME BETWEEN vPMM_DATETIME
> > AND vEND_DATETIME
> > AND TO_NUMBER
> > (C.CALLED_PARTY_ON_DEST_PART3) between D.NIR_INICIAL AND D.NIR_FINAL
> > AND C.CALL_DURATION_INT = 0
> > AND D.MODALIDAD IN ('CPP','FIJO','MPP')
> > )
> > GROUP BY
> > ESTADO,
> > MUNICIPIO,
> > CALL_SOURCE_REGID
> > ) "V_NO_CONECT"
> > ON
> > V_NO_CONECT.ESTADO = V_EXITOSOS.ESTADO
> > AND V_NO_CONECT.MUNICIPIO =
> > V_EXITOSOS.MUNICIPIO
> > AND V_NO_CONECT.CALL_SOURCE_REGID =
> > V_EXITOSOS.CALL_SOURCE_REGID
> > )
> > GROUP BY
> > PMM_DATETIME,
> > CALL_SOURCE_REGID,
> > ESTADO,
> > MUNICIPIO
> > ) "Y" -- Cierra USING
> > ON (
> > X.PMM_DATETIME = Y.PMM_DATETIME
> > AND X.CALL_SOURCE_REGID = Y.CALL_SOURCE_REGID
> > AND X.ESTADO = Y.ESTADO
> > AND X.MUNICIPIO = Y.MUNICIPIO
> > )
> > WHEN MATCHED THEN UPDATE SET
> > X.EXITOSOS = X.EXITOSOS + Y.EXITOSOS,
> > X.NO_EXITOSOS = X.NO_EXITOSOS + Y.NO_EXITOSOS,
> > X.NO_CONECT = X.NO_CONECT + Y.NO_CONECT
> > WHEN NOT MATCHED THEN INSERT (X.ESTADO, X.MUNICIPIO,
> > X.CALL_SOURCE_REGID, X.EXITOSOS, X.NO_EXITOSOS, X.NO_CONECT,
> > X.PMM_DATETIME)
> > VALUES (Y.ESTADO, Y.MUNICIPIO, Y.CALL_SOURCE_REGID,
> > Y.EXITOSOS, Y.NO_EXITOSOS, Y.NO_CONECT, Y.PMM_DATETIME);
>
> > vPMM_DATETIME := vPMM_DATETIME + 1/24;
> > vEND_DATETIME := vPMM_DATETIME + 1/24;
> > END LOOP;
> > COMMIT;
> > END IF;
>
> > dbms_output.put_line('Fin de procedimiento: ' || TO_CHAR(sysdate,
> > 'YYYY-MM-DD HH24:MI:SS'));
> > END;
>
> Are you absolutely sure you merge statement is correct? My syntax
> checker can not find the corresponding left and right parentheses in
> that statement.... and it LOOKS like the "-- Cierra USING" is not in the
> correct position: the outer join has not ended there yet!
> But since I don't have the DDL of your tables, it's hard to check at
> this end.
>
> Shakespeare- Ocultar texto de la cita -
>
> - Mostrar texto de la cita -

Hi thanks for your quickly response,

Im absolutely sure, look the problem is that i have to make a loop i mean the USING part of the MERGE needs 2 vars, this vars must be seted since the source table, like i say my problem is when i use this query like a whole block of PL/SQL like this

DECLARE
    /* Declaring vars */
BEGIN
    /* Setting the vars */

    /* Get start_time and end_time,

       it looks like: start = 2009-04-22 10:00:00 | end = 2009-04-22 13:00:00 */

    /* Then loop (from 2009-04-22 10:00:00 to 2009-04-22 13:00:00)

       and each iteration must increase 1 hour (10:00:00 to 11:00:00, 11:00:00 to 12:00:00 and

       12:00:00 to 13:00:00) */

    /* Merge whit vars */
END; Otherwise if i run just this It works

/* Merge with constants */

So please give me some advice, my goal is to make this process each 15 minutes, the source table may have records since previous hours so thats why the loop.

/* Setting the vars */
/* Get start_time */
SELECT TO_DATE(TO_CHAR(MIN(START_TIME),'YYYY-MM-DD HH24') || ': 00:00','YYYY-MM-DD HH24:MI:SS')
INTO vPMM_DATETIME
FROM OM_DB.CDRS_PRUEBA; /* Get limit of the first iteration */
vEND_DATETIME := vPMM_DATETIME + 1/24;

/* Get end_time */
SELECT TO_DATE(TO_CHAR(MAX(START_TIME),'YYYY-MM-DD HH24') || ': 59:59','YYYY-MM-DD HH24:MI:SS')
INTO vMAX_PMM_DATETIME
FROM om_db.CDRS_PRUEBA;

/* Then looping */
WHILE (vPMM_DATETIME <= vMAX_PMM_DATETIME) LOOP

    MERGE INTO OM_DB.CDRS_VALIDOS "X"
    USING (

        SELECT
            ....
        WHERE  A.START_TIME BETWEEN vPMM_DATETIME AND vEND_DATETIME
    )
    ON

        .....

    /* iteration increase 1 hour */
    vPMM_DATETIME := vPMM_DATETIME + 1/24;     vEND_DATETIME := vPMM_DATETIME + 1/24; END LOOP; Regards Received on Wed Apr 22 2009 - 16:19:01 CDT

Original text of this message