How to cancel row insertion by trigger?

Hello, everybody!
I need the trigger that supplies following functionality:
If UID (unique constrained)is already in some row, it updates the line where UID = :NEW.UID instead of inserting new one incrementing INDEXCOUNTER in this row.
The table is like this: (USERID (PK), UID (Unique), ... , INDEXCOUNTER);
How can I implemented it?
How can I cancel insertion of new line in 2-nd case?
Please, advice how to improve it?
Thanks in advance,
Yura.

Thanks Kevin and Arnold for the MERGE suggestion. I'm using 9i now and being in-grained to do it the other way, I may not have considered/noticed such a new command. Please continue to respond with new better 9i ways of doing things when appropriate. For instance, I think Oracle should have put up a billboard in Times Square to announce the CASE syntax being available to the PL/SQL engine...
Either way, on the original question, the neccessity to handle the INSERT/UPDATE decision can not be coded in a BEFORE or AFTER trigger - we all agree this is fundamental. An INSTEAD OF trigger is really IMHO more akin to the application code "tier" that the database code "tier" (using the word tier loosely).
Michael

Similar Messages

  • How to do update instead of insert / cancel the insert

    Hello,
    we are porting an application, written originally for PostgreSQL, to Oracle. Most of the porting is pretty straightforward - change column types, simple trigger syntax changes etc.
    But we have a table (more precisely several tables) with a set of triggers, holding a tree-like structure. The point is in PostgreSQL we're using a RETURN NULL; behavior in BEFORE triggers, which means 'do nothing' to simplify thing.
    For example imagine tables A and B - and in a trigger on B we could have something like
    INSERT INTO A VALUES (id, ...)
    without a check on a uniqueness of the id value. And in a BEFORE INSERT trigger on A we have something like
    SELECT INTO c id FROM A where id = NEW.id;
    IF FOUND THEN
    UPDATE A SET .... WHERE id = NEW.id;
    -- cancel the insert without an exception
    RETURN NULL;
    END IF;
    which checks for existence of the row, and if it already exists it effectively replaces with UPDATE and cancels the INSERT without an exception.
    Is there something like this in Oracle or do I have to completely rewrite / refactor the whole thing?
    PS: We do have UNIQUE (more precisely PRIMARY KEY) on the columns - I am aware that this is not sufficient to enforce uniqueness in Oracle.

    There are a couple of ways that this could be accomplished in Oracle, although the though of an insert into table b also inserting or updating rows in table a makes me cringe. The easiest way only requires a trigger on table b.
    Something along the lines of:
    SQL> CREATE TABLE a (ID NUMBER PRIMARY KEY, descr VARCHAR2(10));
    Table created.
    SQL> CREATE TABLE b (id NUMBER, descr VARCHAR2(10), descr2 VARCHAR2(20));
    Table created.
    SQL> CREATE TRIGGER b_bi
      2     BEFORE INSERT ON b
      3     FOR EACH ROW
      4  BEGIN
      5     INSERT INTO a VALUES (:new.id, :new.descr);
      6  EXCEPTION
      7     WHEN DUP_VAL_ON_INDEX THEN
      8        UPDATE a SET descr = :new.descr
      9        WHERE id = :new.id;
    10  END;
    11  /
    Trigger created.
    SQL> INSERT INTO a VALUES(1, 'One');
    1 row created.
    SQL> COMMIT;
    Commit complete.
    SQL> INSERT INTO b VALUES(1, 'NewOne', 'New One');
    1 row created.
    SQL> SELECT * FROM a;
            ID DESCR
             1 NewOne
    SQL> INSERT INTO b VALUES(2, 'Two', 'Old Two');
    1 row created.
    SQL> SELECT * FROM a;
            ID DESCR
             1 NewOne
             2 Two
    SQL> COMMIT;
    Commit complete.If you really require the trigger on table a for other reasons, then you could do something like:
    SQL> RENAME a to a_table;
    Table renamed.
    SQL> CREATE VIEW a AS SELECT * FROM a_table;
    View created.
    SQL> CREATE TRIGGER a_ii
      2     INSTEAD OF INSERT ON a
      3     FOR EACH ROW
      4  BEGIN
      5     INSERT INTO a_table VALUES(:new.id, :new.descr);
      6  EXCEPTION
      7     WHEN DUP_VAL_ON_INDEX THEN
      8        UPDATE a_table SET descr = :new.descr
      9        WHERE id = :new.id;
    10  END;
    11  /
    Trigger created.
    SQL> CREATE OR REPLACE TRIGGER b_bi
      2     BEFORE INSERT ON b
      3     FOR EACH ROW
      4  BEGIN
      5     INSERT INTO a VALUES (:new.id, :new.descr);
      6  END;
      7  /
    Trigger created.
    SQL> INSERT INTO b VALUES(2, 'NewTwo', 'New Two');
    1 row created.
    SQL> SELECT * FROM a;
            ID DESCR
             1 NewOne
             2 NewTwo
    SQL> INSERT INTO b VALUES(3, 'Three','Third');
    1 row created.
    SQL> SELECT * FROM a;
            ID DESCR
             1 NewOne
             2 NewTwo
             3 ThreeNeither should require any changes to your application code. However, once agan, I think it is a really bad idea for triggers to have side efects on other tables.
    John

  • How can I use multiple row insert or update into DB in JSP?

    Hi all,
    pls help for my question.
    "How can I use multiple rows insert or update into DB in JSP?"
    I mean I will insert or update the multiple records like grid component. All the data I enter will go into the DB.
    With thanks,

    That isn't true. Different SQL databases have
    different capabilities and use different syntax, That's true - every database has its own quirks and extensions. No disagreement there. But they all follow ANSI SQL for CRUD operations. Since the OP said they wanted to do INSERTs and UPDATEs in batches, I assumed that ANSI SQL was sufficient.
    I'd argue that it's best to use ANSI SQL as much as possible, especially if you want your JDBC code to be portable between databases.
    and there are also a lot of different ways of talking to
    SQL databases that are possible in JSP, from using
    plain old java.sql.* in scriptlets to using the
    jstlsql taglib. I've done maintenance on both, and
    they are as different as night and day.Right, because you don't maintain JSP and Java classes the same way. No news there. Both java.sql and JSTL sql taglib are both based on SQL and JDBC. Same difference, except that one uses tags and the other doesn't. Both are Java JDBC code in the end.
    Well, sure. As long as you only want to update rows
    with the same value in column 2. I had the impression
    he wanted to update a whole table. If he only meant
    update all rows with the same value in a given column
    with the same value, that's trivial. All updates do
    that. But as far as I know there's know way to update
    more than one row where the values are different.I used this as an example to demonstrate that it's possible to UPDATE more than one row at a time. If I have 1,000 rows, and each one is a separate UPDATE statement that's unique from all the others, I guess I'd have to write 1,000 UPDATE statements. It's possible to have them all either succeed or fail as a single unit of work. I'm pointing out transaction, because they weren't coming up in the discussion.
    Unless you're using MySQL, for instance. I only have
    experience with MySQL and M$ SQL Server, so I don't
    know what PostgreSQL, Oracle, Sybase, DB2 and all the
    rest are capable of, but I know for sure that MySQL
    can insert multiple rows while SQL Server can't (or at
    least I've never seen the syntax for doing it if it
    does).Right, but this syntax seems to be specific to MySQL The moment you use it, you're locked into MySQL. There are other ways to accomplish the same thing with ANSI SQL.
    Don't assume that all SQL databases are the same.
    They're not, and it can really screw you up badly if
    you assume you can deploy a project you've developed
    with one database in an environment where you have to
    use a different one. Even different versions of the
    same database can have huge differences. I recommend
    you get a copy of the O'Reilly book, SQL in a
    Nutshell. It covers the most common DBMSes and does a
    good job of pointing out the differences.Yes, I understand that.
    It's funny that you're telling me not to assume that all SQL databases are the same. You're the one who's proposing that the OP use a MySQL-specific extension.
    I haven't looked at the MySQL docs to find out how the syntax you're suggesting works. What if one value set INSERT succeeds and the next one fails? Does MySQL roll back the successful INSERT? Is the unit of work under the JDBC driver's control with autoCommit?
    The OP is free to follow your suggestion. I'm pointing out that there are transactions for units of work and ANSI SQL ways to accomplish the same thing.

  • How to find out the rows inserted between a time period.

    Hi,
    Please help me to solve this.
    Table - emp.
    Colmns - empno(Primary Key),ename, mgr
    How to find out the rows inserted between a time period.
    For eg:- Between 02-Oct-2006 1 PM and 03-Oct-2006 2 PM.
    regards,
    Mathew.

    Hi,
    Maybe work:
    For each row, ORA_ROWSCN returns the conservative upper bound system change number (SCN) of the most recent change to the row. This pseudocolumn is useful for determining approximately when a row was last updated. It is not absolutely precise, because Oracle tracks SCNs by transaction committed for the block in which the row resides
    e.g.:
    SGMS@ORACLE10> create table test(cod number);
    Table created.
    SGMS@ORACLE10> insert into test values (1);
    1 row created.
    SGMS@ORACLE10> insert into test values (2);
    1 row created.
    SGMS@ORACLE10> commit;
    Commit complete.
    SGMS@ORACLE10> insert into test values (3);
    1 row created.
    SGMS@ORACLE10> commit;
    Commit complete.
    SGMS@ORACLE10> select SCN_TO_TIMESTAMP(ora_rowscn),ora_rowscn,cod from test;
    SCN_TO_TIMESTAMP(ORA_ROWSCN)       ORA_ROWSCN        COD
    06/11/06 08:56:56,000000000         727707205          1
    06/11/06 08:56:56,000000000         727707205          2
    06/11/06 08:57:05,000000000         727707210          3Cheers

  • How to change the "1 row inserted" message in a Form

    I DEVELOPED A FORM THAT BASICALLY ALLOWS USERS TO INSERT RECORDS IN A TABLE.
    AFTER THE "INSERT" BUTTON IS CLICKED, THE ROW IS INSERTED AND A MESSAGE SAYING "1 ROW INSERTED" IS DISPLAYED.
    I WOULD LIKE TO REPLACE THAT TEXT BY SOMETHING ELSE... SOME SORT OF EXPLANATION TO THE USER.
    MAYBE I WOULD ALSO LIKE TO REDIRECT THE USER TO ANOTHER SCREEN (NOT SURE YET) .
    HOW CAN I ACCOMPLISH THIS?
    ANY HELP WILL BE GREATLY APPRECIATED...
    TKS!!!

    tks dmitry!
    i have not tried yet but i am sure it will work.
    also, i found a posting regarding how to redirect the user to another screen.
    is there any good documentation somewhere on Portal APPLICATIONS development?
    Tks again...
    null

  • How to Commit before Insert Row when Press Create Insert Button ?

    Hi all;
    I'm Using JDev 11.1.1.2.0
    How to Commit before Insert Row when Press Create Insert Button in ADF11g?
    <af:commandButton actionListener="#{bindings.CreateInsert.execute}"
    text="CreateInsert"
    disabled="#{!bindings.CreateInsert.enabled}"
    id="cb8" />
    best regards;

    You need to do a custom method eather in managed bean or in Application module to do that.
    in managed bean it would be something like:
    public void CommitAndInsert(ActionEvent actionEvent) {
    OperationBinding opCommit = ADFUtils.findOperation("Commit");
    opCommit.execute();
    OperationBinding opCreateInsert = ADFUtils.findOperation("CreateInsert");
    opCreateInsert.execute();
    In page bindings Commit and CreateInsert must exist
    then the button actionListener will be
    <af:commandButton actionListener="#{backing.CommitAndInsert}"

  • How to get last insert/update/delet row of a table?

    I hava a table A and table B which is a copy of A. I want to create a trigger to record the changes of A in B. So every time inserting/updating/deleting A I record the row inserted/updated/deleted in B, But I can't find a effiencial way to get the latest row changed.
    So is there any sys_var in oracle table like cur_rowid or something to record the latest inserted/updated/deleted in a table? I don't want to check a index or a table to get the max_seq_id again.

    user11228816 wrote:
    I hava a table A and table B which is a copy of A. I want to create a trigger to record the changes of A in B. So every time inserting/updating/deleting A I record the row inserted/updated/deleted in B, But I can't find a effiencial way to get the latest row changed.
    So is there any sys_var in oracle table like cur_rowid or something to record the latest inserted/updated/deleted in a table? I don't want to check a index or a table to get the max_seq_id again.Sounds like an ugly requirement, any reason you're not going for materialized views or advanced replication here?

  • How to Track the table using Trigger or any other Object

    Hi Folks
    I need to audit Inserts, deletions, updates  to inserted into other tracking table. I was planning on using a trigger to do this,
    Can you please help me how can I wright code for trigger for this. or else using any other object we can do this operation.
    can you please help me thanks in advance.
    Thank in advance.

    Also you can use an OUTPUT clause ( need to modify your DML operations)
    create table itest ( i int identity not null primary key, j int not null unique )
    create table #new ( i int not null, j int not null)
    insert into itest (j)
    output inserted.i, inserted.j into #new
    select o.object_id from sys.objects as o
    select * from #new
    drop table #new, itest;
    go
    The example below shows code that uses OUTPUT clause in UPDATE and DELETE statements to insert rows into an audit table.
    create table t ( i int not null );
    create table t_audit ( old_i int not null, new_i int null );
    insert into t (i) values( 1 );
    insert into t (i) values( 2 );
    update t
       set i  = i + 1
    output deleted.i, inserted.i into t_audit
     where i = 1;
    delete from t
    output deleted.i, NULL into t_audit
     where i = 2;
    select * from t;
    select * from t_audit;
    drop table t, t_audit;
    go
    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

  • How to execute host command in trigger

    dear professional:
    i'm trying to create a trigger that when a certain value inserts into a table , it fires some UNIX command to do the job following
    here is what i tried ,create a trigger that gives host command , but when i tried insert , it fails to work
    i also tried dbms_pipe ,but seems same when using dynamic sql to do the job
    any idea of how to accomplish this task ?
    many thanks ~
    br/ricky
    SQL> CREATE OR REPLACE TRIGGER price_exec
    2 BEFORE INSERT ON omc.price_test
    FOR EACH ROW
    BEGIN
    IF :NEW.price = 4 THEN
    execute immediate 'host ll';
    END IF;
    END price_exec;
    / 3 4 5 6 7 8 9
    Trigger created.
    SQL> insert into price values ('test',4);
    insert into price values ('test',4)
    ERROR at line 1:
    ORA-00942: table or view does not exist
    SQL> insert into price_test values ('test',4);
    insert into price_test values ('test',4)
    ERROR at line 1:
    ORA-00900: invalid SQL statement
    ORA-06512: at "OMC.PRICE_EXEC", line 3
    ORA-04088: error during execution of trigger 'OMC.PRICE_EXEC'

    hi,
    my db is 9.2
    i'm aware of schedule you mentioned , but if it's up to the task , you don't know when a row with certain value is inserted
    simple way :
    when a row inserted into a table with value "catch me" you want to know who inserted this test value
    so you tried to create a trigger to catch program, machine, module ,and terminal info from v$session
    so you can figure out where it is coming from
    and i want to go a step further , by executing some os command to digging out more
    and i come up with this , when value 4 is inserted i exec a procedure host to execute command,
    the problem is it's not working as i exepcted , so spare me the lecture of reading docs and just tell me what to do
    i'd really appreciate it , thanks
    CREATE OR REPLACE TRIGGER price_exec
    BEFORE INSERT ON omc.price_test
    FOR EACH ROW
    BEGIN
    IF :NEW.price = 4 THEN
    execute immediate 'host('echo')';
    END IF;
    END;
    Warning: Trigger created with compilation errors.
    SQL> show errors
    Errors for TRIGGER PRICE_EXEC:
    LINE/COL ERROR
    3/30 PLS-00103: Encountered the symbol "ECHO" when expecting one of
    the following:
    . ( * @ % & = - + ; < / > at in is mod not rem return
    returning <an exponent (**)> <> or != or ~= >= <= <> and or
    like between into using || bulk
    The symbol ". was inserted before "ECHO" to continue.

  • Master-Detail Multi-Row Insert

    Im still using Oracle forms 6i. How do we create here in ADF for the transaction in master-detail operation specially in inserting multi-row in detail. In forms we can use key-next item trigger next_record for new record transaction for drugs or we can use bar code scanning to insert new records & automatically go to next records waiting for another input...
    pls help me i want to upgrade & pls sorry for my english...
    just want this adf behave like forms in terms of master-detail transaction entry...
    i appreciate if someone can help me or give me demo file to download & play with it...
    Edited by: user8983555 on Nov 10, 2010 10:30 AM

    tnx for the fast reply..
    im new with jdeveloper and no knowledge in java or html. im concentrated in pl/sql , forms 6i.We still using this until now in character base in unix environment but some module in gui mode.im working in hospital which is complete informations sytem (stock,pharm..etc...gl...) which in bulk transactions specially patients outclinic & inpatients charges.now we have also this reservations system for out clinics thats the reason im like to develop for in a web that a patient can reserve on line and i dont like running our application in different front end (forms 6i &jdeveloper).
    (now currently checking form10g & just set up AS10g which is working.can deploy and connect,LAN). but im very interested in ADF when i see the demo on Oracle website.
    now our company pplanning to change our application to power builder whiich is not good in performance regarding in hadling big databases (slow query,needs burst AS...) thru to the demonstration of the
    apllication vendors.
    im very glad if you can help. can you post a links or demo file to do this as you said....(You can replicate the code in the button in some other event on your page, for example when the value of the last field in the row is changed.
    It all comes down to the question of when you actually want to create a new row, and in that event you call the createInsert method.)
    this is my only problem now to make this master-detail multi-row insert like ora form.
    again sorry for my english...

  • JDeveloper 10.1.2.3 Row Insert Update issue

    All,
    We have a problem we hope you can help solve, using JDeveloper 10.1.2.3.0 with JHeadStart 10.1.3.3.87 and its easy to reporduce and its a bad one.
    Create a simple web project > Create Entity/VO for one table > Enable JHeadStart >
    Use JHS to create Master Detail drill down single record
    Run app > Open Browser to the Master list > press button Create X to bring up a new row NOW open another browser TAB and do the same so we have 2 forms open in INSERT mode.
    Press Save on 1st tab to trigger the Insert - fine it reloads the form after commit and row is in the DB THEN switch to the other tab and submit that one > this one will overwire the record you entered 1st.
    This is bad and its happening often when we load the system with many users event without multiple (multiple tabs makes it easy to test) - trapping the doDML we expect the 2nd insert request to be DML_INSERT but we get DML_UPDATE. Depending on refresh setting on some attributes we will get error back JBO-25014 but if no refresh on insert update you still get the same issue only one row in db and 1st row gets over written.
    If you have any ideas what is going on and how to solve this ASAP that would be great.
    Thank you
    Anthony

    Steven,
    Thanks for the entry. Yes, we realized that the two-tab browser scenario was the same session. The thing that baffled us was why our test without JHS allowed two inserts in a two-tab, same session situation whereas with JHS, the second insert did an update on the first record committed. We suspected it had something to do with how the current row pointer in the view cache/entity cache was being handled.
    The main symptom we started with was that users in separate sessions in production are overwriting each other's records; and we agree with you, it is surprising but we can reproduce it when traffic is "heavy" (more than four users usually) or the operations are rapid fire -- less than a minute between User 1 inserting a record and User 2 inserting a record. The second user insert operation acutally updates user 1's record even though the data for both inserts is different.
    We switched EnableTokenValidation to "true" and this "fixes" the two-tab, single session situation -- the second insert presents a row currency JBO error (much better than overwriting the first record). In a two-user session scenario, the effect is worse with this setting: the second user trying to insert actually updates a different record from the record the first user just inserted.
    This seems to point to users sharing a view/entity cache and it seems like that might be an ADF or maybe an OC4J bug -- we are using datasources on OAS and an HTTPS protocol for this app.
    So next we are going to try using a database procedure that overrides the Save operation on new (and updated) records. If the database procedure sees a negative ID (from DBSequence) it will insert regardless of the current record pointer. If the database procedure sees a positive ID, it will update that record. I think we'll also need to roll back the CreateInsert that got us to the new record screen, too. Messy, yes, but if this effect is due to an ADF 10.1.3 bug, rewriting the app in 11g would take much longer.
    Our other ADF JHS 10.1.3 apps do not have this problem as far as we know, but they do not use datasources or HTTPS.
    Peter

  • How to update two tables with trigger

    Hi:
    how to update two tables with trigger ?
    I have two tables :
    (1)ASIA
    MI number;
    (2)ASIA_P
    ID number;
    When I insert a new value into the asia.MI ,I also can
    insert the same value into the asia_p.id field.
    I have write a trigger as follows but it does't work.
    create or replace trigger MI_TRG
    before insert on asia
    for each row
    declare
    seq number;
    begin
    select MI_SEQ.Nextval into seq from dual;
    :new.MI:=seq;
    insert into ASIA_PRO(MI_ID)
    values
    (seq);
    end MI_TRG;
    How to realize it ?
    thanks
    zzm

    Why do you say it does not work?

  • How to check the insert stmt

    Hi,
    How to check whether the following trigger is working properly or not?
    CREATE OR REPLACE TRIGGER employee_ins_t1
       BEFORE INSERT
       ON employee
       FOR EACH ROW
    BEGIN
       SELECT employee_seq.nextval
         INTO :new.id
         FROM dual;
    END;please excuse me if this is very newbie question

    Yeah , I tried to insert some data into the table but getting the following error: So confused how to check the trigger is working
    SQL> insert into employee(id, ename) values (null, 'abc');
    insert into employee(id, ename) values (null, 'abc')
    ERROR at line 1:
    ORA-08004: sequence EMPLOYEE_SEQ.NEXTVAL exceeds MAXVALUE and cannot be
    instantiatedEdited by: Smile on Feb 19, 2013 2:24 AM

  • Preventing duplicate rows insertion

    suppose i have a table with 2 columns
    no constraints are there
    then how i will prevent duplicate rows insertion using triggers.

    but i tried to solve the poster's requirement.yes, but the trigger does not solve it.
    The example you posted above, try this:
    do the first insert in your first sql*plus session, and then without committing, open another sql*plus session and do the second insert.
    Do you see an error?
    SQL> create table is_dup(x number, y varchar2(10));
    Table created.
    SQL> CREATE OR REPLACE TRIGGER chk
      2      BEFORE INSERT ON is_dup
      3      FOR EACH ROW
      4  BEGIN
      5      FOR i IN (SELECT * FROM is_dup)
      6      LOOP
      7          IF (:NEW.x = i.x) AND
      8             (:NEW.y = i.y)
      9          THEN
    10              raise_application_error(-20005, 'Record already exist...');
    11          END IF;
    12      END LOOP;
    13  END;
    14  /
    Trigger created.
    SQL> insert into is_dup values(123,'MYNAME');
    1 row created.
    SQL>
    SQL> $sqlplus /
    SQL*Plus: Release 10.2.0.1.0 - Production on Sun Apr 23 10:17:07 2006
    Copyright (c) 1982, 2005, Oracle.  All rights reserved.
    Connected to:
    Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
    With the Partitioning, OLAP and Data Mining options
    SQL> insert into is_dup values(123,'MYNAME');
    1 row created.
    SQL> exit
    Disconnected from Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
    With the Partitioning, OLAP and Data Mining options
    SQL> select * from is_dup ;
             X Y
           123 MYNAME
           123 MYNAME
    SQL> commit ;
    Commit complete.
    SQL> select * from is_dup ;
             X Y
           123 MYNAME
           123 MYNAME
    SQL>

  • How to cancel email notification from snapshot and simulation

    Hi,
    We've activated workflow template WS28700001 so that email notification can be triggered when task release. Meanwhile we are using snapshot and simulation at the same time. But when saving sanpshot or simulation the tasks which have status of released also trigger email nofitication. How to cancel this notification of snapshot and simulation?
    Regards.

    Hi Ravi
    I have added a Container Element(version) in workflow template WS28700001 and set a workflow start condition as follows.
    &Task.Version& = ' '
    Regards
    Yemi

Maybe you are looking for