Dynamic Update statements

Hello,
I have one SP to do DMLs. This SP works fine without any problem, but for Update I have problem to construct. The update statement should be constructed depending on the values.
For example, in a table we may have so many columns, but only few non primary key columns are updated. The SP is given below.
Following is the update statement. the set_nk_update_cols should be dynamic.
   '    if rec.operation$ = ''UN'' then ' ||
                 '      update <owner>.' || p_target ||
                 '         set ' || replace(set_nk_update_cols,'= ','= rec.') ||
                 '       where (' || pk_target || ') = (select rec.' || replace(pk_target,',',',rec.') ||
                 '                                        from dual ' ||

I just did something like this not long ago
The trick is to build your 2 columns lists using LISTAGG seperately.
1) build your PK col list. Look into dba_ind_columns for this.
2) build your full col list. Look into dba_tab_columns
3) splice them all together in the right place:  ie  PK list is:  where col1 and col2 and col3 .... etc.  Full list is: select col1, col2, col3 ... etc.
[edit]
Something else you may want to do to make things more "readable"
WITH w_template AS
   ( SELECT TO_CLOB(
         RTRIM(q'[UPDATE <table_name>           ]')||CHR(10)||
         RTRIM(q'[   SET                        ]')||CHR(10)||
         RTRIM(q'[<set_cols>                    ]')||CHR(10)||
         RTRIM(q'[ WHERE                        ]')||CHR(10)||
         RTRIM(q'[<where_cols>                  ]')||CHR(10)||
         RTRIM(q'[;                             ]')||CHR(10)
         ) tform
     FROM dual
   w_main AS (
      SELECT DISTINCT
               dtc.table_name,
               LISTAGG ( ?? )  set_cols,
               LISTAGG ( ?? )  where_cols
         FROM dba_tab_columns dtc,
              dba_ind_columns dic
        WHERE ???
Select replace ( replace ( replace(
                              w_template, '<table_name>', table_name ),
                     '<set_cols>', set_cols ),
            '<where_cols>', where_cols )
  from w_template t,
       w_main;
Something like that, anyway ..
Sorry, I haven't got much free time to play with this at the moment, but hopefully this gives you (or somebody else?) a direction you could take.
[/edit]

Similar Messages

  • Dynamic UPDATE statement with parameters for column names.

    Hello,
    On this* website I read "The SQL string can contain placeholders for bind arguments, but bind values cannot be used to pass in the names of schema objects (table or column names). You may pass in numeric, date, and string expressions, but not a BOOLEAN or NULL literal value"
    On the other hand, in this Re: execute immediate with dynamic column name update and many other
    posts people use EXECUTE IMMEDIATE to create a dynamic UPDATE statement.
    dynSQL:='UPDATE CO_STAT2 CO SET CO.'||P_ENT_B_G_NAME||' = '||P_ENT_E_G_WE||'
    WHERE ST IN
    (SELECT ST FROM STG_CO_STAT2_TEST CO WHERE
    '||P_ST||' = CO.ST AND
    CO.'||P_ENT_E_G_NAME||' > '||P_ENT_E_G_WE||' AND
    CO.'||P_ENT_B_G_NAME||' < '||P_ENT_E_G_WE||');';
    EXECUTE IMMEDIATE dynSQL ;
    Since this statement is part of a Stored Procedure, I wont see the exact error but just get a ORA-06512.
    The compiling works fine and I use Oracle 11g.
    http://psoug.org/definition/EXECUTE_IMMEDIATE.htm

    OK I extracted from all of your posts so far that I have to use "bind-variables with :"
    From all the other tuorials and forums posts, I assume using the pipe is correct so I added those as well into the script:
    set serveroutput on format wraped;
    DECLARE
    dynSQL VARCHAR2(5000);
    P_ENT_E_G_NAME VARCHAR2 (100) :='test1'; P_ENT_E_G_WE VARCHAR2 (100) :='01.02.2012'; P_ENT_B_G_NAME VARCHAR2 (100) :='01.01.2012';
    P_ST                VARCHAR2 (100) :='32132';
    BEGIN
    dynSQL:= 'UPDATE CO_STAT2 CO SET CO.'||:P_ENT_B_G_NAME||' = '||:P_ENT_E_G_WE||'
                  WHERE ST IN (SELECT ST FROM STG_CO_STAT2_TEST CO WHERE
                  '||:P_ST||'                           = CO.ST                  AND
                  CO.'||:P_ENT_E_G_NAME||'     > '||:P_ENT_E_G_WE||' AND
                  CO.'||:P_ENT_B_G_NAME||'    
    < '||:P_ENT_E_G_WE||')';
    --this is somehow missing after the last < '||:P_ENT_E_G_WE||')';
    dbms_output.enable;
    dbms_output.put(dynSQL);
    --EXECUTE IMMEDIATE dynSQL;    
    END;Problem:I think I figured it out, the dates that I parse into the query need additional '

  • Creating a Dynamic Update Statement based on Select

    hi,
    i'm trying to create a dynamic update statement based on select statement
    my requirment is to query a joint tables and get the results then based on the results i need to copy all the data and create an update statement for each row
    for ex
    the update statement should look like this
    update iadvyy set SO_SWEEP_CNT = '1' where inst_no = '003' and memb_cust_no = 'aaaaaaaaaaaaaaaa';
    and the select statement like the following
    select substr(key_1,11,9) account_no,sord_mast SO_SWEEP_CNT from
    select acct_no,count(*) sord_mast from
    (select from_acct_no acct_no,update_mast
    from sord where FROM_SYS in ('DEP','INV') and TERM_DATE > 40460
    union all
    select to_acct_no acct_no,update_mast
    from sord where TO_SYS in ('DEP','INV') and TERM_DATE > 40460)
    group by Acct_no)
    right outer join
    invm
    on
    key_1 = '003'||acct_no
    where sord_mast > 0;
    so taking the above two columns from the above select statement and substitue the values as separate update statement.
    is that doable , please share your knowledge with me if poosible
    thanks in advanced

    is that doable , please share your knowledge with me if poosibleyes
    The standard advice when (ab)using EXECUTE IMMEDIATE is to compose the SQL statement in a single VARCHAR2 variable
    Then print the SQL before passing it to EXECUTE IMMEDIATE.
    COPY the statement & PASTE into sqlplus to validate its correctness.

  • Dynamic Update Statement in Native SQL

    Hi Experts,
    I want to dynamically pass the field in Update statement in Native SQL. For eg.
    data: str1 type string.
    str1 = 'MARKETS'.
    EXEC SQL.
          UPDATE PRDT.TBVEHDS4 SET (str1) = :'U'
          WHERE  VEH_NO       =  :'K1WK-54520'
          AND    SEGMENT_NO   =  :'01'
    ENDEXEC.
    But this is not taking (str1) as MARKETS field to update as U , its taking STR1 itself, Giving native SQL exception as Invalid Token as we are using DB2 as external DB system.
    I checked with field-symbols also, but nothing helped.
    Please help, thanks in Advance.
    Regards,
    Abhishek

    Hi,
    Check this demo program in SE38  ADBC_DEMO, take as example to construct your own dynamic native sql
    Regards,
    Felipe

  • Dynamic Update Statement

    How do I invoke a dyanmic update statement where the variable in the WHERE clause is a varchar? for instance code below will not work b/c the value in the where clause is missing single quotation marks '<varible>'
    v_dml_str := 'UPDATE D_UNIT_KP'
    || ' SET ' || p_unit_lvl_cd1 || '=' || p_hier1
    || ' WHERE uic = ' || p_uic;
    --execute immediate v_dml_str;
    DBMS_OUTPUT.PUT_LINE(v_dml_str);
    UPDATE D_UNIT_KP SET BN=WS5DAA WHERE uic = WS5DCD

    However, that should work. See example below :
    SQL> set serveroutput on
    SQL> declare
      2       p_username varchar2(30):='SYSTEM';
      3       p_status   varchar2(30):='OPEN';
      4       v_created  date;
      5       v_stmt     varchar2(1000);
      6  begin
      7       v_stmt:='select created from dba_users where username=:b1 and account_status=:b2';
      8       execute immediate v_stmt into v_created using p_username,p_status;
      9       dbms_output.put_line(v_created);
    10  end;
    11  /
    10-APR-03
    PL/SQL procedure successfully completed.You maybe miss some variables in the USING clause, as it shows here below (I removed the p_status from the USING clause) :
    SQL> declare
      2       p_username varchar2(30):='SYSTEM';
      3       p_status   varchar2(30):='OPEN';
      4       v_created  date;
      5       v_stmt     varchar2(1000);
      6  begin
      7       v_stmt:='select created from dba_users where username=:b1 and account_status=:b2';
      8       execute immediate v_stmt into v_created using p_username;
      9       dbms_output.put_line(v_created);
    10  end;
    11  /
    declare
    ERROR at line 1:
    ORA-01008: not all variables bound
    ORA-06512: at line 8Count the number of bind variables used, you should have the same number of variables. Even if you are using the same bind variable more than once, the variables should be repeated, as the following example :
    SQL> declare
      2       p_username varchar2(30):='SYSTEM';
      3       p_status   varchar2(30):='OPEN';
      4       v_created  date;
      5       v_stmt     varchar2(1000);
      6  begin
      7       v_stmt:='select created from dba_users where username=:b1 and username=:b1';
      8       execute immediate v_stmt into v_created using p_username;
      9       dbms_output.put_line(v_created);
    10  end;
    11  /
    declare
    ERROR at line 1:
    ORA-01008: not all variables bound
    ORA-06512: at line 8
    SQL> declare
      2       p_username varchar2(30):='SYSTEM';
      3       p_status   varchar2(30):='OPEN';
      4       v_created  date;
      5       v_stmt     varchar2(1000);
      6  begin
      7       v_stmt:='select created from dba_users where username=:b1 and username=:b1';
      8       execute immediate v_stmt into v_created using p_username,p_username;
      9       dbms_output.put_line(v_created);
    10  end;
    11  /
    10-APR-03
    PL/SQL procedure successfully completed.
    SQL>Nicolas.

  • Executing a Variable in a Stored Procedure containing an Update Statement

    Hi,
    I have created a Stored Procedure, it has one input parameter. Inside the Stored Procedure there are 5 other variables are declared, based on the input parameter 4 of these variables are populated.
    Fifth variable is a a concatenation of text and some of these variables and creates a dynamic Update Statement. Once it is created I want to execute this variable but it is not executing.
    Could someone please help me in knowing how to execute a variable within a stored procedure that contains an update statement.
    Thanks for your help.
    Thanks
    Vineesh
    vineesh1701

    If you have set up the variable so that it contains a valid sql update, it should work.  For example, see below, which does do an update
    use tempdb
    go
    Create Table #Test(i int);
    Insert #Test(i) Values(1);
    go
    Create Procedure TestProc As
    Begin
    Declare @SQL nvarchar(250);
    Set @SQL = 'Update #Test Set i = 2';
    --Print @SQL;
    Exec sp_executesql @SQL;
    End
    go
    Exec TestProc
    -- Test Result
    Select * From #Test;
    go
    Drop Procedure TestProc;
    go
    Drop Table #Test;
    One thing I would recommend while testing is that you print out or select the variable that contains the dynamic sql.  (Like the above code where I have a print statement.  That lets you see exactly what you are executing and if there is any problem
    with the update command. 
    As Naomi said, to get anything more than general help, you will probably have to show us your code and the parameter values you are passing when you execute the stored proc.
    Tom

  • Problem in Update statement using Execute Immediate

    Hi All,
    I am facing problem in update statement.
    I am creating dynamic sql and use "execute immediate" statement to execute a update statement.
    But it is not updating any thing there in the table.
    I have created a query like :
    update_query='Update '|| Table_Name ||' t set t.process_status =''Y'' where t.tid=:A';
    Execute immediate update_query using V_Id;
    commit;
    But it is not updating the table.
    I have a question , is execute immediate only does insert and delete?
    Thanks
    Ashok

    SQL> select * from t;
                     TID P
                     101 N
    SQL> declare
      2     V_Id          number := 101;
      3     Table_Name    varchar2(30) := 'T';
      4     update_query  varchar2(1000);
      5  begin
      6     update_query := 'Update '|| Table_Name ||' t set t.process_status =''Y'' where t.tid=:A';
      7     Execute immediate update_query using V_Id;
      8     commit;
      9  end;
    10  /
    PL/SQL procedure successfully completed.
    SQL> select * from t;
                     TID P
                     101 Y                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       

  • Performance degradation in Update statement

    Hi
    I have a table t1 with 3 of the columns as :- c1 ,c2,c3.
    there is a non unique index on c2 ,c3.
    I am using an update statement as : update t1 set c1="value" where c2="some_value" and c3="some_value2" ;
    this works fine in case the number of rows for the same c2 and c3 are less (~100) but takes a large time when ~30,000.
    And it has to be run many times in my application (time out is occuring now)
    Can anybody suggest a solution ?
    Thanks
    Message was edited by:
    user580975

    First off, setting a table to NOLOGGING does not affect the rate of redo generation unless you are also doing direct-path inserts (which is obviously not the case here and which come with their own set of issues). Note that the amount of redo being generated in these two examples is quite similar.
    SCOTT @ jcave102 Local> create table all_obj_cpy as select * from all_objects;
    Table created.
    Elapsed: 00:00:10.78
    SCOTT @ jcave102 Local> set autotrace traceonly;
    SCOTT @ jcave102 Local> alter table all_obj_cpy logging;
    Table altered.
    Elapsed: 00:00:00.01
    SCOTT @ jcave102 Local> update all_obj_cpy
      2  set last_ddl_time = sysdate - 1;
    42511 rows updated.
    Elapsed: 00:00:01.45
    Execution Plan
    Plan hash value: 1645016300
    | Id  | Operation          | Name        | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | UPDATE STATEMENT   |             | 43776 |   384K|   137   (3)| 00:00:02 |
    |   1 |  UPDATE            | ALL_OBJ_CPY |       |       |            |          |
    |   2 |   TABLE ACCESS FULL| ALL_OBJ_CPY | 43776 |   384K|   137   (3)| 00:00:02 |
    Note
       - dynamic sampling used for this statement
    Statistics
            556  recursive calls
          46075  db block gets
           1558  consistent gets
              0  physical reads
       13575764  redo size
            924  bytes sent via SQL*Net to client
            965  bytes received via SQL*Net from client
              6  SQL*Net roundtrips to/from client
              6  sorts (memory)
              0  sorts (disk)
          42511  rows processed
    SCOTT @ jcave102 Local> alter table all_obj_cpy nologging;
    Table altered.
    Elapsed: 00:00:00.01
    SCOTT @ jcave102 Local> update all_obj_cpy
      2  set last_ddl_time = sysdate - 2;
    42511 rows updated.
    Elapsed: 00:00:01.32
    Execution Plan
    Plan hash value: 1645016300
    | Id  | Operation          | Name        | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | UPDATE STATEMENT   |             | 43776 |   384K|   137   (3)| 00:00:02 |
    |   1 |  UPDATE            | ALL_OBJ_CPY |       |       |            |          |
    |   2 |   TABLE ACCESS FULL| ALL_OBJ_CPY | 43776 |   384K|   137   (3)| 00:00:02 |
    Note
       - dynamic sampling used for this statement
    Statistics
            561  recursive calls
          44949  db block gets
           1496  consistent gets
              0  physical reads
       12799600  redo size
            924  bytes sent via SQL*Net to client
            965  bytes received via SQL*Net from client
              6  SQL*Net roundtrips to/from client
              6  sorts (memory)
              0  sorts (disk)
          42511  rows processedSecond, if you did manage to do an unlogged operation, make absolutely certain you understand the recovery implications. You must do a complete backup of the database after an unlogged operation or the table will not be recovered in the event of a database failure. If you have a standby database for disaster recovery, unlogged operations would cause the standby to be useless (hence the option to force logging at the tablespace and/or database level).
    While it's certainly possible that this is an Oracle server configuration problem, it would be relatively tough to configure a system so that a 30,000 row update would force excessive log switches. If it were a configuration problem, you'd expect that any update of 30,000 rows would be slow and that multiple sessions running smaller updates would also be slow, but I don't believe that describes the symptoms the original poster is concerned about.
    Justin

  • Dynamically Updating Content Server Portlets

    [urlHi, I am currently having difficulty dynamically updating content server portlets.  I have a portlet of the following form:[/url]
    ArticleName Author Title Date mystory author1 title1 04/05/01
    story2 author2 title2 06/07/04
    story author3 title3 01/02/03
    So I have this table where each one of the line items is an article in the content server. So, for example the first line item is an article "mystory" by "author1", with title "title1" and date "04/05/01" additionally there is an article text field, but this isn't displayed unless I click on the article name.
    I can set up the basics of this portlet, but when I try to add any real functionality I run into one of two problems.
    First Problem: Passing Information
    I cannot find a way to pass information between content portlets. For instance, if the user would like to "re-sort" this table based on "date", I would like to have the user click on the "date" column heading and then reload the page. To do so, I would have to pass the section name back to the page so that it could resort based on this data. I have not found anyway to effectively pass information to a content server portlet. I am building these pages through use of the presentation template framework (so I can have access to the content items) but that seems to change the way portlets are handled.
    I got around this limitation with a regular portlet by creating an intermediary page which captures passed information and stores it to the session state. Once the information was in the session state, it is accessible to the portlet on the first page. However, this only works because remote portlets do not change their session id once loaded. Content Server portlets, on the other hand, change their session id after every reload of the browser or page change. I can send information from a content server portlet to an intermediary page, but I cannot send it back to the portlet because the session id has changed so I have no idea of knowing where to send the information. I can write it to a session state, but by the time I return to the portal page, the content server has changed its session id so it does not know where to look any longer.
    I suppose it would be possible to create an application state variable and append it with some static token (if there is some static variable per portal session) but I would rather not have to deal with application variables if at all possible.
    Second Problem: Dynamically Updating PCS Tags
    Even if I were able to the pass information back to my content server portlet, I run into another issue. The easiest way to sort content server items is using the filter command in the pcs:foreach tag. So, if I wanted to sort by author name, I could do something like the following <pcs:foreach var="item" expr="filter(folderByName('content'), filtered.name == '"name")" or something like that (the syntax may be incorrect, I just wrote this off the top of my head). However, it appears that the way the presentation templates are compiled goes in the order of PCS tags THEN JSP. So I would have no way of dynamically changing the variable on which I sort. For example, if I clicked on "Date" above in my table, I would like to be able to dynamically change my code so that I sort on date, and not name. I cannot find a solution to this problem.
    My workaround is to use the pcs tags to write out all the possible sortings to java array objects. This gives me access to the data on a JSP level and based on whatever the user will chose, I could then display that array. While this works, it is extremely ghetto and inefficient. Any help or suggestions would be fantastic.
    Thanks a lot,
    Jason Grauel

    You can use just about any javascript you want in any Content Server presentation template including ones that are used for portlets.
    However, you should be careful to name javascript functions and global variables uniquely so that they do not conflict with any other javascript on the page. To do this, you can append the item id to function and variable names, for example,
    function doSomething<pcs:value expr="pcs_id"></pcs:value>() {
    return true;
    Randy

  • Dynamic SELECT statement causing CX_SY_DYNAMIC_OSQL_SEMANTICS error.

    Hello Gurus,
    We have a dynamic SELECT statement in our BW Update Rules where the the Selection Fields are populated at run-time and so are the look-up target and also the WHERE clause. The code basically looks like below:
              SELECT (lt_select_flds)
                FROM (lf_tab_name)
                INTO CORRESPONDING FIELDS OF TABLE <lt_data_tab>
                FOR ALL ENTRIES IN <lt_source_data>
                WHERE (lf_where).
    In this instance, we are selecting 5 fields from Customer Master Data and the WHERE condition for this instance of the run is as below:
    WHERE: DIVISION = <lt_source_data>-DIVISION AND DISTR_CHAN = <lt_source_data>-DISTR_CHAN AND SALESORG = <lt_source_data>-SALESORG AND CUST_SALES = <lt_source_data>-SOLD_TO AND OBJVERS = 'A'
    This code was working fine till yesterday when we encountered serious performance problems and the Basis team had to do some changes at the DB level [Oracle]. Ever since, when we execute our data load, we get the CX_SY_DYNAMIC_OSQL_SEMANTICS.
    Is setting changes at the Oracle level cause issues with how the data is being read at the DB. If yes, can you suggest what can we do to this code to get is working correctly [in case Basis can't revert back their changes]?
    Would appreciate any help we can get here.

    You don't understand - this error comes up when we run specific BEx queries.  It was working yesterday, but today it is not.  Our support package did not change from yesterday.  We did not apply any OSSnotes.
    We are however doing pre-prepare on our Prod system.
    The temporary table is used to store SIDs for use in the join.  the table exists in the dictionary, but not at an Oracle level.

  • SQL Update statement taking too long..

    Hi All,
    I have a simple update statement that goes through a table of 95000 rows that is taking too long to update; here are the details:
    Oracle Version: 11.2.0.1 64bit
    OS: Windows 2008 64bit
    desc temp_person;
    Name                                                                                Null?    Type
    PERSON_ID                                                                           NOT NULL NUMBER(10)
    DISTRICT_ID                                                                     NOT NULL NUMBER(10)
    FIRST_NAME                                                                                   VARCHAR2(60)
    MIDDLE_NAME                                                                                  VARCHAR2(60)
    LAST_NAME                                                                                    VARCHAR2(60)
    BIRTH_DATE                                                                                   DATE
    SIN                                                                                          VARCHAR2(11)
    PARTY_ID                                                                                     NUMBER(10)
    ACTIVE_STATUS                                                                       NOT NULL VARCHAR2(1)
    TAXABLE_FLAG                                                                                 VARCHAR2(1)
    CPP_EXEMPT                                                                                   VARCHAR2(1)
    EVENT_ID                                                                            NOT NULL NUMBER(10)
    USER_INFO_ID                                                                                 NUMBER(10)
    TIMESTAMP                                                                           NOT NULL DATE
    CREATE INDEX tmp_rs_PERSON_ED ON temp_person (PERSON_ID,DISTRICT_ID) TABLESPACE D_INDEX;
    Index created.
    ANALYZE INDEX tmp_PERSON_ED COMPUTE STATISTICS;
    Index analyzed.
    explain plan for update temp_person
      2  set first_name = (select trim(f_name)
      3                    from ext_names_csv
      4                               where temp_person.PERSON_ID=ext_names_csv.p_id
      5                               and   temp_person.DISTRICT_ID=ext_names_csv.ed_id);
    Explained.
    @?/rdbms/admin/utlxpls.sql
    PLAN_TABLE_OUTPUT
    Plan hash value: 3786226716
    | Id  | Operation                   | Name           | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | UPDATE STATEMENT            |                | 82095 |  4649K|  2052K  (4)| 06:50:31 |
    |   1 |  UPDATE                     | TEMP_PERSON    |       |       |            |          |
    |   2 |   TABLE ACCESS FULL         | TEMP_PERSON    | 82095 |  4649K|   191   (1)| 00:00:03 |
    |*  3 |   EXTERNAL TABLE ACCESS FULL| EXT_NAMES_CSV  |     1 |   178 |    24   (0)| 00:00:01 |
    Predicate Information (identified by operation id):
       3 - filter("EXT_NAMES_CSV"."P_ID"=:B1 AND "EXT_NAMES_CSV"."ED_ID"=:B2)
    Note
       - dynamic sampling used for this statement (level=2)
    19 rows selected.By the looks of it the update is going to take 6 hrs!!!
    ext_names_csv is an external table that have the same number of rows as the PERSON table.
    ROHO@rohof> desc ext_names_csv
    Name                                                                                Null?    Type
    P_ID                                                                                         NUMBER
    ED_ID                                                                                        NUMBER
    F_NAME                                                                                       VARCHAR2(300)
    L_NAME                                                                                       VARCHAR2(300)Anyone can help diagnose this please.
    Thanks
    Edited by: rsar001 on Feb 11, 2011 9:10 PM

    Thank you all for the great ideas, you have been extremely helpful. Here is what we did and were able to resolve the query.
    We started with Etbin's idea to create a table from the ext table so that we can index and reference easier than an external table, so we did the following:
    SQL> create table ext_person as select P_ID,ED_ID,trim(F_NAME) fst_name,trim(L_NAME) lst_name from EXT_NAMES_CSV;
    Table created.
    SQL> desc ext_person
    Name                                                                                Null?    Type
    P_ID                                                                                         NUMBER
    ED_ID                                                                                        NUMBER
    FST_NAME                                                                                     VARCHAR2(300)
    LST_NAME                                                                                     VARCHAR2(300)
    SQL> select count(*) from ext_person;
      COUNT(*)
         93383
    SQL> CREATE INDEX EXT_PERSON_ED ON ext_person (P_ID,ED_ID) TABLESPACE D_INDEX;
    Index created.
    SQL> exec dbms_stats.gather_index_stats(ownname=>'APPD', indname=>'EXT_PERSON_ED',partname=> NULL , estimate_percent=> 30 );
    PL/SQL procedure successfully completed.We had a look at the plan with the original SQL query that we had:
    SQL> explain plan for update temp_person
      2  set first_name = (select fst_name
      3                    from ext_person
      4                               where temp_person.PERSON_ID=ext_person.p_id
      5                               and   temp_person.DISTRICT_ID=ext_person.ed_id);
    Explained.
    SQL> @?/rdbms/admin/utlxpls.sql
    PLAN_TABLE_OUTPUT
    Plan hash value: 1236196514
    | Id  | Operation                    | Name           | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | UPDATE STATEMENT             |                | 93383 |  1550K|   186K (50)| 00:37:24 |
    |   1 |  UPDATE                      | TEMP_PERSON    |       |       |            |          |
    |   2 |   TABLE ACCESS FULL          | TEMP_PERSON    | 93383 |  1550K|   191   (1)| 00:00:03 |
    |   3 |   TABLE ACCESS BY INDEX ROWID| EXTT_PERSON    |     9 |  1602 |     1   (0)| 00:00:01 |
    |*  4 |    INDEX RANGE SCAN          | EXT_PERSON_ED  |     1 |       |     1   (0)| 00:00:01 |
    Predicate Information (identified by operation id):
       4 - access("EXT_PERSON"."P_ID"=:B1 AND "RS_PERSON"."ED_ID"=:B2)
    Note
       - dynamic sampling used for this statement (level=2)
    20 rows selected.As you can see the time has dropped to 37min (from 6 hrs). Then we decided to change the SQL query and use donisback's suggestion (using MERGE); we explained the plan for teh new query and here is the results:
    SQL> explain plan for MERGE INTO temp_person t
      2  USING (SELECT fst_name ,p_id,ed_id
      3  FROM  ext_person) ext
      4  ON (ext.p_id=t.person_id AND ext.ed_id=t.district_id)
      5  WHEN MATCHED THEN
      6  UPDATE set t.first_name=ext.fst_name;
    Explained.
    SQL> @?/rdbms/admin/utlxpls.sql
    PLAN_TABLE_OUTPUT
    Plan hash value: 2192307910
    | Id  | Operation            | Name         | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |
    |   0 | MERGE STATEMENT      |              | 92307 |    14M|       |  1417   (1)| 00:00:17 |
    |   1 |  MERGE               | TEMP_PERSON  |       |       |       |            |          |
    |   2 |   VIEW               |              |       |       |       |            |          |
    |*  3 |    HASH JOIN         |              | 92307 |    20M|  6384K|  1417   (1)| 00:00:17 |
    |   4 |     TABLE ACCESS FULL| TEMP_PERSON  | 93383 |  5289K|       |   192   (2)| 00:00:03 |
    |   5 |     TABLE ACCESS FULL| EXT_PERSON   | 92307 |    15M|       |    85   (2)| 00:00:02 |
    Predicate Information (identified by operation id):
       3 - access("P_ID"="T"."PERSON_ID" AND "ED_ID"="T"."DISTRICT_ID")
    Note
       - dynamic sampling used for this statement (level=2)
    21 rows selected.As you can see, the update now takes 00:00:17 to run (need to say more?) :)
    Thank you all for your ideas that helped us get to the solution.
    Much appreciated.
    Thanks

  • Help With SUBSTR in dynamic SQL statement

    Following is the dynamic SQL statement.
    EXECUTE IMMEDIATE 'UPDATE table_name pml
    SET pml.'|| con_fields.field ||' = SUBSTR(pml.'||con_fields.field||' ||'' ''||
    (SELECT pml1.'||con_fields.field||'
    FROM table_name pml1
    WHERE pml1.grp_id = '||los_concats.grp_id ||'
    AND pml1.row_id = '||los_concats.row_id||'
    AND pml1.loser_flg = ''Y''),1, '||con_fields.max_length||')
    WHERE pml.grp_id = '||los_concats.grp_id ||'
    AND pml.loser_flg IS NULL ';
    what it does is that it updates a particular field. This field is concatenated by a field of a similar record.
    My problem is with SUBSTR function. Since I am concatenating fields I do not want the field to be updated greater than max_length on that field, the reason why I use SUBSTR. the select query inside SUBSTR works alright with one of the AND condition in a WHERE clause not present. When I add that additional condition it gives me this error.
    ORA-00907: missing right parenthesis.
    Is there any way to get around this problem. Does SQL has other than SUBSTR function which can limit the character length.
    Appreciate it.

    The other alternative I thought about was to do this first
    EXECUTE IMMEDIATE 'SELECT pml.'||con_fields.field||'
    FROM table_name pml
    WHERE pml.grp_id = '||los_concats.grp_id||'
    AND pml.row_id = '||los_concats.row_id||'
    AND pml.loser_flg = ''Y''
    ' INTO v_concat_field;
    write into the variable v_concat_field and then use it into the previous script.
    But on this I get SQL Command not properly terminated, I don't get it Why?
    Donald I tried with your suggested script. It works fine with one of the conditions eliminated. I don't understand what the error trying to say?
    Thanks

  • Preparing Dynamic SQL statement for inserting in Pro*C

    Hi Friends,
    From quite some time i am struggling writing Dynamic SQL statement for dynamic insert and update in Pro*C.
    Can somebody go through my code and suggest me the rigth way of doing.
    Right now it throws an error saying " Error while updating ORA-00904: invalid column name "
    Please help me.
    Girish.
    int main()
    EXEC SQL BEGIN DECLARE SECTION;
    char *uid ="scott/tiger";
    static char sqlstmt[129];
    struct /* DEPT record */
    int dept_num;
    char dept_name[15];
    char location[14];
    } dept_rec;
    EXEC SQL END DECLARE SECTION;
    EXEC SQL WHENEVER SQLERROR DO sql_error();
    EXEC SQL CONNECT :uid;
    dept_rec.dept_num = 50;
    strcpy(dept_rec.dept_name,"ADMIN");
    strcpy(dept_rec.location,"IN");
    strcpy(sqlstmt,"UPDATE dept set DNAME = dept_rec.dept_name where DEPTNO = dept_rec.dept_num");
    EXEC SQL EXECUTE IMMEDIATE:sqlstmt;
    EXEC SQL COMMIT;
    exit(0);
    void sql_error()
    printf("\nError while updating %s",sqlca.sqlerrm.sqlerrmc);
    EXEC SQL ROLLBACK;
    }

    A bit rusty here but this is how I see it.
    Think of it this way ..
    all Oracle is going to see is:
    UPDATE dept set DNAME = dept_rec.dept_name where DEPTNO = dept_rec.dept_num
    Its NOT going to know what dept_rec.dept_name is or dept_rec.dept_num is ..
    it doesnt go back and fill in those values.
    You need something like
    strcpy(sqlstmt,"UPDATE dept set DNAME = \"");
    strcat(sqlstmt,dept_rec.dept_name);
    strcat(sqlstmt,"\" where DEPTNO = ");
    strcat(sqlstmt,dept_rec.dept_num);
    printf(sqlsmt); # Just to be sure the update statement look right during testing.

  • Dynamic Update Queries - SQL Script

    Hi All,
    I have a table Account_info where columns are ACCT_NO and flag with other information (columns). We are receving a file which contains ACCT_NO and FLAG. Now i need to compare ACCT_NO for Table and file and based on it need to update FLAG column in table.
    To automate this process, i can develop a shell script, which load data from file to temp table and then update statement to update Account_info table. For batch process, i can write a for loop, which commit data after every 10,000 update.
    but client does not want this way. We have to send file to Production team, where they will load data manually into temp table.
    Once done, i have to write a update statement which will take 10000 records to update on every run and then commit it, so there will not be space/memory issue.
    For example, if table has 50,000 records, i have to create 5 update statement. and then i have to send all 5 queries as sql script and send it to Production support.
    It is difficult for me to do it daily.
    Is there any other way, where SQL script is dynamic and based on number of rows/10000 , it create UPDATE statement and run it daily.
    Regards,
    ACE

    ace_friends22 wrote:
    Hi All,
    I have a table Account_info where columns are ACCT_NO and flag with other information (columns). We are receving a file which contains ACCT_NO and FLAG. Now i need to compare ACCT_NO for Table and file and based on it need to update FLAG column in table.
    To automate this process, i can develop a shell script, which load data from file to temp table and then update statement to update Account_info table. For batch process, i can write a for loop, which commit data after every 10,000 update.Why not simply use an external table pointing at the file and use a single update statement? If you write a loop with intermittent commits, this is one of the worst known ways of processing data.
    but client does not want this way.And the client knows how to technically implement a solution then? Why aren't they doing it themselves then?
    We have to send file to Production team, where they will load data manually into temp table.Unnecessary. Use an External table
    Once done, i have to write a update statement which will take 10000 records to update on every run and then commit it, so there will not be space/memory issue.Oracle is an enterprise level database engine capable of processing millions of rows without space/memory issues. If you've encountered shuch an issue you should be trying to identify the cause of it rather than suppress the symptoms.
    For example, if table has 50,000 records, i have to create 5 update statement. and then i have to send all 5 queries as sql script and send it to Production support.Bad Idea ^tm^

  • Dynamic update in Oracle 9i Release 9.2

    Hi all,
    The update statement I want to execute depends on three variables. The statement is like this :
    update fichier_tempo
                   set flag = 0
                   where substr(texte,7,2) = pcode_enreg
                   and flag = 1
                   and v_id = vcode;
    In this statement : pcode_enreg , v_id and vcode are variables.
    The statement may affect many rows.
    I have already thought about using the execute immediate statement but it requires that the update affects only one row with the returning into clause.
    So how to execute this dynamic update ?
    Thank you very much indeed.

    You have lots of errors in that code.
    One of them is indeed the dynamic update where you say that the string "substr(texte,20,13)" should be equal to the string that's in vcode (in my example below: abcdefghijklm). This is probably not what you want.
    First I'll show you a variant of your code, which lots of areas in it to improve on, but hey: it works ;-)
    Then I'll show you one merge statement that does it all in once.
    Hope it helps.
    SQL> create table fichier_tempo
      2  as
      3  select 'xxxxxx50xxxxxxxxxxxabcdefghijklm' texte, 1 flag, 5 num from dual union all
      4  select 'xxxxxx50xxxxxxxxxxxabcdefghijklm', 1, 4 from dual union all
      5  select 'xxxxxx50xxxxxxxxxxxabcdefghijklm', 0, 3 from dual union all
      6  select 'xxxxxx50xxxxxxxxxxxabcdefghijklm', 1, 2 from dual union all
      7  select 'xxxxxx53xxxxxxxxxxxzyxwvutsrqpon', 0, 11 from dual union all
      8  select 'xxxxxx53xxxxxxxxxxxzyxwvutsrqpon', 1, 12 from dual union all
      9  select 'xxxxxx53xxxxxxxxxxxzyxwvutsrqpon', 0, 13 from dual
    10  /
    Tabel is aangemaakt.
    SQL> create or replace procedure p_test397(pcode_enreg varchar2)
      2  is
      3    --vmotif conrej_fic.crf_lib_err%type := get_motif_rejet('397');
      4    v_id varchar2(40);
      5    vsql varchar2(4000);
      6    c_div sys_refcursor;
      7    vcode varchar2(13);
      8    nb number;
      9    vsql_div varchar2(4000);
    10    updt_div sys_refcursor;
    11  begin
    12    select case pcode_enreg
    13    when '50' then 'substr(texte,20,13)'
    14    when '53' then 'substr(texte,20,4)'
    15    when '56' then 'substr(texte,20,4)'
    16    end
    17    into v_id
    18    from dual;
    19
    20    vsql := 'select '||v_id||',count(*) '||
    21    'from fichier_tempo '||
    22    'where flag = 1 '||
    23    'and substr(texte,7,2) = '||pcode_enreg||' '||
    24    'and num > 0 '||
    25    'having count(*) > 1 '||
    26    'group by '||v_id;
    27
    28    open c_div for vsql;
    29
    30    loop
    31      fetch c_div into vcode,nb;
    32      exit when c_div%notfound;
    33
    34      -- This is the dynamic update
    35      execute immediate
    36      'update fichier_tempo ' ||
    37      'set flag = 0 ' ||
    38      'where substr(texte,7,2) = ' || pcode_enreg || ' ' ||
    39      'and flag = 1 ' ||
    40      'and '||v_id||' = '''||vcode||''''
    41      ;
    42    end loop;
    43    close c_div;
    44  end;
    45  /
    Procedure is aangemaakt.
    SQL> select * from fichier_tempo
      2  /
    TEXTE                                                              FLAG                                 NUM
    xxxxxx50xxxxxxxxxxxabcdefghijklm                                      1                                   5
    xxxxxx50xxxxxxxxxxxabcdefghijklm                                      1                                   4
    xxxxxx50xxxxxxxxxxxabcdefghijklm                                      0                                   3
    xxxxxx50xxxxxxxxxxxabcdefghijklm                                      1                                   2
    xxxxxx53xxxxxxxxxxxzyxwvutsrqpon                                      0                                  11
    xxxxxx53xxxxxxxxxxxzyxwvutsrqpon                                      1                                  12
    xxxxxx53xxxxxxxxxxxzyxwvutsrqpon                                      0                                  13
    7 rijen zijn geselecteerd.
    SQL> exec p_test397('50')
    PL/SQL-procedure is geslaagd.
    SQL> select * from fichier_tempo
      2  /
    TEXTE                                                              FLAG                                 NUM
    xxxxxx50xxxxxxxxxxxabcdefghijklm                                      0                                   5
    xxxxxx50xxxxxxxxxxxabcdefghijklm                                      0                                   4
    xxxxxx50xxxxxxxxxxxabcdefghijklm                                      0                                   3
    xxxxxx50xxxxxxxxxxxabcdefghijklm                                      0                                   2
    xxxxxx53xxxxxxxxxxxzyxwvutsrqpon                                      0                                  11
    xxxxxx53xxxxxxxxxxxzyxwvutsrqpon                                      1                                  12
    xxxxxx53xxxxxxxxxxxzyxwvutsrqpon                                      0                                  13
    7 rijen zijn geselecteerd.
    SQL> exec p_test397('53')
    PL/SQL-procedure is geslaagd.
    SQL> select * from fichier_tempo
      2  /
    TEXTE                                                              FLAG                                 NUM
    xxxxxx50xxxxxxxxxxxabcdefghijklm                                      0                                   5
    xxxxxx50xxxxxxxxxxxabcdefghijklm                                      0                                   4
    xxxxxx50xxxxxxxxxxxabcdefghijklm                                      0                                   3
    xxxxxx50xxxxxxxxxxxabcdefghijklm                                      0                                   2
    xxxxxx53xxxxxxxxxxxzyxwvutsrqpon                                      0                                  11
    xxxxxx53xxxxxxxxxxxzyxwvutsrqpon                                      1                                  12
    xxxxxx53xxxxxxxxxxxzyxwvutsrqpon                                      0                                  13
    7 rijen zijn geselecteerd.
    SQL> rollback
      2  /
    Rollback is voltooid.
    SQL> create procedure mytest397 (pcode_enreg in varchar2)
      2  is
      3  begin
      4    merge into fichier_tempo f1
      5    using ( select a, rid
      6              from ( select count(*) over
      7                            ( order by
      8                                case pcode_enreg
      9                                when '50' then substr(texte,20,13)
    10                                when '53' then substr(texte,20,4)
    11                                when '56' then substr(texte,20,4)
    12                                end
    13                            ) a
    14                          , rowid rid
    15                       from fichier_tempo
    16                      where flag = 1
    17                        and num > 0
    18                        and substr(texte,7,2) = pcode_enreg
    19                   )
    20             where a > 1
    21          ) f2
    22    on (f1.rowid = f2.rid)
    23    when matched then
    24      update set flag = 0
    25    when not matched then
    26      insert values (null,null,null)  -- dummy line for version 9i
    27    ;
    28  end;
    29  /
    Procedure is aangemaakt.
    SQL> select * from fichier_tempo
      2  /
    TEXTE                                                              FLAG                                 NUM
    xxxxxx50xxxxxxxxxxxabcdefghijklm                                      1                                   5
    xxxxxx50xxxxxxxxxxxabcdefghijklm                                      1                                   4
    xxxxxx50xxxxxxxxxxxabcdefghijklm                                      0                                   3
    xxxxxx50xxxxxxxxxxxabcdefghijklm                                      1                                   2
    xxxxxx53xxxxxxxxxxxzyxwvutsrqpon                                      0                                  11
    xxxxxx53xxxxxxxxxxxzyxwvutsrqpon                                      1                                  12
    xxxxxx53xxxxxxxxxxxzyxwvutsrqpon                                      0                                  13
    7 rijen zijn geselecteerd.
    SQL> exec mytest397('50')
    PL/SQL-procedure is geslaagd.
    SQL> select * from fichier_tempo
      2  /
    TEXTE                                                              FLAG                                 NUM
    xxxxxx50xxxxxxxxxxxabcdefghijklm                                      0                                   5
    xxxxxx50xxxxxxxxxxxabcdefghijklm                                      0                                   4
    xxxxxx50xxxxxxxxxxxabcdefghijklm                                      0                                   3
    xxxxxx50xxxxxxxxxxxabcdefghijklm                                      0                                   2
    xxxxxx53xxxxxxxxxxxzyxwvutsrqpon                                      0                                  11
    xxxxxx53xxxxxxxxxxxzyxwvutsrqpon                                      1                                  12
    xxxxxx53xxxxxxxxxxxzyxwvutsrqpon                                      0                                  13
    7 rijen zijn geselecteerd.
    SQL> exec mytest397('53')
    PL/SQL-procedure is geslaagd.
    SQL> select * from fichier_tempo
      2  /
    TEXTE                                                              FLAG                                 NUM
    xxxxxx50xxxxxxxxxxxabcdefghijklm                                      0                                   5
    xxxxxx50xxxxxxxxxxxabcdefghijklm                                      0                                   4
    xxxxxx50xxxxxxxxxxxabcdefghijklm                                      0                                   3
    xxxxxx50xxxxxxxxxxxabcdefghijklm                                      0                                   2
    xxxxxx53xxxxxxxxxxxzyxwvutsrqpon                                      0                                  11
    xxxxxx53xxxxxxxxxxxzyxwvutsrqpon                                      1                                  12
    xxxxxx53xxxxxxxxxxxzyxwvutsrqpon                                      0                                  13
    7 rijen zijn geselecteerd.Regards,
    Rob.

Maybe you are looking for

  • Error when updating Idocs in Source System - Urgent

    Hi Team, When i was loading the data from SAP R/3 to BW, i was facing the error "Error when updating Idocs in Source System" (0 From 0 Records). When i check in the Environment>Transaction RFC->In the Source System, it was displaying the error-- <b>"

  • C5 message srting by HOUR?!

    i have no idea if this is a bug or a feature, but in nokia c5, there is an option to sort by date, sender, type etc, but when it's set to sort by date, it actually sorts by hour. so messages 4 days old will be on top of the list if they have been rec

  • How to increase photo size whilst viewing on HDTV using Airplay?

    Hello, I am using a new Apple iphone 4s with IOS 5.1 etc and I am trying to view photos on my HDTV in widescreen format via Apple TV (3rdGen) ... The video playback mirrored from the iphone in 1080P automatically appears in widesreen using the full s

  • Using blend tool to create even transitions between shapes

    When I use the blend tool I notice that the blends from large to small and the distance between the objects are based upon the center of the two shapes. I blended the squares on the outside and the gaps between the blended squares aren't even. Is the

  • Need HELP with finally() in nested try-catch

    hi, i am having trouble with deadlock and wondering if its due to an incorrect use of finally nested within multiple try catch blocks. is the inner finally() required, will the outer one get executed, or will the two finally() statements get executed