Update statement with multiple joints

Hello

I use Oracle 12 c and here my Question:

/*

ledgerstb is an Oracle the ITO (TransNo column is the primary key)

vledgerstb_gtt is a global temporary Table

vledgervc_gtt is a global temporary Table

*/

UPDATE

(, SELECT ledgerstb. TransNoVC AS TransNoVC_Old,

vledgervc_gtt.transnovc AS TransNoVC_New

OF ledgerstb

INNER JOIN vledgerstb_gtt ON ledgerstb. TransNo = vledgerstb_gtt.transnostb

INNER JOIN vledgervc_gtt ON ledgerstb. STBNo = vledgervc_gtt. STBNo

) T

SET T.TransNoVC_OLD = T.TransNoVC_NEW;

This update statement gives the following error message:

Error report-

ORA-01779: cannot modify a column that is mapped to a table not preserved key

ORA-06512: at "RELYC. STBPKG', line 597

ORA-06512: at line 201 level

01779 00000 - 'impossible to change a column that is mapped to a non-preserved table at key'

* Cause: An attempt was made to insert or update columns in a join finds out who

map to a table not kept the key.

* Action: Change the directly underlying base tables.

For your reference, the following result internal instruction select (in blue color police) give;

TransNo: 1 STBNo: VAAAABM315711131

TransNo: STBNo 2: VAAAABM315711214

TransNo: STBNo 3: VAAAABM315711262

TransNo: STBNo 4: VAAAABM316410986

Please suggest if I'm doing something wrong or it is not possible to update the table like that.

(I know that I can use ForAll Update statement, but I do not want to use Collections here.)

Thank you carine, finally I found my answer,

the update query requires that each record that will be updated should be updated only once. so if I do join 1<->1 it updates successfully.

Thanks to all who contributed, or at least tried. Thanks again.

Tags: Database

Similar Questions

  • Update statement with joins of tables and where Clause

    Hi, I have MS SQL background and I try to execute an update statement in Oracle with joins of tables. However, the syntax below does not work but I think it works for MS SQL.

    Basically, the base table must be attached to a master table trend with monthly snapshots, an account will be only an entry for a given date monthly. Where clause must be limited to accounts within a certain range of interest rates.

    The first approach returns command SQL ORA-00933 not correctly completed, and the second approach returns ORA-01427 row below query returns multiple rows. Can anyone help? Thanks in advance!



    1:

    Update PenaltyAll
    Set a.indicator = month (b.)
    of PenaltyAll an inner join Master b on a.acctno = b.accountnumber
    where a.monthend='01/31/2009' and b.date='12/31/2008' and b.apr < 20

    2:

    Update PenaltyAll
    adjustment indicator =
    (select to_char (b., 'MM')
    of PenaltyAll an inner join Master b on a.acctno = b.accountnumber
    "where to_char (a.monthend,'mm/dd/yyyy ') = 31 January 2009"
    (et to_char(b.date,'mm/dd/yyyy') = December 31, 2008 "
    and b.apr < 20)

    Published by: sqlrookie on August 21, 2009 07:04

    I edited my post, that was my mistake, ANC you try now?

  • Update statement with Date field

    I'm trying to run an update statement and I want to update the date in the format:

    04/05/2010 12:31:54

    If I run this query on the double it appears correctly: select the double to_char(sysdate,'DD/MM/YYYY HH12:MI:SS PM')

    If I run this well query on my table, I get a 'not one month valid' error.


    UPDATE WR_MEASURE_VALUE SET HOST_CORRECTED_VALUE = 35,
    HOST_CORRECTED_DATE = to_char(sysdate,'DD/MM/YYYY HH12:MI:SS PM') WHERE WR_MEASURE_VALUE_OID = 474066


    what I am doing wrong and how can I get my update statement to update date correctly in the ' HH12:MI JJ/MM/AAAA: SS PM' form?

    Thank you


    Guess all I had to say was HOST_CORRECTED_DATE = SYSDATE

    Thanks anyway

    Published by: Rich75 on May 5, 2010 07:10

    If you want:

    'UPDATE WR_MEASURE_VALUE SET ' || p_FieldToInsertUpdate || '=' || v_ValueAfterFactored || ',' ||
                                      v_DateToUpdate || '= to_date(''' || to_char(sysdate, 'dd/mm/yyyy hh12:mi:ss PM') || ''', ''dd/mm/yyyy hh12:mi:ss PM'')'||
    ' WHERE WR_MEASURE_VALUE_OID= ' || v_MeasureValueOID_arr(i) ||
    ' AND ' || v_Current_25Month_Value || ' != ' || v_DisplayValue;
    

    But... smacks of dubious design if you do not know what columns you update at compile time, IMO.

  • Update statement with join other tables

    Hello
    I have two table is one that contains the xml file, basically, I need to read the xml file, then upgrade to another table based on certain conditions.
    UPDATE TRCB_XBRL_STG_2 STG 
    SET PROFIT = 
      case when xbrl.isconsolidatedacc='Y' and EXTRACTVALUE(XBRL.XBRLFILE,'//PROFIT ', 'xmlns:acra="..."') is not null
      THEN EXTRACTVALUE(XBRL.XBRLFILE,'//PROFIT ', 'xmlns:acra="..."')
      WHEN XBRL.ISCONSOLIDATEDACC='N' AND EXTRACTVALUE(XBRL.XBRLFILE,'//PROFIT ', 'xmlns:acra="..') IS NOT NULL
      THEN extractValue(XBRL.xbrlfile,'//PROFIT ', 'xmlns:acra=".."')
      ELSE STG.PROFIT
      END,
      SET REVENUE= 
      case when xbrl.isconsolidatedacc='Y' and EXTRACTVALUE(XBRL.XBRLFILE,'//REVENUE', 'xmlns:acra="..."') is not null
      THEN EXTRACTVALUE(XBRL.XBRLFILE,'//REVENUE.', 'xmlns:acra="..."')
      WHEN XBRL.ISCONSOLIDATEDACC='N' AND EXTRACTVALUE(XBRL.XBRLFILE,'//REVENUE', 'xmlns:acra="..') IS NOT NULL
      THEN extractValue(XBRL.xbrlfile,'//REVENUE', 'xmlns:acra="REVENUE"')
      ELSE STG.REVENUE
      END,
      ....
      ... (around 100 columns)
    FROM  TRCB_XBRL xbrl ,TRCB_XBRL_STG_2 STG 
    WHERE STG.XBRL_ID = XBRL.XBRL_ID 
    About 100 the number of columns, please someone suggest how to use the update with a join of two tables.

    Hello

    If all the values needed to update a given line from table_x come from the same line of table_y (or in the same row of a result set of a query on a number any of tables), then you can do something like this:

    UPDATE  table_x  x
    SET     (col1, col2, col3, ...)
    =     (
             SELECT  NVL (y.col1, x.col1)
             ,         NVL (y.col2, x.col2)
             ,         NVL (y.col3, x.col3)
             FROM    table_y  y
             WHERE   x.pkey   = y.expr
             AND         ...
         )
    WHERE   ...
    ;
    

    If the WHERE clause is based on the same line of table_y, then it will be probably easier and more efficient to use the MERGER instead of UPDATE.

    I hope that answers your question.
    If not, post a small example of data (CREATE TABLE and only relevant columns, INSERT statements) for all of the tables involved and the results desired from these data.
    In the case of a DML (UPDATE), for example, the sample data should show what looks like the tables before the DML, and the results will be the content of the or the tables changed after the DML.
    Explain, using specific examples, how you get these results from these data.
    Always say what version of Oracle you are using (for example, 11.2.0.2.0).
    See the FAQ forum {message identifier: = 9360002}

  • Update statement with a subquery

    Hello gurus,

    I am having trouble with an Update query.  Basically, I want to just update some documents in my DB Oracle (version 11.2.0.2) according to certain criteria in my WHERE clause.  That's what I have below.

    Select count (*)

    From Table_1 a, b Table_2

    Where a.unique_id = b.unique_id and b.Doc_Type = 'AP' and a.Doc_Title is null;  < == returns 540 records

    Update Table_1

    Define Doc_Title = 'data '.

    Where Doc_Title = (select a.Doc_Title

    from Table_1 a, b Table_2

    where a.unique_id = b.unique_id and b.Doc_Type = 'AP' and a.Doc_Title is null

    A.Doc_Title group);  < == lines updates 0 (I expect it, updated the 540 chronogram my query earlier than I used to check)

    Any ideas?  Thank you!

    Update Table_1 one

    Define Doc_Title = 'data '.

    When there is)

    Select 1

    in Table_2 b

    where a.unique_id = b.unique_id

    and b.Doc_Type = 'AP '.

    and a.Doc_Title is null

    )

    /

    SY.

  • Update statement with dups

    This query has worked well for me, but now the driving table (tt) has duplicates in it, due to an upgrade of database and the client wants to keep duplicates, there is value for them it...

    The problem is that now that I get, you guessed it: ORA-01427: einreihig subquery returns multiple rows

    I need help to be updated so that it can handle multiple lines, duplicates are ok.
    UPDATE /*+ PARALLEL (16) */ UPDATE_TABLE_07092011  ta
                         SET (ta.GO_TO_PERSON, ta.UPDATE_DT) = 
                                       (SELECT /*+ PARALLEL (16) */ tt.GO_TO_PERSON, SYSDATE
                                        FROM DRIVER_TABLE tt
                                        WHERE ta.cust_id = tt.cust_id
                                        AND ta.STAMP_DATE = tt.STAMP_DATE)
                          WHERE EXISTS (SELECT 1
                                       FROM  DRIVER_TABLE tt
                                       WHERE ta.cust_id = tt.cust_id
                                       AND ta.STAMP_DATE = tt.STAMP_DATE
                                       AND (NVL(ta.GO_TO_PERSON, 'X') != NVL(tt.GO_TO_PERSON, 'X')));
    Published by: Kodiak_Seattle on May 10, 2012 11:04

    How about adding "AND ROWNUM = 1" to the first subquery?

  • Update statement with joins

    Hello
    I tried to update the 50 rows in a table using joins

    But the error
    ORA-01732 data manipulation operation not legal on this view
    But the table I worked is not a view
    update
    (
      select *
       from   (Select *from tran where tid in (select TID from isum where settld is null  and oper='ABCD')
    and rec_exists='Y' and status ='A'
    order by prd desc)
    where rownum<51
    )
    set status =null
    Please help thsis

    You cannot update a subquery. To update the table tran instead.

    To select the 50 lines you want, your logic in the WHERE clause of the nesting.

    UPDATE tran
    SET status = NULL
    WHERE ROWID IN ( SELECT ROWID
                        FROM ( SELECT ROWID
                                  FROM tran
                                 WHERE tid IN (SELECT TID FROM isum
                                                WHERE settld IS NULL
                                                  AND oper='ABCD' )
                                   AND rec_exists='Y'
                                   AND status ='A'
                                ORDER BY prd DESC)
                    WHERE ROWNUM < 51 )
    
  • Case statement with multiple queries to the THEN clause

    Y at - it a syntax something like:

    Case

    When A = 1
    Then B: = 2 and C: = 3

    When A = 2
    Then B: = 4 and C: = 5

    Else B: = 6 and C: = 7

    End case;

    where clause can then have multiple assignments?

    Also, how to mark entries as code on this forum?

    TIA,

    Extreme Farley

    You can simplify a bit:

    SQL> declare
      2     a number := 0;
      3     b number := 0;
      4     c number := 0;
      5  begin
      6
      7     Case A
      8          WHEN 1 Then
      9            B := 2;
     10            C := 3;
     11          WHEN 2 Then
     12            B := 4;
     13            C := 5;
     14          Else
     15            B := 6;
     16            C := 7;
     17     End Case;
     18     dbms_output.put_line('A=' || a);
     19     dbms_output.put_line('B=' || b);
     20     dbms_output.put_line('C=' || c);
     21  end;
     22  /
    A=0
    B=6
    C=7
    
    PL/SQL procedure successfully completed.
    
  • Problems with multiple monitors for critical update Windows 7

    Since the update critical October 1, I can no longer run multiple monitors.

    According to the record, this update made changes at the same time the driver for my AMD Radeon 7470 and Dell monitor 1.1 card, and I've updated the software.

    Devices for work and when I pass cables or remove cables. Yet they are simply not recognized as connected.

    Hello Kent,

    Thanks for posting your question on the Microsoft community.

    Thank you for details on the issue.

    This problem may occur because of corrupted or incorrect display settings.

    I suggest you run the hardware and devices Troubleshooter and check.
    Reference:
    Open the hardware and devices Troubleshooter
    http://Windows.Microsoft.com/en-us/Windows7/open-the-hardware-and-devices-Troubleshooter

    Please also read this article and check.
    Work and play better with multiple monitors
    http://Windows.Microsoft.com/en-us/Windows7/work-and-play-better-with-multiple-monitors

    I hope this information helps.

    Please let us know if you need more help.

    Thank you

  • Is possible to write the INSERT statement that fills two columns: 'word' and 'sense' of the file text with multiple lines - in each line is followed word that is the meaning?

    Is possible to write the INSERT statement that fills two columns: 'word' and 'sense' of the file text with multiple lines - in each line is followed word that is the meaning?

    Hello

    2796614 wrote:

    Is possible to write the INSERT statement that fills two columns: 'word' and 'sense' of the file text with multiple lines - in each line is followed word that is the meaning?

    Of course, it is possible.  According to what the text file looks like to, you can create an external table that treats the text file as if it were a table.  Otherwise, you can always read the file in PL/SQL, using the utl_file package and INSERT of PL/SQL commands.

    You have problems whatever you wantt?  If so, your zip code and explain what the problem is.

    Whenever you have any questions, please post a small example of data (CREATE TABLE and only relevant columns, INSERT statements) for all of the tables involved and the exact results you want from these data, so that people who want to help you can recreate the problem and test their ideas.  In this case, also post a small sample of the text involved file.

    If you ask about a DML operation, such as INSERT, then INSERT statements, you post should show what looks like the tables before the DML, and the results will be the content of the table changed after the DML.

    Explain, using specific examples, how you get these results from these data.

    Always say what version of Oracle you are using (for example, 11.2.0.2.0).

    See the FAQ forum: Re: 2. How can I ask a question on the forums?

  • Merger of statement: with several Update statement.

    Hello

    I'm trying under the merge statement. However to get the error "not correctly completed 0ra-00933 sql command.

    In fact, my join conditions are the same, but I wanted to update the different columns based on the different places where clause in the update statement.

    for example.

    FUSION
    IN abc3 tgt
    With the HELP of abc CBC
    WE (src.cust = tgt.cust)
    WHEN MATCHED
    THEN
    UPDATE
    SET tgt.sales = src.sales
    where tgt.cust = 'Cust3'
    UPDATE
    SET tgt.sales1 = src.sales
    where tgt.cust = 'Cust2';

    Please let me know if there is no work around for this.

    Hi, pm

    You can try this please.

    MERGE
     INTO ABC3 TGT
     USING ABC SRC
      ON (src.cust = tgt.cust)
    WHEN MATCHED THEN
    UPDATE SET TGT.SALES = DECODE(TGT.CUST,'Cust3',SRC.SALES,TGT.SALES),
               TGT.SALES1 = DECODE(TGT.CUST,'Cust2',SRC.SALES,TGT.SALES1)
    WHERE TGT.CUST='Cust3' OR tgt.cust='Cust2';
    
  • Need help with update statement to be used in the stored procedure

    I have the following update statement and I get "ORA-06512. Someone of you can help me.

    ----
    UPDATE MO X SET X.MOMODEL = (SELECT Y.MOMODEL FROM MO Y WHERE Y.MOID = A_TEMP_INT3)
    WHERE X.MOID in (UPDATE MO X SET X.MOMODEL = (SELECT Y.MOMODEL FROM MO Y WHERE Y.MOID = A_TEMP_INT3)
    WHERE X.MOID in (A_TEMP_INT1, (select assocchild from mo_association
    Connect prior assocchild = assocparent
    Start with assocparent = A_TEMP_INT1)); (by selecting assocchild in mo_association
    Connect prior assocchild = assocparent
    Start with assocparent = A_TEMP_INT1));
    ----

    Note: A_TEMP_INT1 and A_TEMP_INT3 are the values of cursor and is assigned to numeric values in the code.


    Thanks for all the help in advance.

    Kind regards
    REDA
    WHERE X.MOID IN
     (SELECT ASSOCCHILD   FROM MO_ASSOCIATION
          CONNECT BY PRIOR ASSOCCHILD = ASSOCPARENT
         START WITH ASSOCPARENT = A_TEMP_INT1
         UNION
      SELECT A_TEMP_INT1 FROM DUAL );
    

    Should work.
    VR,
    Sudhakar B.

  • How can I use multiple row subqueries in update statement

    Hai All

    I'm using the Group feature in my update statement... and I need to update several lines so I need to use several rows

    subquery pls tell me how to use multiple row subqueries in update statement


    For example

    while I use it like this I got an error

    Update dail_att set outtime to (select max (r2.ptime) in the temp_att where empcode = r2.enpno and)

    bar code = r2.cardn and group attend_date = r2.pdate by enpno, update, cardn);


    Pls tell me how to use for example


    Thanks and greetings

    Srikkanth.M

    Hello

    for r2 loop p1

    R2 is a line of the cursor,

    Max (R2. PtIMe)? It is always equal to r2.ptime if the select statement returns rows.

  • Performance issue with the Update statement

    Oracle 10204

    I have a problem related to updaing one performance table.
    only 5000 lines should be updated.
    Hir are some details on the tables/M.V concerned:
    TABLE_NAME     LAST_ANALYZED          NUM_ROWS     SAMPLE_SIZE
    PS_RF_INST_PROD     1/20/2010 1:14:22 AM     7194402          7194402
    BL_TMP_INTRNT     1/27/2010 9:08:54 AM     885445          885445
    NAP_INTERNET     1/25/2010 11:47:02 AM     7053990          560777
    I tried to run the update with two options:
    1. with the plan than oracle choose.
    2. with notes I added.
    In both cases I he collapsed after more than an hour.

    Can any one suggest how to speed it up?

    Below are for the two option tkprof.
    Please note that beside the defualt statistics on those tables i also gathered statistics on two column level as followed:
    BEGIN
      SYS.DBMS_STATS.GATHER_TABLE_STATS (
          OwnName        => 'B'
         ,TabName        => 'BL_TMP_INTRNT'
        ,Estimate_Percent  => 100
        ,Degree            => 8
        ,Cascade           => TRUE
        ,No_Invalidate     => FALSE);
    END;
    /
    
    exec dbms_stats.gather_table_stats('B' , 'BL_TMP_INTRNT', cascade=>TRUE, method_opt=>'for columns SERVICE_UID size 254');
    exec dbms_stats.gather_table_stats('B' , 'BL_TMP_INTRNT', cascade=>TRUE, method_opt=>'for columns FIX_IP_USER size 254');
    Plan 1
    UPDATE BL_TMP_INTRNT A
       SET A.FIX_IP_USER =
              (SELECT C.PRODUCT_ID
                 FROM NAP_INTERNET B, PS_RF_INST_PROD C
                WHERE B.INST_PROD_ID = A.SERVICE_UID
                  AND B.SETID = 'SHARE'
                  AND C.INST_PROD_ID = B.NAP_SURF_UID)
     WHERE A.TERM_DESC LIKE '%ip%'
    
    call     count       cpu    elapsed       disk      query    current        rows
    ------- ------  -------- ---------- ---------- ---------- ----------  ----------
    Parse        1      0.03       0.02          0          0          0           0
    Execute      1   1166.64    4803.78   17989002   18792167        117           0
    Fetch        0      0.00       0.00          0          0          0           0
    ------- ------  -------- ---------- ---------- ---------- ----------  ----------
    total        2   1166.67    4803.81   17989002   18792167        117           0
    
    Misses in library cache during parse: 1
    Optimizer mode: FIRST_ROWS
    Parsing user id: 13
    
    Rows     Row Source Operation
    -------  ---------------------------------------------------
          0  UPDATE  BL_TMP_INTRNT (cr=0 pr=0 pw=0 time=2 us)
         46   TABLE ACCESS FULL BL_TMP_INTRNT (cr=586400 pr=22228 pw=0 time=15333652 us)
         15   HASH JOIN  (cr=18170453 pr=17931639 pw=0 time=3991064192 us)
         46    MAT_VIEW ACCESS FULL NAP_INTERNET (cr=5659886 pr=5655436 pw=0 time=988162557 us)
    329499624    MAT_VIEW ACCESS FULL PS_RF_INST_PROD (cr=12545734 pr=12311281 pw=0 time=2636471644 us)
    plan 2
    UPDATE BL_TMP_INTRNT A
       SET A.FIX_IP_USER =
              (SELECT /*+ index(b NAP_INTERNET_PK) index(c PS_RF_INST_PROD_PK)*/ C.PRODUCT_ID
                 FROM NAP_INTERNET B, PS_RF_INST_PROD C
                WHERE B.INST_PROD_ID = A.SERVICE_UID
                  AND B.SETID = 'SHARE'
                  AND C.INST_PROD_ID = B.NAP_SURF_UID)
     WHERE A.TERM_DESC LIKE '%ip%'
    
    call     count       cpu    elapsed       disk      query    current        rows
    ------- ------  -------- ---------- ---------- ---------- ----------  ----------
    Parse        1      0.02       0.02          0          0          0           0
    Execute      1   4645.25    4613.70      95783   39798095        735           0
    Fetch        0      0.00       0.00          0          0          0           0
    ------- ------  -------- ---------- ---------- ---------- ----------  ----------
    total        2   4645.27    4613.73      95783   39798095        735           0
    
    Misses in library cache during parse: 1
    Optimizer mode: FIRST_ROWS
    Parsing user id: 13
    
    Rows     Row Source Operation
    -------  ---------------------------------------------------
          0  UPDATE  BL_TMP_INTRNT (cr=0 pr=0 pw=0 time=1 us)
        473   TABLE ACCESS FULL BL_TMP_INTRNT (cr=10461 pr=10399 pw=0 time=4629385 us)
        408   MAT_VIEW ACCESS BY INDEX ROWID PS_RF_INST_PROD (cr=39776109 pr=85381 pw=0 time=4605125045 us)
       1350    NESTED LOOPS  (cr=39784584 pr=84974 pw=0 time=4601874262 us)
        470     MAT_VIEW ACCESS BY INDEX ROWID NAP_INTERNET (cr=23569112 pr=50472 pw=0 time=2544364336 us)
        470      INDEX FULL SCAN NAP_INTERNET_PK (cr=23568642 pr=50005 pw=0 time=2540300981 us)(object id 11027362)
        408     INDEX FULL SCAN PS_RF_INST_PROD_PK (cr=16215472 pr=34502 pw=0 time=2057500175 us)(object id 10980137)
    
    
    Elapsed times include waiting on following events:
      Event waited on                             Times   Max. Wait  Total Waited
      ----------------------------------------   Waited  ----------  ------------
      db file scattered read                       1300        0.50          4.27
      db file sequential read                     85707        0.51         29.88
      latch: cache buffers chains                     1        0.00          0.00
      log file sync                                   1        0.00          0.00
      SQL*Net break/reset to client                   1        0.00          0.00
      SQL*Net message to client                       1        0.00          0.00
      SQL*Net message from client                     1       14.73         14.73
    ********************************************************************************

    The problem in your update statement that is the query in your set clause is executed many times that there are lines in BL_TMP_INTRNT of 'intellectual property' in their column of term_desc. You mentioned there are about 5000, then the query joining NAP_INTERNET with PS_RF_ISNT_PROD is begun 5000 times.
    The trick is to join only once, be updated using join views - provided that it is preserved - key or by using the merge statement.

    Here is an example:

    SQL> create table bl_tmp_intrnt (fix_ip_user,service_uid,term_desc)
      2  as
      3   select level
      4        , level
      5        , 'aipa'
      6     from dual
      7  connect by level <= 5000
      8  /
    
    Tabel is aangemaakt.
    
    SQL> create table nap_internet (inst_prod_id,setid,nap_surf_uid)
      2  as
      3   select level
      4        , 'SHARE'
      5        , level
      6     from dual
      7  connect by level <= 10
      8  /
    
    Tabel is aangemaakt.
    
    SQL> create table ps_rf_inst_prod (product_id,inst_prod_id)
      2  as
      3   select level
      4        , level
      5     from dual
      6  connect by level <= 10
      7  /
    
    Tabel is aangemaakt.
    
    SQL> exec dbms_stats.gather_table_stats(user,'bl_tmp_intrnt')
    
    PL/SQL-procedure is geslaagd.
    
    SQL> exec dbms_stats.gather_table_stats(user,'nap_internet')
    
    PL/SQL-procedure is geslaagd.
    
    SQL> exec dbms_stats.gather_table_stats(user,'ps_rf_inst_prod')
    
    PL/SQL-procedure is geslaagd.
    
    SQL> set serveroutput off
    SQL> update ( select a.fix_ip_user
      2                , c.product_id
      3             from bl_tmp_intrnt a
      4                , nap_internet b
      5                , ps_rf_inst_prod c
      6            where a.term_desc like '%ip%'
      7              and a.service_uid = b.inst_prod_id
      8              and b.setid = 'SHARE'
      9              and b.nap_surf_uid = c.inst_prod_id
     10         )
     11     set fix_ip_user = product_id
     12  /
       set fix_ip_user = product_id
           *
    FOUT in regel 11:
    .ORA-01779: cannot modify a column which maps to a non key-preserved table
    

    Join is one key kept in the case of b.inst_prod_id and c.inst_prod_id are unique. Please refer to the documentation for more information here: http://download.oracle.com/docs/cd/B19306_01/server.102/b14231/views.htm#sthref3055

    SQL> alter table nap_internet add primary key (inst_prod_id)
      2  /
    
    Tabel is gewijzigd.
    
    SQL> alter table ps_rf_inst_prod add primary key (inst_prod_id)
      2  /
    
    Tabel is gewijzigd.
    
    SQL> update /*+ gather_plan_statistics */
      2         ( select a.fix_ip_user
      3                , c.product_id
      4             from bl_tmp_intrnt a
      5                , nap_internet b
      6                , ps_rf_inst_prod c
      7            where a.term_desc like '%ip%'
      8              and a.service_uid = b.inst_prod_id
      9              and b.setid = 'SHARE'
     10              and b.nap_surf_uid = c.inst_prod_id
     11         )
     12     set fix_ip_user = product_id
     13  /
    
    10 rijen zijn bijgewerkt.
    
    SQL> select * from table(dbms_xplan.display_cursor(null,null,'allstats last'))
      2  /
    
    PLAN_TABLE_OUTPUT
    --------------------------------------------------------------------------------------------------------------------------------------
    SQL_ID  c7nqbxwzpyq5p, child number 0
    -------------------------------------
    update /*+ gather_plan_statistics */        ( select a.fix_ip_user               , c.product_id            from bl_tmp_intrnt
    a               , nap_internet b               , ps_rf_inst_prod c           where a.term_desc like '%ip%'             and
    a.service_uid = b.inst_prod_id             and b.setid = 'SHARE'             and b.nap_surf_uid = c.inst_prod_id        )
    set fix_ip_user = product_id
    
    Plan hash value: 1745632149
    
    ---------------------------------------------------------------------------------------------------------------------------------------
    | Id  | Operation                      | Name            | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
    ---------------------------------------------------------------------------------------------------------------------------------------
    |   1 |  UPDATE                        | BL_TMP_INTRNT   |      1 |        |      0 |00:00:00.01 |      32 |       |       |          |
    |   2 |   NESTED LOOPS                 |                 |      1 |     10 |     10 |00:00:00.01 |      21 |       |       |          |
    |   3 |    MERGE JOIN                  |                 |      1 |     10 |     10 |00:00:00.01 |       9 |       |       |          |
    |*  4 |     TABLE ACCESS BY INDEX ROWID| NAP_INTERNET    |      1 |     10 |     10 |00:00:00.01 |       2 |       |       |          |
    |   5 |      INDEX FULL SCAN           | SYS_C00132995   |      1 |     10 |     10 |00:00:00.01 |       1 |       |       |          |
    |*  6 |     SORT JOIN                  |                 |     10 |    250 |     10 |00:00:00.01 |       7 |   267K|   256K|  237K (0)|
    |*  7 |      TABLE ACCESS FULL         | BL_TMP_INTRNT   |      1 |    250 |   5000 |00:00:00.01 |       7 |       |       |          |
    |   8 |    TABLE ACCESS BY INDEX ROWID | PS_RF_INST_PROD |     10 |      1 |     10 |00:00:00.01 |      12 |       |       |          |
    |*  9 |     INDEX UNIQUE SCAN          | SYS_C00132996   |     10 |      1 |     10 |00:00:00.01 |       2 |       |       |          |
    ---------------------------------------------------------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       4 - filter("B"."SETID"='SHARE')
       6 - access("A"."SERVICE_UID"="B"."INST_PROD_ID")
           filter("A"."SERVICE_UID"="B"."INST_PROD_ID")
       7 - filter("A"."TERM_DESC" LIKE '%ip%')
       9 - access("B"."NAP_SURF_UID"="C"."INST_PROD_ID")
    
    32 rijen zijn geselecteerd.
    
    SQL> rollback
      2  /
    
    Rollback is voltooid.
    

    And it's your current statement. Please note the number of 5000 in the column begins:

    SQL> UPDATE /*+ gather_plan_statistics */ BL_TMP_INTRNT A
      2     SET A.FIX_IP_USER =
      3            (SELECT C.PRODUCT_ID
      4               FROM NAP_INTERNET B, PS_RF_INST_PROD C
      5              WHERE B.INST_PROD_ID = A.SERVICE_UID
      6                AND B.SETID = 'SHARE'
      7                AND C.INST_PROD_ID = B.NAP_SURF_UID)
      8   WHERE A.TERM_DESC LIKE '%ip%'
      9  /
    
    5000 rijen zijn bijgewerkt.
    
    SQL> select * from table(dbms_xplan.display_cursor(null,null,'allstats last'))
      2  /
    
    PLAN_TABLE_OUTPUT
    --------------------------------------------------------------------------------------------------------------------------------------
    SQL_ID  f1qtnpa0nmbh8, child number 0
    -------------------------------------
    UPDATE /*+ gather_plan_statistics */ BL_TMP_INTRNT A    SET A.FIX_IP_USER =           (SELECT
    C.PRODUCT_ID              FROM NAP_INTERNET B, PS_RF_INST_PROD C             WHERE B.INST_PROD_ID
    = A.SERVICE_UID               AND B.SETID = 'SHARE'               AND C.INST_PROD_ID =
    B.NAP_SURF_UID)  WHERE A.TERM_DESC LIKE '%ip%'
    
    Plan hash value: 3190675455
    
    -----------------------------------------------------------------------------------------------------------
    | Id  | Operation                     | Name            | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
    -----------------------------------------------------------------------------------------------------------
    |   1 |  UPDATE                       | BL_TMP_INTRNT   |      1 |        |      0 |00:00:00.10 |    5076 |
    |*  2 |   TABLE ACCESS FULL           | BL_TMP_INTRNT   |      1 |    250 |   5000 |00:00:00.01 |       7 |
    |   3 |   NESTED LOOPS                |                 |   5000 |      1 |     10 |00:00:00.02 |      24 |
    |*  4 |    TABLE ACCESS BY INDEX ROWID| NAP_INTERNET    |   5000 |      1 |     10 |00:00:00.01 |      12 |
    |*  5 |     INDEX UNIQUE SCAN         | SYS_C00132995   |   5000 |      1 |     10 |00:00:00.01 |       2 |
    |   6 |    TABLE ACCESS BY INDEX ROWID| PS_RF_INST_PROD |     10 |     10 |     10 |00:00:00.01 |      12 |
    |*  7 |     INDEX UNIQUE SCAN         | SYS_C00132996   |     10 |      1 |     10 |00:00:00.01 |       2 |
    -----------------------------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       2 - filter("A"."TERM_DESC" LIKE '%ip%')
       4 - filter("B"."SETID"='SHARE')
       5 - access("B"."INST_PROD_ID"=:B1)
       7 - access("C"."INST_PROD_ID"="B"."NAP_SURF_UID")
    
    29 rijen zijn geselecteerd.
    

    Kind regards
    Rob.

  • need help with the Update statement

    Hello
    I received a question in a course and I tried my best to respond, and now my brain is giving. I would really appreciate help with the update statement. I don't mind if you do not validate a solution, a little nudge in the right direction would be really useful. I'll post that I got.

    THE QUESTION
    / * For these agents disabled on more than seven missions, change their date of deactivation of the first date of deactivation of all the agents that have been activated in the same year as the agent that you update currently.
    */

    I have it divided into parts, here is my select statement to agents disabled on more than 7 missions, which produces the deactivation_dates in the agents table that I want to update...
    SELECT
    s.deactivation_date
    FROM
    (
    SELECT
    a.deactivation_date,
    count(m.mission_id) as nomissions
    FROM
    agents a
    INNER JOIN
    missions_agents m
    on
    a.agent_id=m.agent_id
    GROUP BY
    a.deactivation_date
    ) s
    WHERE
    s.nomissions>7 AND s.deactivation_date IS NOT NULL
    .. .and the code for the first date of deactivation for each year of activation agent
    select 
    a2.deactivation_date
    from
    agents a2
    where a2.deactivation_date= 
    (
    select min(a.deactivation_date)
    from 
    agents a
    where to_number(to_char(a.activation_date,'YYYY'))=to_number(to_char(a2.activation_date,'YYYY'))
    )
    ..... I am not real to marry these two statements together in the Update statement. I can't extract each date of deactivation produced in the first select statement and their match against the first date of deactivation in the year they have been activated for the second select statement.

    Any help greatly appreciated... :))

    I began to wonder how things would :)

    user8695469 wrote:
    First of all why he chooses the date the earliest of all agents

    UPDATE  AGENTS_COPY AC /* (1) */
    SET     DEACTIVATION_DATE = (
    SELECT  MIN(AGS.DEACTIVATION_DATE)
    FROM    AGENTS_COPY  AGS
    ,       AGENTS_COPY AC /* (2) */
    WHERE   TRUNC(AGS.ACTIVATION_DATE,'YEAR') = TRUNC(AC.ACTIVATION_DATE,'YEAR') /* (3) */
    )
    

    He recovers as soon as the subquery has not been correctly set in the SET clause. It seems you are trying to update a correlated, but we are still having a conceptual shift. I have added a few comments to your code above and below will explain.

    (1): when you do a correlated update it is useful to the table alias that you did right here.

    (2): this table statement is not necessary and is the reason why the FIRST deactivation date is selected. The alias that you use (3) refers to THIS table, not the one defined in the update statement. Remove the line indicated by (2) in the FROM clause and a correlated update will happen.

    and secondly why is it to update each row, when I thought that I'm just the lines where the agents are disabled and missions > 7? Pointers on where I'm wrong would be very appreciated. (SQL = stupid query language!) :)

    user8695469 wrote: then why is it to update each row, when I thought that I'm just the lines where the agents are disabled and missions > 7? Pointers on where I'm wrong would be very appreciated. (SQL = stupid query language!) :)

    
    WHERE EXISTS
    (
    SELECT
    a.agent_id,
    count(m.mission_id)
    FROM
    agents a
    /* INNER JOIN AC ON AC.AGENT_ID = A.AGENT_ID */
    INNER JOIN
    missions_agents m
    ON
    a.agent_id=m.agent_id
    GROUP BY
    a.agent_id,
    a.deactivation_date
    HAVING
    count(m.mission_id)>7 AND a.deactivation_date IS NOT NULL
    )
    

    Once again this problem is similar to the question above that a correlation update doesn't work. Test existence of lines in an EXISTS subquery. Since your subquery is not related to the table that you are trying to update, it will be always return a line and, therefore, it returns true for EACH LINE in the AGENTS table. To limit the game to only agents > 7 missions results, you need to add a join condition that references the table in your update statement. I added one above (with comments) as a sample.

    I recommend you look over all material that you have associated with correlated subqueries, including documents that I posted above. This seems to be what you're having the problem more with. If you need me to explain the concept of correlated queries any better please let me know.

    Thank you!

Maybe you are looking for