Locking in Merge Statement

Hi All,
I am using merge statement to insert and update rows. The merge statement takes a row level exclusive lock
Suppose the select statement returns 1 Million records does
1) The merge statement first tries to lock all the affected rows and then update / insert records.
OR
2) The merge statement aquires lock on an incremental basis as returned by the select statement.

The merge works just like an insert or update statement in that locks are acquired "on an incremental basis", but as of the timestamp the merge began. When Oracle detects that another session has updated a row in the meantime, then it re-executes the entire merge statement as of that new timestamp. It is sometimes referred to as "write consistency".
Here is a good Asktom thread on this topic: http://asktom.oracle.com/pls/asktom/f?p=100:11:1694097844551766::::P11_QUESTION_ID:11504247549852
Regards,
Rob.

Similar Messages

  • Merge Statement in ABAP

    Dear Gurrus,
    i am having a trouble in using oracle merge statement in abap, the moment i use where clause in the bottom it  gives me an oracle error
    EXEC SQL.
      MERGE INTO SAP_GL_ACCOUNT@GETZDB a
      USING SKA1 b
        ON (A.gl_code= B.SAKNR)
      WHEN MATCHED THEN
        UPDATE SET a.posting_block =  B.XSPEB,
                   a.locked        =  B.XSPEA,
                   A.BALANCE_SHEET =  B.XBILK
         WHEN NOT MATCHED THEN
           insert   (gl_code,
                     DESCRIPTION,
                     posting_block,
                     locked,
                     balance_sheet)
          VALUES (b.SAKNR,'shadab',B.XSPEB,B.XSPEA,B.XBILK)
          where b. mandt = 950      I am talking about this line
             ENDEXEC.
    the Moment  i include WHERE clause in the botton before ENDEXEC it generates as error
    " Database error text........: "ORA-00904: "A3"."MANDT": invalid  identifier#ORA-02063: preceding line from GETZDB".
    although its a basic feature of Oracle to inclue where clauses in insert or update in merge, but here it is generating an error.

    Hello Shadab,
    As per my understanding of this oracle native sql code.
    everything is fine except the use of direct value i.e 950 .
    System is not able to process this value .
    This normally happens even in normal abap sql statements also.
    The better solution could be to declare a variable with the
    same data type as "mandt" and then pass this "950" value into that
    variable and then use this variable in the where clause instead of directly
    passing the value.
    i.e data:l_var type mandt vlaue '950'.
    The other option could be to use the same hard coded
    value but use this value in the where clause in quotations i.e.,
    '950' instead of 950.
    I hope this would solve your purpose, If not please reply me back.
    thanks,
    M.Naveen Kumar.

  • Automatic Parallelism causes Merge statement to take longer.

    We have a problem in a new project as part of the ETL load into the Oracle datawarehouse we perform a merge statement to update rows in a global temporary table then load
    the results into a permanant table, when testing with automatic parallel execution enabled the plan changes and the merge never finishes and consumes vast amounts of resources.
    The database version is:-
    Database version :11.2.0.3
    OS: redhat 64bit
    three node rac 20 cores per node
    when executing serially the query response is typically similar to the following:
    MERGE /*+ gather_plan_statistics no_parallel */ INTO T_GTTCHARGEVALUES USING
      (SELECT
      CASTACCOUNTID,
      CHARGESCHEME,
      MAX(CUMULATIVEVALUE) AS MAXMONTHVALUE,
      MAX(CUMULATIVECOUNT) AS MAXMONTHCOUNT
    FROM
      V_CACHARGESALL
    WHERE
      CHARGEDATE >= TRUNC(TO_DATE(:B1,'YYYY-MM-DD'),'MM')
      AND CHARGEDATE < TO_DATE(:B1,'YYYY-MM-DD')
    GROUP BY
       CASTACCOUNTID,
       CHARGESCHEME
    HAVING MAX(CUMULATIVECOUNT) IS NOT NULL ) MTOTAL
    ON
      (T_GTTCHARGEVALUES.CASTACCOUNTID=MTOTAL.CASTACCOUNTID AND
      T_GTTCHARGEVALUES.CHARGESCHEME=MTOTAL.CHARGESCHEME)
    WHEN MATCHED
    THEN UPDATE SET
      CUMULATIVEVALUE=CUMULATIVEVALUE+MTOTAL.MAXMONTHVALUE ,
      CUMULATIVECOUNT=CUMULATIVECOUNT+MTOTAL.MAXMONTHCOUNT;
    1448340 rows merged.
    select * from table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST')); 
    | Id  | Operation                       | Name              | Starts | E-Rows | A-Rows |   A-Time   | Buffers | Reads  |  OMem |  1Mem | Used-Mem |
    |   0 | MERGE STATEMENT                 |                   |      1 |        |      0 |00:03:08.43 |    2095K|    186K|       |       |          |
    |   1 |  MERGE                          | T_GTTCHARGEVALUES |      1 |        |      0 |00:03:08.43 |    2095K|    186K|       |       |          |
    |   2 |   VIEW                          |                   |      1 |        |   1448K|00:02:53.14 |     619K|    177K|       |       |          |
    |*  3 |    HASH JOIN                    |                   |      1 |      1 |   1448K|00:02:52.70 |     619K|    177K|   812K|   812K| 1218K (0)|
    |   4 |     VIEW                        |                   |      1 |      1 |    203 |00:02:51.26 |     608K|    177K|       |       |          |
    |*  5 |      FILTER                     |                   |      1 |        |    203 |00:02:51.26 |     608K|    177K|       |       |          |
    |   6 |       SORT GROUP BY             |                   |      1 |      1 |    480 |00:02:51.26 |     608K|    177K| 73728 | 73728 |          |
    |*  7 |        FILTER                   |                   |      1 |        |     21M|00:02:56.04 |     608K|    177K|       |       |          |
    |   8 |         PARTITION RANGE ITERATOR|                   |      1 |    392K|     21M|00:02:51.32 |     608K|    177K|       |       |          |
    |*  9 |          TABLE ACCESS FULL      | T_CACHARGES       |     24 |    392K|     21M|00:02:47.48 |     608K|    177K|       |       |          |
    |  10 |     TABLE ACCESS FULL           | T_GTTCHARGEVALUES |      1 |   1451K|   1451K|00:00:00.48 |   10980 |      0 |       |       |          |
    Predicate Information (identified by operation id):
       3 - access("T_GTTCHARGEVALUES"."CASTACCOUNTID"="MTOTAL"."CASTACCOUNTID" AND "T_GTTCHARGEVALUES"."CHARGESCHEME"="MTOTAL"."CHARGESCHEME")
       5 - filter(MAX("CUMULATIVECOUNT") IS NOT NULL)
       7 - filter(TRUNC(TO_DATE(:B1,'YYYY-MM-DD'),'fmmm')<TO_DATE(:B1,'YYYY-MM-DD'))
       9 - filter(("LOGICALLYDELETED"=0 AND "CHARGEDATE">=TRUNC(TO_DATE(:B1,'YYYY-MM-DD'),'fmmm') AND "CHARGEDATE"<TO_DATE(:B1,'YYYY-MM-DD')))removing the no_parallel hint results in the following, (this is pulled from the sql monitoring report and editied to remove the lines relating to individual parallel servers)
    I understand that the query is considered for parallel execution due to the estimated length of time it will run for and although the degree of parallleism seems excessive
    it is the default maximum for the server configuration, what we are tryig to understand is which statistics could be inacurate or missing and could cause this kind of problem.
    In this case we can add the no_parallel hint in the etl package as a workaround but would really liek to identify the root cause to avoid similar problems elsewhere.
    SQL Monitoring Report
    SQL Text
    MERGE INTO T_GTTCHARGEVALUES USING (SELECT CASTACCOUNTID, CHARGESCHEME, MAX(CUMULATIVEVALUE) AS MAXMONTHVALUE,
    MAX(CUMULATIVECOUNT) AS MAXMONTHCOUNT FROM V_CACHARGESALL WHERE CHARGEDATE >= TRUNC(TO_DATE(:B1,'YYYY-MM-DD'),'MM')
    AND CHARGEDATE < to_date(:B1,'YYYY-MM-DD')
    GROUP BY CASTACCOUNTID, CHARGESCHEME HAVING MAX(CUMULATIVECOUNT) IS NOT NULL ) MTOTAL
    ON (T_GTTCHARGEVALUES.CASTACCOUNTID=MTOTAL.CASTACCOUNTID AND
    T_GTTCHARGEVALUES.CHARGESCHEME=MTOTAL.CHARGESCHEME) WHEN MATCHED THEN UPDATE SET
    CUMULATIVEVALUE=CUMULATIVEVALUE+MTOTAL.MAXMONTHVALUE ,
    CUMULATIVECOUNT=CUMULATIVECOUNT+MTOTAL.MAXMONTHCOUNT
    Error: ORA-1013
    ORA-01013: user requested cancel of current operation
    Global Information
    Status              :  DONE (ERROR)
    Instance ID         :  1
    Session             :  XXXX(2815:12369)
    SQL ID              :  70kzttjbyyspt
    SQL Execution ID    :  16777216
    Execution Started   :  04/27/2012 09:43:27
    First Refresh Time  :  04/27/2012 09:43:27
    Last Refresh Time   :  04/27/2012 09:48:43
    Duration            :  316s
    Module/Action       :  SQL*Plus/-
    Service             :  SYS$USERS
    Program             :  sqlplus@XXXX (TNS V1-V3)
    Binds
    ========================================================================================================================
    | Name | Position |     Type     |                                        Value                                        |
    ========================================================================================================================
    | :B1  |        1 | VARCHAR2(32) | 2012-04-25                                                                          |
    ========================================================================================================================
    Global Stats
    ====================================================================================================================
    | Elapsed | Queuing |   Cpu   |    IO    | Application | Concurrency | Cluster  |  Other   | Buffer | Read | Read  |
    | Time(s) | Time(s) | Time(s) | Waits(s) |  Waits(s)   |  Waits(s)   | Waits(s) | Waits(s) |  Gets  | Reqs | Bytes |
    ====================================================================================================================
    |    7555 |    0.00 |    4290 |     2812 |        0.08 |          27 |      183 |      243 |     3M | 294K |   7GB |
    ====================================================================================================================
    SQL Plan Monitoring Details (Plan Hash Value=323941584)
    ==========================================================================================================================================================================================================
    | Id |             Operation             |       Name        |  Rows   | Cost  |   Time    | Start  | Execs |   Rows   | Read | Read  |  Mem  | Activity |                Activity Detail                |
    |    |                                   |                   | (Estim) |       | Active(s) | Active |       | (Actual) | Reqs | Bytes | (Max) |   (%)    |                  (# samples)                  |
    ==========================================================================================================================================================================================================
    |  0 | MERGE STATEMENT                   |                   |         |       |           |        |     1 |          |      |       |       |          |                                               |
    |  1 |   MERGE                           | T_GTTCHARGEVALUES |         |       |           |        |     1 |          |      |       |       |          |                                               |
    |  2 |    PX COORDINATOR                 |                   |         |       |        57 |     +1 |   481 |        0 |  317 |   5MB |       |     4.05 | latch: shared pool (40)                       |
    |    |                                   |                   |         |       |           |        |       |          |      |       |       |          | os thread startup (17)                        |
    |    |                                   |                   |         |       |           |        |       |          |      |       |       |          | Cpu (7)                                       |
    |    |                                   |                   |         |       |           |        |       |          |      |       |       |          | DFS lock handle (36)                          |
    |    |                                   |                   |         |       |           |        |       |          |      |       |       |          | SGA: allocation forcing component growth (14) |
    |    |                                   |                   |         |       |           |        |       |          |      |       |       |          | latch: parallel query alloc buffer (200)      |
    |  3 |     PX SEND QC (RANDOM)           | :TQ10003          |       1 | 19054 |           |        |       |          |      |       |       |          |                                               |
    |  4 |      VIEW                         |                   |         |       |           |        |       |          |      |       |       |          |                                               |
    |  5 |       FILTER                      |                   |         |       |           |        |       |          |      |       |       |          |                                               |
    |  6 |        SORT GROUP BY              |                   |       1 | 19054 |           |        |       |          |      |       |       |          |                                               |
    |  7 |         PX RECEIVE                |                   |       1 | 19054 |           |        |       |          |      |       |       |          |                                               |
    |  8 |          PX SEND HASH             | :TQ10002          |       1 | 19054 |           |        |   240 |          |      |       |       |          |                                               |
    |  9 |           SORT GROUP BY           |                   |       1 | 19054 |       246 |    +70 |   240 |        0 |      |       |  228M |    49.32 | Cpu (3821)                                    |
    | 10 |            FILTER                 |                   |         |       |       245 |    +71 |   240 |       3G |      |       |       |     0.08 | Cpu (6)                                       |
    | 11 |             HASH JOIN             |                   |       1 | 19054 |       259 |    +57 |   240 |       3G |      |       |  276M |     4.31 | Cpu (334)                                     |
    | 12 |              PX RECEIVE           |                   |      1M |     5 |       259 |    +57 |   240 |       1M |      |       |       |     0.04 | Cpu (3)                                       |
    | 13 |               PX SEND HASH        | :TQ10000          |      1M |     5 |         6 |    +56 |   240 |       1M |      |       |       |     0.01 | Cpu (1)                                       |
    | 14 |                PX BLOCK ITERATOR  |                   |      1M |     5 |         6 |    +56 |   240 |       1M |      |       |       |     0.03 | Cpu (1)                                       |
    |    |                                   |                   |         |       |           |        |       |          |      |       |       |          | PX Deq: reap credit (1)                       |
    | 15 |                 TABLE ACCESS FULL | T_GTTCHARGEVALUES |      1M |     5 |         7 |    +55 |  5486 |       1M | 5487 |  86MB |       |     2.31 | gc cr grant 2-way (3)                         |
    |    |                                   |                   |         |       |           |        |       |          |      |       |       |          | gc current block lost (7)                     |
    |    |                                   |                   |         |       |           |        |       |          |      |       |       |          | Cpu (7)                                       |
    |    |                                   |                   |         |       |           |        |       |          |      |       |       |          | db file sequential read (162)                 |
    | 16 |              PX RECEIVE           |                   |     78M | 19047 |       255 |    +61 |   240 |     801K |      |       |       |     0.03 | IPC send completion sync (2)                  |
    | 17 |               PX SEND HASH        | :TQ10001          |     78M | 19047 |       250 |    +66 |   240 |       3M |      |       |       |     0.06 | Cpu (5)                                       |
    | 18 |                PX BLOCK ITERATOR  |                   |     78M | 19047 |       250 |    +66 |   240 |       4M |      |       |       |          |                                               |
    | 19 |                 TABLE ACCESS FULL | T_CACHARGES       |     78M | 19047 |       254 |    +62 |  1016 |       4M | 288K |   6GB |       |    37.69 | gc buffer busy acquire (104)                  |
    |    |                                   |                   |         |       |           |        |       |          |      |       |       |          | gc cr block 2-way (1)                         |
    |    |                                   |                   |         |       |           |        |       |          |      |       |       |          | gc cr block lost (9)                          |
    |    |                                   |                   |         |       |           |        |       |          |      |       |       |          | gc cr grant 2-way (14)                        |
    |    |                                   |                   |         |       |           |        |       |          |      |       |       |          | gc cr multi block request (1)                 |
    |    |                                   |                   |         |       |           |        |       |          |      |       |       |          | gc current block 2-way (3)                    |
    |    |                                   |                   |         |       |           |        |       |          |      |       |       |          | gc current block 3-way (2)                    |
    |    |                                   |                   |         |       |           |        |       |          |      |       |       |          | gc current block busy (1)                     |
    |    |                                   |                   |         |       |           |        |       |          |      |       |       |          | gc current grant busy (2)                     |
    |    |                                   |                   |         |       |           |        |       |          |      |       |       |          | Cpu (58)                                      |
    |    |                                   |                   |         |       |           |        |       |          |      |       |       |          | latch: gc element (1)                         |
    |    |                                   |                   |         |       |           |        |       |          |      |       |       |          | db file parallel read (26)                    |
    |    |                                   |                   |         |       |           |        |       |          |      |       |       |          | db file scattered read (207)                  |
    |    |                                   |                   |         |       |           |        |       |          |      |       |       |          | db file sequential read (2433)                |
    |    |                                   |                   |         |       |           |        |       |          |      |       |       |          | direct path read (1)                          |
    |    |                                   |                   |         |       |           |        |       |          |      |       |       |          | read by other session (57)                    |
    ==========================================================================================================================================================================================================
    Parallel Execution Details (DOP=240 , Servers Allocated=480)
    Instances  : 3

    chris_c wrote:
    | Id  | Operation                       | Name              | Starts | E-Rows | A-Rows |   A-Time   | Buffers | Reads  |  OMem |  1Mem | Used-Mem |
    |*  9 |          TABLE ACCESS FULL      | T_CACHARGES       |     24 |    392K|     21M|00:02:47.48 |     608K|    177K|       |       |          |
    Based on the discrepancy between the estimated number of rows and the actual, and the below posted bind value of 2012-04-25 i'd first be checking if the statistics on T_CACHARGES are up to date.
    As a reference
    http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:4399338600346902127
    So that would be my first avenue of exploration.
    Cheers,

  • Merge statements in Pro*C

    First I tried doing the following:
    EXEC SQL
    MERGE INTO <table>
    ect. etc.
    And got Encountered the symbol "MERGE" when expecting one of the following:
    for, register, at, close, commit, connect, declare, describe,
    execute, fetch, open, prepare, rollback, select, whenever,
    alter, audit, comment, create, delete, drop, get, grant,
    insert, lock, noaudit, rename, revoke, set, update, validate,
    arraylen, allocate, cache, call, collection, context,
    deallocate, enable, free, lob, object, savepoint, analyze,
    explain, truncate,
    I later found out that you can't embed MERGE statements like that. So instead I tried to embed it as a PL/SQL block.
    EXEC SQL EXECUTE
    BEGIN
    MERGE INTO <table>
    USING (..)
    ON (..)
    WHEN MATCHED ..
    WHEN NOT MATCHED ..
    END;
    END-EXEC;
    And got the following: "MERGE INTO BENEFITS.BROKER_INFORMATION D
    PLS-S-00103, Encountered the symbol "INTO" when expecting one of the following:
    Does Pro*C just flat out hate merge statements?

    Hi,
    I tried out, exactly the same as you tried..
    Looks like the ANSI Pro C ompiler is not equiped to compile Merge statement.
    So if we can get the compiler not touch the Merge statement, our job is done.
    The work around is as follows:
         /*SQL Declarations*/
              EXEC SQL BEGIN DECLARE SECTION;
                        char O_str1[1024];
                        EXEC SQL VAR O_str1 IS STRING (1024);
              EXEC SQL END DECLARE SECTION;
              strcpy(O_str1,"MERGE INTO .....");
         /*SQL query to be executed*/
              EXEC SQL PREPARE curSqlStmt FROM :O_str1;
    Please try and respond, it worked for me...
    Regds
    Santosh Iyengar

  • Merge statement

    i would like to know if it is possible to identify the row that is causing the problem when you use a merge statement in pl/sql. i know if you create a cursor and then loop through the data you can identify the column but what about if i have only a merge that will either insert or update. is it possible to identify which row of data cause the problem? thanks

    You can use an Error Logging Table<br>
    <br>
    Nicolas.

  • Merge Statement in PL/SQL

    Hi
    I am using a merge statement where i am updating and inserting records in table 2 from table 1.
    I want to log the no. of rows updated and new rows inserted in the log table.
    If i am not wrong, we can use sql%rowcount but i need help as how to use this statement.
    Please suggest a solution.
    Thanks

    user11018028 wrote:
    Will the sql%rowcount will give the no. of updated rows OR no. of newly inserted rows OR the sum of both in case of a merge statement.Total number of rows that changed (SUM).

  • Question on passing string values to Partition clause in a merge statement

    Hello All,
    I am using the below code to update specific sub-partition data using oracle merge statements.
    I am getting the sub-partition name and passing this as a string to the sub-partition clause.
    The Merge statement is failing stating that the specified sub-partition does not exist. But the sub-partition do exists for the table.
    We are using Oracle 11gr2 database.
    Below is the code which I am using to populate the data.
    declare
    ln_min_batchkey PLS_INTEGER;
    ln_max_batchkey PLS_INTEGER;
    lv_partition_name VARCHAR2 (32767);
    lv_subpartition_name VARCHAR2 (32767);
    begin
    FOR m1 IN ( SELECT (year_val + 1) AS year_val, year_val AS orig_year_val
    FROM ( SELECT DISTINCT
    TO_CHAR (batch_create_dt, 'YYYY') year_val
    FROM stores_comm_mob_sub_temp
    ORDER BY 1)
    ORDER BY year_val)
    LOOP
    lv_partition_name :=
    scmsa_handset_mobility_data_build.fn_get_partition_name (
    p_table_name => 'STORES_COMM_MOB_SUB_INFO',
    p_search_string => m1.year_val);
    FOR m2
    IN (SELECT DISTINCT
    'M' || TO_CHAR (batch_create_dt, 'MM') AS month_val
    FROM stores_comm_mob_sub_temp
    WHERE TO_CHAR (batch_create_dt, 'YYYY') = m1.orig_year_val)
    LOOP
    lv_subpartition_name :=
    scmsa_handset_mobility_data_build.fn_get_subpartition_name (
    p_table_name => 'STORES_COMM_MOB_SUB_INFO',
    p_partition_name => lv_partition_name,
    p_search_string => m2.month_val);
                        DBMS_OUTPUT.PUT_LINE('The lv_subpartition_name => '||lv_subpartition_name||' and lv_partition_name=> '||lv_partition_name);
    IF lv_subpartition_name IS NULL
    THEN
                             DBMS_OUTPUT.PUT_LINE('INSIDE IF => '||m2.month_val);
    INSERT INTO STORES_COMM_MOB_SUB_INFO T1 (
    t1.ntlogin,
    t1.first_name,
    t1.last_name,
    t1.job_title,
    t1.store_id,
    t1.batch_create_dt)
    SELECT t2.ntlogin,
    t2.first_name,
    t2.last_name,
    t2.job_title,
    t2.store_id,
    t2.batch_create_dt
    FROM stores_comm_mob_sub_temp t2
    WHERE TO_CHAR (batch_create_dt, 'YYYY') = m1.orig_year_val
    AND 'M' || TO_CHAR (batch_create_dt, 'MM') =
    m2.month_val;
    ELSIF lv_subpartition_name IS NOT NULL
    THEN
                        DBMS_OUTPUT.PUT_LINE('INSIDE ELSIF => '||m2.month_val);
    MERGE INTO (SELECT *
    FROM stores_comm_mob_sub_info
    SUBPARTITION (lv_subpartition_name)) T1
    USING (SELECT *
    FROM stores_comm_mob_sub_temp
    WHERE TO_CHAR (batch_create_dt, 'YYYY') =
    m1.orig_year_val
    AND 'M' || TO_CHAR (batch_create_dt, 'MM') =
    m2.month_val) T2
    ON (T1.store_id = T2.store_id
    AND T1.ntlogin = T2.ntlogin)
    WHEN MATCHED
    THEN
    UPDATE SET
    t1.postpaid_totalqty =
    (NVL (t1.postpaid_totalqty, 0)
    + NVL (t2.postpaid_totalqty, 0)),
    t1.sales_transaction_dt =
    GREATEST (
    NVL (t1.sales_transaction_dt,
    t2.sales_transaction_dt),
    NVL (t2.sales_transaction_dt,
    t1.sales_transaction_dt)),
    t1.batch_create_dt =
    GREATEST (
    NVL (t1.batch_create_dt, t2.batch_create_dt),
    NVL (t2.batch_create_dt, t1.batch_create_dt))
    WHEN NOT MATCHED
    THEN
    INSERT (t1.ntlogin,
    t1.first_name,
    t1.last_name,
    t1.job_title,
    t1.store_id,
    t1.batch_create_dt)
    VALUES (t2.ntlogin,
    t2.first_name,
    t2.last_name,
    t2.job_title,
    t2.store_id,
    t2.batch_create_dt);
    END IF;
    END LOOP;
    END LOOP;
    COMMIT;
    end;
    Much appreciate your inputs here.
    Thanks,
    MK.

    I've not used partitioning, but I do not see MERGE supporting a variable as a partition name in
    MERGE INTO (SELECT *
    FROM stores_comm_mob_sub_info
    SUBPARTITION (lv_subpartition_name)) T1
    USING ... I suspect it is looking for a partition called lv_subpartition_name.
    I also don't see why you need that partition name - the ON clause should be able to identify the partition's criteria.

  • Issue while using SUBPARTITION clause in the MERGE statement in PLSQL Code

    Hello All,
    I am using the below code to update specific sub-partition data using oracle merge statements.
    I am getting the sub-partition name and passing this as a string to the sub-partition clause.
    The Merge statement is failing stating that the specified sub-partition does not exist. But the sub-partition do exists for the table.
    We are using Oracle 11gr2 database.
    Below is the code which I am using to populate the data.
    declare
    ln_min_batchkey PLS_INTEGER;
    ln_max_batchkey PLS_INTEGER;
    lv_partition_name VARCHAR2 (32767);
    lv_subpartition_name VARCHAR2 (32767);
    begin
    FOR m1 IN ( SELECT (year_val + 1) AS year_val, year_val AS orig_year_val
    FROM ( SELECT DISTINCT
    TO_CHAR (batch_create_dt, 'YYYY') year_val
    FROM stores_comm_mob_sub_temp
    ORDER BY 1)
    ORDER BY year_val)
    LOOP
    lv_partition_name :=
    scmsa_handset_mobility_data_build.fn_get_partition_name (
    p_table_name => 'STORES_COMM_MOB_SUB_INFO',
    p_search_string => m1.year_val);
    FOR m2
    IN (SELECT DISTINCT
    'M' || TO_CHAR (batch_create_dt, 'MM') AS month_val
    FROM stores_comm_mob_sub_temp
    WHERE TO_CHAR (batch_create_dt, 'YYYY') = m1.orig_year_val)
    LOOP
    lv_subpartition_name :=
    scmsa_handset_mobility_data_build.fn_get_subpartition_name (
    p_table_name => 'STORES_COMM_MOB_SUB_INFO',
    p_partition_name => lv_partition_name,
    p_search_string => m2.month_val);
                        DBMS_OUTPUT.PUT_LINE('The lv_subpartition_name => '||lv_subpartition_name||' and lv_partition_name=> '||lv_partition_name);
    IF lv_subpartition_name IS NULL
    THEN
                             DBMS_OUTPUT.PUT_LINE('INSIDE IF => '||m2.month_val);
    INSERT INTO STORES_COMM_MOB_SUB_INFO T1 (
    t1.ntlogin,
    t1.first_name,
    t1.last_name,
    t1.job_title,
    t1.store_id,
    t1.batch_create_dt)
    SELECT t2.ntlogin,
    t2.first_name,
    t2.last_name,
    t2.job_title,
    t2.store_id,
    t2.batch_create_dt
    FROM stores_comm_mob_sub_temp t2
    WHERE TO_CHAR (batch_create_dt, 'YYYY') = m1.orig_year_val
    AND 'M' || TO_CHAR (batch_create_dt, 'MM') =
    m2.month_val;
    ELSIF lv_subpartition_name IS NOT NULL
    THEN
                        DBMS_OUTPUT.PUT_LINE('INSIDE ELSIF => '||m2.month_val);
    MERGE INTO (SELECT *
    FROM stores_comm_mob_sub_info
    SUBPARTITION (lv_subpartition_name)) T1 --> Issue Here
    USING (SELECT *
    FROM stores_comm_mob_sub_temp
    WHERE TO_CHAR (batch_create_dt, 'YYYY') =
    m1.orig_year_val
    AND 'M' || TO_CHAR (batch_create_dt, 'MM') =
    m2.month_val) T2
    ON (T1.store_id = T2.store_id
    AND T1.ntlogin = T2.ntlogin)
    WHEN MATCHED
    THEN
    UPDATE SET
    t1.postpaid_totalqty =
    (NVL (t1.postpaid_totalqty, 0)
    + NVL (t2.postpaid_totalqty, 0)),
    t1.sales_transaction_dt =
    GREATEST (
    NVL (t1.sales_transaction_dt,
    t2.sales_transaction_dt),
    NVL (t2.sales_transaction_dt,
    t1.sales_transaction_dt)),
    t1.batch_create_dt =
    GREATEST (
    NVL (t1.batch_create_dt, t2.batch_create_dt),
    NVL (t2.batch_create_dt, t1.batch_create_dt))
    WHEN NOT MATCHED
    THEN
    INSERT (t1.ntlogin,
    t1.first_name,
    t1.last_name,
    t1.job_title,
    t1.store_id,
    t1.batch_create_dt)
    VALUES (t2.ntlogin,
    t2.first_name,
    t2.last_name,
    t2.job_title,
    t2.store_id,
    t2.batch_create_dt);
    END IF;
    END LOOP;
    END LOOP;
    COMMIT;
    end;
    Much appreciate your inputs here.
    Thanks,
    MK.
    (SORRY TO POST THE SAME QUESTION TWICE).
    Edited by: Maddy on May 23, 2013 10:20 PM

    Duplicate question

  • Error executing a stored procedure from SSIS using the MERGE statement between databases

    Good morning,
    I'm trying to execute from SSIS a stored procedure that compares the content of two tables on different databases in the same server and updates one of them. To perform this action, I've created a stored procedure in the destination database and I'm
    comparing the data between tables with the MERGE statement. When I execute the procedure on the destination database the error that I obtain is:
    "Msg 916, Level 14, State 1, Procedure RefreshDestinationTable, Line 13
    The server principal "XXXX" is not able to access the database "XXXX" under the current security context."
    Some things to take in account:
    1. I've created a temporary table on the same destination database to check if the problem was on the MERGE statement and it works fine.
    2. I've created the procedure with the option "WITH EXECUTE AS DBO".
    I've read that it can be a problem of permissions but I don't know if I'm executing the procedure from SSIS to which user/login I should give permissions and which.
    Could you give me some tip to continue investigating how to solve the problem?
    Thank you,
    Virgilio

    Read Erland's article http://www.sommarskog.se/grantperm.html
    Best Regards,Uri Dimant SQL Server MVP,
    http://sqlblog.com/blogs/uri_dimant/
    MS SQL optimization: MS SQL Development and Optimization
    MS SQL Consulting:
    Large scale of database and data cleansing
    Remote DBA Services:
    Improves MS SQL Database Performance
    SQL Server Integration Services:
    Business Intelligence

  • Error while using Merge statement

    Hi,
    Can any one please look at the merge statement and help me understand the error.Thanks in advance.
    MERGE /*+ APPEND */
    INTO intf_lpa_master m
    USING (SELECT std_district_student_id,
    std_grade_code,
    sub_test,
    test_date,
    performance_lvl_code,
    test_lang_code,
    v_student_id,
    v_test_id,
    v_lang_cd,
    v_plc,
    valid_test_date,
    -- school_year,
    -- school_id,
    valid_src_stu_id,
    test_code
    FROM intf_lpa_master_vw
    MINUS
    SELECT std_district_student_id,
    std_grade_code,
    sub_test,
    test_date,
    performance_lvl_code,
    test_lang_code,
    v_student_id,
    v_test_id,
    v_lang_cd,
    v_plc,
    valid_test_date,
    -- school_yr,
    -- school_id,
    valid_src_stu_id,
    test_code
    FROM intf_lpa_master
    WHERE active_flag = 'Y') v
    ON ( m.std_district_student_id = v.std_district_student_id
    AND m.sub_test = v.sub_test
    AND m.test_date = v.test_date)
    WHEN MATCHED
    THEN
    UPDATE SET m.std_grade_code = v.std_grade_code,
    m.performance_lvl_code = v.performance_lvl_code,
    m.test_lang_code = v.test_lang_code,
    m.active_flag = 'Y', -- if we are touching this record, it is to be active.
    m.error_message = NULL, -- refresh these, to properly reconsider records.
    m.create_date = SYSDATE,
    m.record_id = intf_lpa_master_seq.NEXTVAL,
    m.process_row = 'U',
    m.last_update_date = SYSDATE,
    m.last_update_user = 'PRE_PROCESS_LPA - UPDATE',
    -- m.job_id = c_run_id ,
    m.validation_step = NULL, -- refresh these, to properly reconsider records.
    m.v_student_id = v.v_student_id,
    m.v_test_id = v.v_test_id,
    m.v_lang_cd = v.v_lang_cd,
    m.v_plc = v.v_plc,
    m.valid_test_date = v.valid_test_date,
    -- m.school_year = v.schloo_year,
    -- m.school_id = v.school_id,
    m.valid_src_stu_id = v.valid_src_stu_id,
    m.test_code = v.test_code
    WHEN NOT MATCHED
    THEN
    INSERT (
    m.std_district_student_id,
    m.std_grade_code,
    m.sub_test,
    m.test_date,
    m.performance_lvl_code,
    m.test_lang_code,
    m.active_flag,
    m.error_message,
    m.create_date,
    m.record_id,
    m.process_row,
    m.last_update_date,
    m.last_update_user,
    -- m.job_id,
    m.validation_step,
    m.v_student_id,
    m.v_test_id,
    m.v_lang_cd,
    m.v_plc,
    m.valid_test_date,
    -- m. school_year,
    -- m. school_id,
    m.valid_src_stu_id,
    m.test_code)
    VALUES (
    v.std_district_student_id,
    v.std_grade_code,
    v.sub_test,
    v.test_date,
    v.performance_lvl_code,
    v.test_lang_code,
    'Y',
    NULL,
    SYSDATE,
    intf_lpa_master_seq.NEXTVAL,
    'I',
    SYSDATE,
    'PRE_PROCESS_LPA - INSERT',
    -- c_run_id,
    NULL,
    v.v_student_id,
    v.v_test_id,
    v.v_lang_cd,
    v.v_plc,
    v.valid_test_date,
    -- v. school_year,
    -- v. school_id,
    v.valid_src_stut_id,
    v.test_code);
    Error Message :
    ORA-06553 : PLS-306:wrong number or types of arguments in call to 'V'

    There are a couple of thngs wrong here. In the when matched insert column list, you cannot qualify the field name with the table alias. It should be just:
    insert (std_district_student_id, std_grade_code, sub_test ...)Are v_student_id, v_test_id, v_lang_cd, and v_plc really columns in the intf_lpa_master table? I am more used to seeing v_name as a variable naming convention than a column name, but I could be wrong.
    John

  • Instead of trigger is NOT firing for merge statements in Oracle 10gR2

    The trigger fires fine for a update statement, but not when I use a merge statement
    with an update clause. Instead I get the normal error for the view ( which is a union all view, and therefore not updatable.)
    The error is :-
    ORA-01733: virtual column not allowed here
    oracle release is 10.2.0.2 for AIX 64L
    Is this a known bug ?
    I've used a multi-table insert statement to work around the problem for inserts, but
    for updates, I'd really like to be able to use a merge statement instead of an update.
    Mark.

    This is my cut-down version :-
    In this case case I'm getting an :-
    ORA-01446: cannot select ROWID from, or sample, a view with DISTINCT, GROUP BY, etc.
    rather then the ora-01733 error I get in the real code ( which is an update from an involved
    XML expression - cast to a table form)
    create table a ( a int primary key , b char(30) ) ;
    create table b ( a int primary key , b char(30) ) ;
    create view vw_a as
    select *
    from a
    union all
    select *
    from b ;
    ALTER VIEW vw_a ADD (
    PRIMARY KEY
    (a) DISABLE);
    DROP TRIGGER TRG_IO_U_ALL_AB;
    CREATE OR REPLACE trigger TRG_IO_U_ALL_AB
    instead of update ON vw_a
    for each row
    begin
    update a targ
    set b = :new.b
    where targ.a = :new.a
    if SQL%ROWCOUNT = 0
    then
         update b targ
         set b      = :new.b
         where targ.a = :new.a
    end if ;
    end ;
    insert into a values (1,'one');
    insert into a values (2,'two');
    insert into a values (3,'three');
    insert into b values (4,'quatre');
    insert into b values (5,'cinq');
    insert into b values (6,'six');
    commit;
    create table c as select a + 3 as a, b from a ;
    commit;
    merge into vw_a targ
    using (select * from c ) src
    on ( targ.a = src.a )
    when matched
    then update
    set targ.b = src. b
    select * from vw_a ;
    rollback ;
    update vw_a b
    set b = ( select c.b from c where b.a = c.a )
    where exists ( select c.b from c where b.a = c.a ) ;
    select * from vw_a ;
    rollback ;

  • Need suggestion in MERGE Statement

    Hi,
    I have a scenario like, I have one table T1 with 500,000 to 700,000 records and now I want to check the other table T2 if record exists or not. If record exists with opposite amount ( - or + ) as compare with first table T1 then I need to insert this record from second table T2 to first table T1 and if record is not exists then need to update the flag with 'N' in first table T1. Can MERGE statement will be better solution in this scenario?
    Thanks,

    Here's something generic:
    insert into T1 (columns...)
    select (columns...)
    from   T1
    where  exists (select 1
                   from   T2
                   where  T2.some_key = T1.some_key
                   and    T2.some_value + T1.some_value = 0);
    update T1
    set    some_flag = 'N'
    where  not exists (select 1
                       from   T2
                       where  T2.some_key = T1.some_key);Sure seems odd though. Are you sure you wrote your original question correctly?

  • Help needed in MERGE statement

    Hi,
    I am new to PL/SQL, I want to update a table called "final_test" based on the below query result.
    1. I want to check whether that particular record is present or not in my "final_test" table.
    2. If its present in the "final_test" table and the process_status got changed then I want to update that alone in my "final_test" table.
    3. If its not present then I want to insert that record into my "final_test" table.
    Basically I am retrieving the report and its status for a particular date.
    select
    b.id,
    a.name,
    a.t_name,
    c.process_status,
    c.time_process
    from rep_tab_map a, j_tab_map b, proc_status c
    where a.t_name=b.t_name
    and b.id=c.id (+)
    and trunc(c.date_start)=trunc(sysdate -1)
    group by a.name,b.id,c.process_status,c.time_process,a.t_name
    order by 2
    I thought of using Merge statement but i am not sure what i have to use in ":USING" and "ON" clause.
    Please help me with MERGE or with someother way.
    Thanks

    Assuming final_test has same structure as select list in your query:
    merge
      into final_test a
      using (
             select  b.id,
                     a.name,
                     a.t_name,
                     c.process_status,
                     c.time_process
               from  rep_tab_map a,
                     j_tab_map b,
                     proc_status c
               where a.t_name=b.t_name
                 and b.id=c.id(+)
                 and trunc(c.date_start)=trunc(sysdate -1)
               group by a.name,b.id,c.process_status,c.time_process,a.t_name
            ) b
      on (b.id = a.id)
      when matched then update set a.name = case a.process_status
                                              when b.process_status then a.name
                                              else b.name
                                            end,
                                   a.t_name = case a.process_status
                                                when b.process_status then a.t_name
                                                else b.t_name
                                              end,
                                   a.process_status = b.process_status,
                                   a.time_process = case a.process_status
                                                      when b.process_status then a.time_process
                                                      else b.time_process
                                                    end
      when not matched then insert(
                                   a.id,
                                   a.name,
                                   a.t_name,
                                   a.process_status,
                                   a.time_process
                            values(
                                   b.id,
                                   b.name,
                                   b.t_name,
                                   b.process_status,
                                   b.time_process
    /SY.

  • Help needed in the Merge Statement

    Hi All,
    I am using MERGE statement in my program. I want to maintain the log for the duplicate reords mean maintain the log for those reocrds which are updated in the merge statement.
    Can any one help me in this that how can i maintain the log?
    Thanks for your help in advance.
    kind Regards,

    http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:35615502072484

  • How to use Inner join of table as Source in Merge statement in SQL

    Hi All,
        I am trying to make source as multiple tables output using Join while coding there is no any syntax error but when i am executing this statement is giving following error
    Following is the query 
    Merge Into EmpDept Target
    Using (select E.Address,e.Design,e.EmailId,e.EmpId,e.Ename,e.ManagerId, e.Salary,D.DeptId,D.DeptName,D.Location from Employee E Inner join Dept D on E.DeptId=D.DeptId )As Source (Address,Design,EmailId,EmpId,EName,ManagerId,Salary,DeptId,DeptName,Location)
    On Source.EmpId=Target.EmpId
    when not matched then
    Insert (Target.Address,Target.Design,Target.EmailId,Target.EmpId,Target.Ename,Target.ManagerId, Target.Salary,Target.DeptId,Target.DeptName,Target.Location)
    values
    (Address,Design,EmailId,EmpId,EName,ManagerId, Salary,DeptId,DeptName,Location)
    When matched then 
    Update set Target.Address = Source.Address ,Target.Design = Source.Design,Target.EmailId      = Source.EmailId     ,Target.Ename       = Source.Ename      ,Target.ManagerId = Source.ManagerId , Target.Salary        = Source.Salary       ,Target.DeptId      = Source.DeptId      ,Target.DeptName = Source.DeptName ,Target.Location    = Source.Location;
    This is error while executing the above merge statement 
    The insert column list used in the MERGE statement cannot contain multi-part identifiers. Use single part identifiers instead.
    Please suggest me where i am wrong.. 
    Niraj Sevalkar

    MERGE INTO EmpDept Target
    Using (SELECT E.Address,
    e.Design,
    e.EmailId,
    e.EmpId,
    e.Ename,
    e.ManagerId,
    e.Salary,
    D.DeptId,
    D.DeptName,
    D.Location
    FROM Employee E
    INNER JOIN Dept D
    ON E.DeptId = D.DeptId) AS Source (Address, Design, EmailId, EmpId, EName, ManagerId, Salary, DeptId, DeptName, Location)
    ON Source.EmpId = Target.EmpId
    WHEN NOT matched THEN
    INSERT (Address,
    Design,
    EmailId,
    EmpId,
    Ename,
    ManagerId,
    Salary,
    DeptId,
    DeptName,
    Location)
    VALUES (Address,
    Design,
    EmailId,
    EmpId,
    EName,
    ManagerId,
    Salary,
    DeptId,
    DeptName,
    Location)
    WHEN matched THEN
    UPDATE SET Address = Source.Address,
    Design = Source.Design,
    EmailId = Source.EmailId,
    Ename = Source.Ename,
    ManagerId = Source.ManagerId,
    Salary = Source.Salary,
    DeptId = Source.DeptId,
    DeptName = Source.DeptName,
    Location = Source.Location;

Maybe you are looking for

  • How to see the change logs for billing document

    Dears, Could you please how to see the change logs for billing document. My client is using ECC 6.0 & if i use VF03 > Environment > changes > does not show the changes i had made. Thanks in advance Ranjan

  • ABAP OO: traffic lights in ALV

    Hello, Instead of going the easy way, I decided to practise a bit of ABAP OO (which I am still quite unfamiliar with), and do ALV list to my new report by using CL_SALV_TABLE class. This seems to be quite clear if I just follow Rich's great instructi

  • Aluminum Keyboard spill

    After much web browsing searching for solutions, I think I found an answer to the sticky keys leftover from (literally) the drops of fine ale that found its way onto my keyboard. First, take the keys off as described here: http://skeltoac.com/2007/10

  • Custom Preference Panel for quick access

    I love that I can hit CMD-K to get to preferences and toggle things like Scale Strokes & Effects. But that's pretty much the only one I toggle in that area. Request: A custom control panel (keyboard shortcut accessible) so I can quickly access freque

  • Jerky playback in elements organizer

    Hoping some one can help out here.  I've downloaded the trial version of Premiere elements to edit videos captured with a Kodak playsport.  When I view the captured video in the organizer, it a very jerky playback.  When I play back using Windows med