Learning Pl/SQL here: Help creating a trigger

Hello everyone.
I am just learning PL/SQL here and have tasked with creating at trigger. The trigger basically needs to fire off a email when any records are updated on a specific table.
So far, I was going to use the built in procedure utl_smtp. I have that part configured, but where I am struggly is how to tell the trigger work when the table is updated with new data.
I am a little lost here so any help is greatly appreciated.
Thanks,
JW

Hello! I have following code for a trigger that fires when some record inserted in the table. However I got following error. Like this for example "ERROR at line 38: PL/SQL: Statement ignored". What is wrong whith the code?
CREATE OR REPLACE TRIGGER "SPEAKERS_T2"
AFTER
insert on "SPEAKERS"
for each row
declare
sender varchar2(80) := '[email protected]';
recipient varchar2(80) := '[email protected]';
smtpHost varchar2(80) := 'smtp.hotmail.com';
smtpUser varchar2(256) := 'someusername';
smtpPassword varchar2(256) := '<password>';
mail_conn utl_smtp.connection;
separator varchar2(1) := ' ';
content_charset varchar2(8) := 'utf8';
procedure send_header(name in varchar2, header in varchar2) as
begin
utl_smtp.write_raw_data(mail_conn, UTL_RAW.cast_to_raw(name||': '||header||utl_tcp.CRLF));
end;
begin
mail_conn := utl_smtp.open_connection(smtpHost, 25);
utl_smtp.helo(mail_conn, smtpHost);
-- If Authentication required for SMTP
-- After upgrade to Oracle 9i, replace demo_base64.encode
-- with the native utl_encode.base64_encode for better performance.
utl_smtp.command(mail_conn, 'AUTH LOGIN');
utl_smtp.command(
mail_conn, utl_raw.cast_to_varchar2(
utl_encode.base64_encode(utl_raw.cast_to_raw(smtpUser))
utl_smtp.command(
mail_conn, utl_raw.cast_to_varchar2(
utl_encode.base64_encode(utl_raw.cast_to_raw(smtpPassword))
utl_smtp.mail(mail_conn, sender);
utl_smtp.rcpt(mail_conn, recipient);
utl_smtp.open_data(mail_conn);
send_header('From', sender);
send_header('To', recipient);
send_header('CC', recipient);
send_header('Subject', 'Test');
send_header('MIME-Version', '1.0');
send_header('Content-Type', 'text/plain; charset="utf8"');
utl_smtp.write_raw_data(
mail_conn, utl_raw.cast_to_raw(utl_tcp.CRLF||' ')
utl_smtp.close_data(mail_conn);
utl_smtp.quit(mail_conn);
end;

Similar Messages

  • Help creating a trigger

    I need to create a trigger that makes an exeption error on a insert statement when the salary is > 3500 on scott.emp

    Hi ,
    try the following...
    CREATE OR REPLACE TRIGGER TRG_SAL_CHECK
    BEFORE INSERT OR UPDATE ON EMP
    FOR EACH ROW
    BEGIN
    IF :NEW.SAL>3500 THEN
    RAISE_APPLICATION_ERROR (-20001,'SAL TOO MUCH...');
    END IF;
    END;
    Simon
    /

  • Pl/Sql Error while creating a trigger

    Hello everyone m trying to make a trigger whose purpose is not to allow any update insert or delete to be done on the table Work if the day is sunday.I tried this code but it is giving me error
    create or replace trigger No_work_on_Sunday
    After insert or update or delete
    on Work When owner='MAX'
    for each row
    begin
            if (select to_char(sysdate,'D')=1) then
                     raise_application_error(-20001,'no work on sunday');
          end if;
    end;
    on Work when owner='MAX'
    ERROR at line 3:
    ORA-04077: WHEN clause cannot be used with table level triggers Pls help
    Edited by: 781207 on Jul 16, 2010 7:43 AM

    create or replace trigger No_work_on_Sunday
    before insert or update or delete
    for each row
    on Work When owner='MAX'
    begin
            if to_char(sysdate,'D')=1 then
                     raise_application_error(-20001,'no work on sunday');
          end if;
    end;
    /Keep in mind to_char(sysdate,'D')=1 is NLS dependent. In US week starts Sunday in most european some coutries week starts Monday. In middle east it can be Friday or Saturday...
    SY.
    Edited by: Solomon Yakobson on Jul 16, 2010 7:50 AM

  • Basic help needed creating a trigger

    I'm completely new to SQL programming altogether, and I'm trying to set up a trigger that will make some checks before adding a new row to a given table. I am trying to do this because I need to enforce a CONSTRAINT that checks whether the dates entered for 'deadline' and 'startDate' are greater than sysdate and less than (sysdate + 365), and I found out that you cannot reference sysdate from a CONSTRAINT. Therefore I am now attempting to do this using a trigger, but I don't really know how to do this. Here is the sql code used to create the table:
    -- PLACEMENT TABLE
    DROP TABLE placement;
    CREATE TABLE placement
    contactId Int,
    placementId Int,
    position VARCHAR(60),
    description CLOB,
    lengMonths Int,
    salary Number(7,2),
    deadline DATE,
    startDate DATE,
    addrLine1 VARCHAR(120),
    postCd VARCHAR(10)
    And here is my attempt at creating the trigger that will only allow the deadline and startDate to be entered if they satisfy the following check: (sysdate < deadline/startDate <= sysdate+365)
    CREATE OR REPLACE TRIGGER trg_deadline_low BEFORE INSERT OR UPDATE OF deadline ON placement
    BEGIN
    IF :deadline <= SYSDATE THEN
    ROLLBACK;
    END IF;
    END;
    CREATE OR REPLACE TRIGGER trg_deadline_high BEFORE INSERT OR UPDATE OF deadline ON placement
    BEGIN
    IF :deadline > SYSDATE + 365 THEN
    ROLLBACK;
    END IF;
    END;
    If possible, I would like for these triggers to display an error rather than just using ROLLBACK, but I'm not sure how! At the moment, these triggers do not work at all; I get an error message "Warning: Trigger created with compilation errors." when I attempt to create the triggers in the first place.
    Can anyone tell me why I am seeing this error when trying to implement the triggers? And if anyone could also improve on my amateur attempt at coding a trigger, then that would be great! Thanks for any help!

    Oops!
    Nicolas, Thank you for correcting my mistake.
    SQL> edit
    Wrote file afiedt.buf
    1 CREATE TABLE placement
    2 (
    3 contactId Int,
    4 placementId Int,
    5 position VARCHAR(60),
    6 description CLOB,
    7 lengMonths Int,
    8 salary Number(7,2),
    9 deadline DATE check (deadline between sysdate and sysdate+365),
    10 startDate DATE,
    11 addrLine1 VARCHAR(120),
    12 postCd VARCHAR(10)
    13* )
    SQL> /
    deadline DATE check (deadline between sysdate and sysdate+365),
    ERROR at line 9:
    ORA-02436: date or system variable wrongly specified in CHECK constraint
    SQL> edit
    Wrote file afiedt.buf
    1 CREATE TABLE placement
    2 (
    3 contactId Int,
    4 placementId Int,
    5 position VARCHAR(60),
    6 description CLOB,
    7 lengMonths Int,
    8 salary Number(7,2),
    9 deadline DATE check (deadline between to_date('2007-03-21','yyyy-mm-dd') and to_date('2008-03-21','yyyy-mm-dd')
    10 startDate DATE,
    11 addrLine1 VARCHAR(120),
    12 postCd VARCHAR(10)
    13* )
    SQL> /
    Table created.
    On the contrary, I think that OP want an error instead of rollback : "I would like for these triggers to display an error rather than just using ROLLBACK"Ah, I had misread additionally. Sorry.

  • Help me in creating a Trigger for Insert and Update Options

    Hi
    Please help me in creating a Trigger .
    My requirement is that after insert or update on a Table , i want to fire an event .
    I have started this way ,but doesn't know how to fully implement this .
    say i have a dept table
    CREATE TRIGGER DepartmentTrigger
    AFTER INSERT ON Dept
    BEGIN
    INSERT INTO mytable VALUES("123","Kiran");
    END DepartmentTrigger;
    Please tell me how can i put the Update option also .
    Thanks in advance .

    Please tell me how can i put the Update option also .Add "Or Update". ;-)
    Here are a few suggestions, but you definitely need to refer to the manual page that the previous poster suggested.
    CREATE OR REPLACE TRIGGER DepartmentTrigger
    AFTER INSERT Or Update ON Dept
    BEGIN
    INSERT INTO mytable VALUES(:new.Dept,'DEPT ADDED OR CHANGED');
    END DepartmentTrigger;
    The "Or Replace" means you can replace the trigger while you're developing without having to type in a drop statement every time. Just change and rerun your script, over and over until you get it right.
    Adding "Or Update" or "Or Delete" makes the trigger fire for those events too. Note, you may want seperate triggers in different scripts and with different names for each event. You have to decide if your design really does the same thing whether it's an insert or an update.
    :new.Dept is how you would refer to the changed vale of the Dept column (:old.Dept is the prior value). I changed the double quotes on the string in the VALUES clause to single quotes.
    Andy

  • Need help creating trigger with delete capabilities

    I have two tables:
    create table person(userid integer,
    lname varchar(20),
    fname varchar (20),
    phone_number varchar(12),
    email_address varchar(35),
    city varchar(20),
    zip_code varchar(20),
    department varchar(20),
    major_street varchar(20),
    cross_street varchar(20),
    notes varchar(100),
    Primary Key (userid));
    create table vehicle(car_id integer,
    make varchar(15),
    model varchar(20),
    year integer,
    gas_mileage integer,
    capacity integer,
    owner integer,
    primary key (car_id),
    foreign key (owner) references person (userid));
    I am trying to create a trigger that would delete all those records in vehicle whenever someone deletes a record in the person table. Here is the code that I run but it get a compilation error. Here is the the trigger text followed by the error:
    CREATE OR REPLACE TRIGGER ON_DELETE_PERSON
    AFTER DELETE ON person FOR EACH ROW
    BEGIN
    DELETE from vehicle
    where owner=userId;
    END;
    2/4 PL/SQL: SQL Statement ignored
    3/19 PL/SQL: ORA-00904: "USERID": invalid identifier
    Any suggestions?

    CREATE OR REPLACE TRIGGER ON_DELETE_PERSON
    BEFORE DELETE ON person FOR EACH ROW
    BEGIN
    DELETE from vehicle
    where owner=:old.userId;
    END;

  • Need Help in creating this trigger

    I need your help to create this trigger. I need to set the default fl in this table depending on various conditions:
    If there is only one indvl with end date as null then set the default_pk column for that indvl as 'Y'
    ELSE
    If there are multiple indvl_pks in this table with NULL end date then set the default_fl column to 'Y' for the indvl_pk with the earliest start date .
    ELSE if there are multiple indvls with same start date then set the dflt_fl to 'Y' with the minimum br_pk
    I am unable to get this to work due to the mutating trigger problem.
    For example in this one rows with emplt_pk with 1001 and 1003 will be set to 'Y'.
    create table emplt
    emplt_pk number,
    indvl_pk number,
    start_dt date,
    end_dt date,
    lct_fl char(1),
    sup_fl char(1),
    br_pk number,
    nro_pk number,
    default_fl
    char(1) default 'N' );
    INSERT
    INTO emplt
    values(1001, 101, to_date ('01-01-2005', 'MM-DD-YYYY' ), NULL, 'Y','N' ,123,NULL,NULL );
    INSERT INTO emplt values(
    1002, 101, to_date ('02-01-2005', 'MM-DD-YYYY' ), NULL, 'Y','N' ,NULL,0001,NULL );
    INSERT INTO emplt values(
    1003, 102, to_date ('02-01-2005', 'MM-DD-YYYY' ), NULL, 'Y','N' ,NULL,0001,NULL );
    Thanks in advance

    the Easy Tabs could be useful for your requirement
    http://usermanagedsolutions.com/SharePoint-User-Toolkit/Pages/Easy-Tabs-v5.aspx
    /blog
    twttr @esjord

  • Help with create a trigger

    hello all
    i have a 4 tables and i would like to create a trigger in a tables
    CREATE TABLE CLIENT_INFO
    ( CLIENT_NO     VARCHAR2(10) CONSTRAINT CLIENT_INFO_CNO_PK PRIMARY KEY,
      CLIENT_NAME   VARCHAR2(50) NOT NULL,
      ORDERS_AMOUNT NUMBER(7)
    CREATE TABLE STOCK_INFO
    ( ITEM_NO              VARCHAR2(10) ,
      ITEM_DESCRIPTION     VARCHAR2(100),
      SELLING_PRICE        NUMBER(6),
      QTY_IN_HAND          NUMBER(6)    NOT NULL,
      CONSTRAINT ITEM_NUM_SPRICE_PK PRIMARY KEY (ITEM_NO , SELLING_PRICE)
    CREATE TABLE ORDER_INFO
    ( ORDER_NO     VARCHAR2(10) CONSTRAINT ORDER_INFO_ONO_PK PRIMARY KEY,
      CLIENT_NO    VARCHAR2(10),
      ORDER_DATE   DATE,
      ORDER_AMOUNT NUMBER(6),
      CONSTRAINT ORDER_INFO_CNO_FK  FOREIGN KEY (CLIENT_NO) REFERENCES CLIENT_INFO (CLIENT_NO)
    CREATE TABLE ORDER_LINES
    ( ORDER_NO       VARCHAR2(10),
      ITEM_NO        VARCHAR2(10),
      LINE_QTY       NUMBER(6),
      SELLING_PRICE  NUMBER(6),
      TOTAL_PRICE    NUMBER(6)
    ALTER TABLE ORDER_LINES
    ADD  CONSTRAINT ORDER_LINES_ONO_FK FOREIGN KEY (ORDER_NO) REFERENCES ORDER_INFO (ORDER_NO);
    ALTER TABLE ORDER_LINES
    ADD  CONSTRAINT ORDER_LINES_INO_FK FOREIGN KEY (ITEM_NO) REFERENCES STOCK_INFO (ITEM_NO);i would like to create this trigger
    1-order_amount in table 3 due to any (insert,update or delete ) in total_price in table 4
    2-orders_amount in table 1 due to any (insert,update or delete ) in order_amount in table 3
    i would like to ask another quotations r this relations in good for tables
    thank's all

    >
    plz i need a help to create a trigger
    >
    Using a trigger won't solve your problem. You are trying to use child table triggers to maintain parent table information.
    There is no transaction control to ensure that the parent table will be updated with the correct information.
    One process could update child record 1 while another process is updating child record two. Each process will see a different total if they try to compute the sum of all child records since the first process will see the 'old' value for the child record that the second process is updating and the second process will the 'old' value for the child record that the first process is updating.
    So the last process to commit could store the wrong total in the parent record withoug an exception ever being raised.
    See Conflicting Writes in Read Committed Transactions in the Database Concepts doc
    http://docs.oracle.com/cd/E14072_01/server.112/e10713/consist.htm
    >
    some one ask me this quotation in interview
    and im told him i can't understand this structure for database he said just do it
    >
    And I would tell them that using a trigger is not the right way to accomplish that since it could invalidate the data concurrency and data consistency of the tables.
    Sometimes you just have to tell people NO.

  • Help needed in creating a trigger

    hi,
    I am creating a Trigger which keep track of the updates of a particular table.
    Whenver a col value is updated i want to insert a row into newtable, with colname,old value and new value.
    How do we get to know which col value is changed in a table?
    Thanks

    I have seen the approach you propose (1 row for each column changed) and it is tedious and prone to maintenance headaches. You have to write code for each column, doing compares (remembering to consider NULLs), dealing with different datatypes, etc. You also have to decide how to record inserts and deletes.
    An easier trigger-based solution is to create a history table for the table you want to track, with all of the columns from the original, plus whatever else you need for housekeeping. Write an After Insert/Update/Delete trigger on your base table, and populate/insert rows into the history table:
    - For inserts, populate and insert row from the :new. values
    - For deletes, populate and insert a row from the :old. values
    - For updates, popualte and insert a row from the :old. values and another from the :new. values
    I would also have a column to designate whether this is an Insert, Delete, Update-Old or Update-New row.
    Once you have done one example, the rest are easy. If you were sufficiently motivated (I have not yet been), you could probably write a script to query DBA_TAB_COLS and generate the code.

  • Creating a trigger to enforce data validation

    I would like to create a trigger to do some basic data validation. For example, to join an honors society a student must have a gpa between 3.7 and 4.0. I want this to fire before an insert on the table NatlHonSoc, and the field name is gpa.
    Thanks!

    user8775995 wrote:
    I'm trying to learn how to use triggers and just made this example up. It always helps to state your real intent from the beginning.
    All I have is the general syntax from a book <snip>"A" book? Which book? Just any old book?
    There is no book better to start with than the official documentation.
    Learning where to look things up in the documentation is time well spent investing in your career. To that end, you should drop everything else you are doing and do the following:
    Go to tahiti.oracle.com. Drill down to your product and version.
    Spend a few minutes just getting familiar with what is available here. Take special note of the "books" and "search" tabs. Under the "books" tab you will find the complete documentation library.
    Spend a few minutes just getting familiar with what kind of documentation is available there by simply browsing the titles under the "Books" tab.
    Open the Reference Manual and spend a few minutes looking through the table of contents to get familiar with what kind of information is available there.
    Do the same with the SQL Reference Manual.
    Do the same with the Utilities manual.
    You don't have to read the above in depth. They are reference manuals. Just get familiar with what is there to be referenced. Ninety percent of the questions asked on this forum can be answered in less than 5 minutes by simply searching one of the above manuals.
    As pointed out by Centinul, for your purpose, you should include the Application Developer's Guide as part of your "must reference" books.
    Then set yourself a plan to dig deeper.
    - Read a chapter a day from the Concepts Manual.
    - Look in your alert log and find all the non-default initialization parms listed at instance startup. Then read up on each one of them in the Reference Manual.
    - Take a look at your listener.ora, tnsnames.ora, and sqlnet.ora files. Go to the Network Administrators manual and read up on everything you see in those files.
    - When you have finished reading the Concepts Manual, do it again.
    Give a man a fish and he eats for a day. Teach a man to fish and he eats for a lifetime.

  • Oracle SQL template to create re-usable DDL/DML Scripts for Oracle database

    Hi,
    I have a requirement to put together a Oracle SQL template to create re-usable DDL/DML Scripts for Oracle databases.
    Only the Oracle DBA will be running the scripts so permissions is not an issue.
    The workflow for any DDL is as follows:-
    1) New Table
    a. Check if the table exists from the system/admin views.
    b. If table exists then give message "Table Exists"
    c. If table does not exist then execute DDL code
    2) Add Column
    a. Check if Column exists for a given table from system/admin views
    b. If column exists in the specified table,
    b1. backup table.
    b2. alter table to make changes to the column
    b3. verify data or execute dml script convert from backup to the new change.
    c. If Column does not exist
    c1. backup table
    c2. alter table to add column
    c3. execute dml to populate column with default value.
    The DML scripts are for populating base tables with data required for business operations.
    3) Add new row
    a. check if row exists by comparing old values of each column with new values to be added for the new record.
    b. If exists, give message row exists
    c. If not exists, add new record.
    4) Update existing record (We have createtime columns in these tables so changes can be tracked)
    a. check if row exists using primary key.
    b. If exists,
    b1. deactivate the record using the "active" column of the table
    b2. Add new record with the changes required.
    c. If does not exist, add new record with the changes required.
    Could you please help with some ideas which can get this done accurately?
    I have tried several ways, but I am not able to put together something that fulfills all requirements.
    Thank you,

    First let me address your question. (This is the easy part.)
    1. The existence of tables can be found in DBA_TABLES. Query it and and then use conditional logic and execute immediate to process the DDL.
    2. The existence of table columns is found in DBA_TAB_COLUMNS. Query it and then conditionally execute your DDL. You can copy the "before picture" of the table using that same dba view, or even better, use DBMS_METADATA.
    As for your DML scripts, they should be restartable, reversible, and re-run-able. They should "fail gracefully" on error, be written in such a way that they can run twice in a row without creating duplicate changes.
    3. Adding appropriate constraints can prevent invalid duplicate rows. Also, you can usually add to the where clause so that the DML does only what it needs to do without even relying on the constraint (but the constraint is there as a safeguard). Look up the MERGE statement to learn how to do an UPSERT (update/insert), which will let you conditionally "deactivate" (update) or insert a record. Anything that you cannot do in SQL can be done with simple procedural code.
    Now, to the heart of the matter...
    You think I did not understand your requirements?
    Please be respectful of people's comments. Many of us are professionals with decades of experience working with databases and Oracle technology. We volunteer our valuable time and knowledge here for free. It is extremely common for someone to post what they feel is an easy SQL or PL/SQL question without stating the real goal--the business objective. Experienced people will spot that the "wrong question" has been asked, and then cut to the chase.
    We have some good questions for you. Not questions we need answers from, but questions you need to ask yourself and your team. You need to reexamine this post and deduce what those questions are. But I'll give you some hints: Why do you need to do what you are asking? And will this construct you are asking for even solve the root cause of your problems?
    Then ponder the following quotations about asking the right question:
    Good questions outrank easy answers.
    — Paul Samuelson
    The only interesting answers are those which destroy the questions.
    — Susan Sontag
    The scientific mind does not so much provide the right answers as ask the right questions.
    — Claude Levi-Strauss
    You can tell whether a man is clever by his answers. You can tell whether a man is wise by his questions.
    — Mahfouz Naguib
    One hears only those questions for which one is able to find answers.
    — Friedrich Nietzsche
    Be patient towards all that is unresolved in your heart and try to love the questions themselves.
    — Rainer Maria Rilke
    What people think of as the moment of discovery is really the discovery of the question.
    — Jonas Salk
    Judge a man by his questions rather than his answers.
    — Voltaire
    The ability to ask the right question is more than half the battle of finding the answer.
    — Thomas J. Watson

  • Create Table Trigger to replicate data from MSSQL2K5 to Oracle 11G on Linux

    I am trying to create a trigger on my MSSQL 2k5 server so that when a record is inserted, a replicated record is created in a table on an Oracle 11g database on a Linux server (Oracle Linux 6).
    Creating the trigger is easy, but when I test it I am getting an error stating the following:
    .NetSqlClient Data Provider The operation could not be performed because OLE DB Provider 'OraOLEDB.Oracle' for linked server "<myserver>" was unable to begin the distributed transaction.
    OLEDB Provider "OraOLEDB.Oracle" for linked server "<myserver>" returned: "New transaction cannot enlist in the specified transaction coordinator"
    Here is the trigger (MSSQL):
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    CREATE PROCEDURE insert_aban8_state
        @an8 int,
        @st nvarchar(3)
    AS
    BEGIN
        SET NOCOUNT ON;
        declare @c numeric
        select @c = count(*) from [e9db]..[CRPDTA].[ABAN8_STATE$] where alan8=@an8 and aladds=@st
        if(@c =0)
         begin
            insert into [e9db]..[CRPDTA].[ABAN8_STATE$]
            values(@an8, @st)
         end
        END
    GO
    After reviewing the MS Transaction Coordinator, I am now totally confused. I checked the services and have the MS DTC enabled and running, but am not sure what to do on the Linux side.
    Does the Oracle Services for Microsoft Transaction Server (OraMTS) work on Linux? I could only find references for this for Oracle 11g on Windows.
    What do I need to do to enable this replication via mssql table trigger to Oracle11g on Linux?

    nsidev wrote:
    While I would agree in part, it appears from the message that the trigger is requiring the Transaction Service to be enabled on both the host and target. The point of this post is to determine what, if anything, I need to do on my Oracle DB to allow the trigger to complete successfully.
    There are many posts found with Google concerning the OraMTS service on the Oracle system, but they all appear to be for Windows based systems. My question is, is this service part of the Linux based Oracle DB and if so, how do I initialize it?
    If I am mistaken and this is truly an issue with the MSSQL server, I will replicate the post in those forums. I am just looking for direction and help.
    1) I have NEVER heard that Oracle has, knows about, or supports any "Transaction Service".
    2) Consider what I previously posted regarding the flavor of client source.
    If your assertion about this mythical service were correct, then the Oracle DB would have to be able to "know" that this client connection was originated by SQL Server.
    I don't understand how or why Oracle should behave differently depending upon whether INSERT is done inside or outside a MS SQL Server trigger.
    Please explain & elaborate why Oracle should behave different depending upon the source of any INSERT statement.
    3) From Oracle DB standpoint an INSERT is an INSERT; regardless of the client.

  • Need help on a trigger

    I am using Oracle 9i. I tried to take a lot of the other fields out of this trigger so that the real problem could be seen. I am trying to create a trigger that cleans up a string field, then verifies the new character with a field in another table. Once they are equal it will grab that ID number and place it in required field. Below is what I have so far for the trigger.
    Table 1
    SP_id INTEGER
    TT_id INTEGER
    LEGACY VARCHAR2
    Table 2
    SID NUMBER (10)
    UID VARCHAR2
    DESCRIPTION VARCHAR2
    Table 3
    T_id INTEGER
    NAME VARCHAR2
    CREATE OR REPLACE TRIGGER ABC
    AFTER INSERT OR UPDATE
    ON 2
    REFERENCING NEW AS NEW OLD AS OLD
    FOR EACH ROW
    BEGIN
    IF (INSERTING)
    THEN
    INSERT INTO 1
    (SP_id,
    TT_id,
    LEGACY)
    VALUES (XXX_seq.NEXTVAL,
    substr(:New.description, 1, instr(translate(:New.description, '1234567890', '**********'),'*')-2) ,
    SUBSTR (:NEW.uid, 1, 30));
    END IF;
    END ABC;
    I need to take the parsed character field [substr(:New.description, 1, instr(translate(:New.description, '1234567890', '**********'),'*')-2) ,]
    then verify its value with table 3's NAME field. Once the correct name is found I need to grab the table3.T_id and place it in the TT_id in table 1. Should this all be done in a trigger or should I try to create a function that is then called out in the trigger? Any help, advice, or examples would be appreciated.

    Below I've done it using two different approaches:
    1) using triggers
    2) using an api
    I prefer using an api for mainly for performance reasons, but it's your call
    SQL> create table t1
      2  ( sp_id integer
      3  , tt_id integer
      4  , legacy varchar2(100)
      5  )
      6  /
    Tabel is aangemaakt.
    SQL> create table t2
      2  ( sid number (10)
      3  , u_id varchar2 (100)
      4  , description varchar2(100)
      5  )
      6  /
    Tabel is aangemaakt.
    SQL> create table t3
      2  ( t_id integer
      3  , name varchar2(100)
      4  )
      5  /
    Tabel is aangemaakt.
    SQL> create sequence xxx_seq start with 1 increment by 1
      2  /
    Reeks is aangemaakt.
    SQL> create or replace trigger abc
      2  after insert on t2
      3  for each row
      4  declare
      5    l_t3_id t3.t_id%type;
      6  begin
      7    begin
      8      select t3.t_id
      9        into l_t3_id
    10        from t3
    11       where t3.name = substr(:new.description, 1, instr(translate(:new.description, '1234567890', '**********'),'*')-2)
    12      ;
    13    exception
    14    when no_data_found
    15    then
    16      null;
    17    when too_many_rows
    18    then
    19      null;
    20    end
    21    ;
    22    insert into t1
    23    ( sp_id
    24    , tt_id
    25    , legacy
    26    )
    27    values
    28    ( xxx_seq.nextval
    29    , l_t3_id
    30    , substr (:new.u_id, 1, 30)
    31    );
    32  end abc;
    33  /
    Trigger is aangemaakt.
    SQL> insert into t3 values (1, 'abc')
      2  /
    1 rij is aangemaakt.
    SQL> insert into t3 values (2, 'xyz')
      2  /
    1 rij is aangemaakt.
    SQL> commit
      2  /
    Commit is voltooid.
    SQL> insert into t2 values (11, '12', 'abc 12345')
      2  /
    1 rij is aangemaakt.
    SQL> insert into t2 values (13, '14', 'pqr 65432')
      2  /
    1 rij is aangemaakt.
    SQL> insert into t2 values (15, '16', 'xyza9875123')
      2  /
    1 rij is aangemaakt.
    SQL> select * from t2
      2  /
           SID U_ID                           DESCRIPTION
            11 12                             abc 12345
            13 14                             pqr 65432
            15 16                             xyza9875123
    3 rijen zijn geselecteerd.
    SQL> select * from t1
      2  /
         SP_ID      TT_ID LEGACY
             1          1 12
             2            14
             3          2 16
    3 rijen zijn geselecteerd.This is the end of the trigger approach.
    From here on it's the api approach:
    SQL> rollback
      2  /
    Rollback is voltooid.
    SQL> drop trigger abc
      2  /
    Trigger is verwijderd.
    SQL> create package t2_dml
      2  as
      3    procedure create_t2_and_t1
      4    ( p_sid         t2.sid%type
      5    , p_u_id        t2.u_id%type
      6    , p_description t2.description%type
      7    );
      8  end t2_dml;
      9  /
    Package is aangemaakt.
    SQL> create package body t2_dml
      2  as
      3    procedure create_t2_and_t1
      4    ( p_sid         t2.sid%type
      5    , p_u_id        t2.u_id%type
      6    , p_description t2.description%type
      7    )
      8    is
      9      l_t3_id t3.t_id%type;
    10    begin
    11      insert into t2
    12      ( sid
    13      , u_id
    14      , description
    15      )
    16      values
    17      ( p_sid
    18      , p_u_id
    19      , p_description
    20      );
    21      begin
    22        select t3.t_id
    23          into l_t3_id
    24          from t3
    25         where t3.name = substr(p_description, 1, instr(translate(p_description, '1234567890', '**********'),'*')-2)
    26        ;
    27      exception
    28      when no_data_found
    29      then
    30        null;
    31      when too_many_rows
    32      then
    33        null;
    34      end
    35      ;
    36      insert into t1
    37      ( sp_id
    38      , tt_id
    39      , legacy
    40      )
    41      values
    42      ( xxx_seq.nextval
    43      , l_t3_id
    44      , substr (p_u_id, 1, 30)
    45      );
    46    end create_t2_and_t1
    47    ;
    48  end t2_dml;
    49  /
    Package-body is aangemaakt.
    SQL> exec t2_dml.create_t2_and_t1(11,'12','abc 12345')
    PL/SQL-procedure is geslaagd.
    SQL> exec t2_dml.create_t2_and_t1(13,'14','pqr 65432')
    PL/SQL-procedure is geslaagd.
    SQL> exec t2_dml.create_t2_and_t1(15,'16','xyza9875123')
    PL/SQL-procedure is geslaagd.
    SQL> select * from t2
      2  /
           SID U_ID                           DESCRIPTION
            11 12                             abc 12345
            13 14                             pqr 65432
            15 16                             xyza9875123
    3 rijen zijn geselecteerd.
    SQL> select * from t1
      2  /
         SP_ID      TT_ID LEGACY
             4          1 12
             5            14
             6          2 16
    3 rijen zijn geselecteerd.I hope this helps.
    Regards,
    Rob.

  • ORA-06552 and ORA-06553 when creating a trigger

    Hey Everyone,
    I have a issue when i try and create a trigger on a view. I get this error message.
    ORA-06552: PL/SQL: Compilation unit analysis terminated
    ORA-06553: PLS-320: the declaration of the type of this expression is incomplete or malformedThis is the Desc of the view.
    Table          Column               Data Type     Length     Nullable
    NCRCPV01     ROWID               UROWID          4000     -
              LOB_ID               VARCHAR2     1     -
              PRG_ID               VARCHAR2     1     -
              PSG_ID               VARCHAR2     1     -
              SMP_ID               VARCHAR2     4     -
              PTP_ID               VARCHAR2     1     -
              COU_ISO_ID          VARCHAR2     2     -
              PLC_DOM_INT_CD          VARCHAR2     1     -
              PLC_EFFECT_DT          DATE          7     -
              PLC_EFFECT_TO_DT     DATE          7     -
              PLC_UPDT_TD          DATE          7     -
              PLC_UPDT_USER_ID     VARCHAR2     8     -
              PLC_SOFTLOCK_TS          TIMESTAMP(6)     11     -
              PLC_LATST_COL_TM     DATE          7     nullable
              PLC_HANDRATE_IN          VARCHAR2     1     nullable
              PLC_VL_MAND_ODE_IN     VARCHAR2     1     nullableThis is the SQL of the trigger im trying to exicute.
    CREATE OR REPLACE TRIGGER "UPD_NCRCPV01_TR"
       INSTEAD OF UPDATE
       ON NCRCPV01
       REFERENCING NEW AS NEW OLD AS OLD
       FOR EACH ROW
    BEGIN
       UPDATE NCADMIN.NCRCPV01@CSAHEPA_DBAAPEX.gb.tntpost.com
          SET LOB_ID = :NEW.LOB_ID,
              PRG_ID = :NEW.PRG_ID,
              PSG_ID = :NEW.PSG_ID,
              SMP_ID = :NEW.SMP_ID,
              PTP_ID = :NEW.PTP_ID,
              COU_ISO_ID = :NEW.COU_ISO_ID,
              PLC_DOM_INT_CD = :NEW.PLC_DOM_INT_CD,
              PLC_EFFECT_DT = :NEW.PLC_EFFECT_DT,
              PLC_EFFECT_TO_DT = :NEW.PLC_EFFECT_TO_DT,
              PLC_UPDT_TD = :NEW.PLC_UPDT_TD,
              PLC_UPDT_USER_ID = :NEW.PLC_UPDT_USER_ID,
              PLC_SOFTLOCK_TS = :NEW.PLC_SOFTLOCK_TS,
              PLC_LATST_COL_TM = :NEW.PLC_LATST_COL_TM,
              PLC_HANDRATE_IN = :NEW.PLC_HANDRATE_IN,
              PLC_VL_MAND_ODE_IN = :NEW.PLC_VL_MAND_ODE_IN
        WHERE ROWID = :NEW.UROWID;
    END;I find this really strange as i have created this view and trigger in my dev environment with no issues. Now when im trying to exicute the same code in my production environment im coming up against this error. The only thing that has changed is the database link in the trigger from CSPCCPA_DBAAPEX.TNTEWW.COM to CSAHEPA_DBAAPEX.gb.tntpost.com
    I have googled the error codes and it seems that the most common error is naming a column somthing like DATE, which i have not done.
    Any help here would be appreitated :)
    Thanks,
    -N.S.N.O.

    Hello,
    And are the tables (and columns) of both tables (CSPCCPA_DBAAPEX.TNTEWW.COM and CSAHEPA_DBAAPEX.gb.tntpost.com) exactly the same?
    BTW Why don't you use (the same) synonyms for those tables. Then you don't need to change your code when you move it from dev to prod...
    Greetings,
    Roel
    http://roelhartman.blogspot.com/
    You can reward this reply by marking it as either Helpful or Correct ;-)

  • Help with mutating trigger

    Hi all,
    I have a trigger shown below is gives me the mutating error.
    The error is to do with the select from the payments table (which it does not allow cos of the mutating effect).
    Can anyone give me some ideas on how I can resolve this?
    Thank you very much
    create or replace
    TRIGGER CHECK_INVOICE_PAID_IN_FULL AFTER
    UPDATE OF "PAYMENT_STATUS" ON "PAYMENTS" FOR EACH ROW
    DECLARE
    -- check if all the payments for that invoice have been received (completed)
    -- if they are complete then sum all the payments for that invoice and compare to gross value on invoices
    v_invoice_amount NUMBER;
    v_gross_amount NUMBER;
    thisproc CONSTANT VARCHAR2(80) := 'trap_errmesg for mco_transfer_status';
    v_value VARCHAR2(150);
    BEGIN
    -- Changed as requested by nicola on 12/09/05 IF :NEW.PAYMENT_COMPLETE is not null
    IF :NEW.PAYMENT_STATUS='C' AND :NEW.PAYMENT_STATUS <> :OLD.PAYMENT_STATUS
    THEN
    -- We will sum all the payments for that invoice that have a value in payment_complete
    SELECT NVL(SUM(amount),0) INTO v_invoice_amount FROM payments WHERE payment_complete IS NOT NULL AND invoice_id=:NEW.INVOICE_ID;
    -- We will also get the gross amount for the invoice to compare to the sum of the payments
    SELECT NVL(gross,0) INTO v_gross_amount FROM invoices WHERE
    invoice_id = :NEW.INVOICE_ID ;
    END IF;
    IF v_invoice_amount = v_gross_amount
    THEN
    UPDATE invoices SET paid_date=SYSDATE;
    END IF;
    END CHECK_INVOICE_PAID_IN_FULL;
    /

    Hi Anwar,
    Thanks for this.
    Can you please help me out here
    I did the bit with creating a temporay table to hold the invoice_ids and then created a procedure that will be fired by the trigger, however because of the clause
    IF :NEW.PAYMENT_STATUS='C' AND :NEW.PAYMENT_STATUS <> :OLD.PAYMENT_STATUS
    I cant use a statement level trigger for this procedure and when i use the row level trigger i get the mutating error.
    here is what i have got so far.
    A temporary table which holds the invoice_ids (this is called payments_temp)
    I then created a trigger as below which populates this temp table
    TRIGGER insert_payments_temp BEFORE
    UPDATE OF "PAYMENT_STATUS" ON "PAYMENTS" FOR EACH ROW
    DECLARE
    -- check if all the payments for that invoice have been received (completed)
    -- if they are complete then sum all the payments for that invoice and compare to gross value on invoices
    v_invoice_amount NUMBER;
    v_gross_amount NUMBER;
    thisproc CONSTANT VARCHAR2(80) := 'trap_errmesg for mco_transfer_status';
    v_value VARCHAR2(150);
    BEGIN
    INSERT INTO payments_temp
    VALUES (:NEW.invoice_id);
    END insert_payments_temp;
    Then I created a procedure below which will do the update
    PROCEDURE "CHECK_INVOICE_PAID_IN_FULL_PRO" IS
    -- check if all the payments for that invoice have been received (completed)
    -- if they are complete then sum all the payments for that invoice and compare to gross value on invoices
    v_invoice_amount NUMBER(20);
    v_gross_amount NUMBER;
    thisproc CONSTANT VARCHAR2(80) := 'trap_errmesg for mco_transfer_status';
    v_value VARCHAR2(150);
    BEGIN
    -- We will sum all the payments for that invoice that have a value in payment_complete
    --select sum(amount) into v_invoice_amount from payments where payment_complete is not null and invoice_id=:NEW.INVOICE_ID;
    FOR x IN (SELECT invoice_id FROM payments_temp) LOOP
    SELECT NVL(SUM(amount),0) INTO v_invoice_amount FROM payments
    WHERE payment_complete IS NOT NULL AND invoice_id=X.INVOICE_ID;
    SELECT NVL(gross,0) INTO v_gross_amount FROM INVOICES WHERE
    invoice_id = X.INVOICE_ID ;
    END LOOP;
    -- We will also get the gross amount for the invoice to compare to the sum of the payments
    IF v_invoice_amount = v_gross_amount
    THEN
    UPDATE INVOICES SET paid_date=SYSDATE;
    COMMIT;
    END IF;
    END CHECK_INVOICE_PAID_IN_FULL_PRO;
    Then finally the update trigger itself below
    TRIGGER "NICKC"."CHECK_INVOICE_PAID_IN_FULL" AFTER
    UPDATE OF "PAYMENT_STATUS" ON "NICKC"."PAYMENTS" FOR EACH ROW
    DECLARE
    -- check if all the payments for that invoice have been received (completed)
    -- if they are complete then sum all the payments for that invoice and compare to gross value on invoices
    v_invoice_amount NUMBER;
    v_gross_amount NUMBER;
    thisproc CONSTANT VARCHAR2(80) := 'trap_errmesg for mco_transfer_status';
    v_value VARCHAR2(150);
    BEGIN
    -- Changed as requested by nicola on 12/09/05 IF :NEW.PAYMENT_COMPLETE is not null
    IF :NEW.PAYMENT_STATUS='C' AND :NEW.PAYMENT_STATUS <> :OLD.PAYMENT_STATUS
    THEN
    CHECK_INVOICE_PAID_IN_FULL_PRO;
    END IF;
    END CHECK_INVOICE_PAID_IN_FULL;
    However i still get the mutating error message and when i try to create a statemtnet level trigger i get the message say cannot use :NEW and :OLD values here.
    Please help

Maybe you are looking for

  • How to retrieve data from a web service

    Hi i am at very beginner level about web services. I am searching for a simple example of retrieving data from a web services, but cant find. How can i get xml data from a web service. i dont need to develop the web service it is already ready, i jus

  • Cannot connect to EM on ODD guest from Windows host

    Hello, I cannot connect to the Enterprise Manager in my guest VM from my host. From a IE v8.0 browser, the recommended link https://192.168.56.101:1158/em fails to connect. I installed Oracle VM VirtualBox 4.0.4 on a Windows 7 laptop and imported the

  • Dreamweaver text looks fine in Safari but not Firefox NEED HELP!!!

    Dreamweaver text looks fine in Safari but not Firefox, all my text goes out of alignment and the fonts look like different sizes. Please let me know your thoughts. Here is a link to the page I'm having problems with. http://www.alexandrasantibanez.co

  • Bridge CS4 will not Launch

    Recently I tried to upgrade my Mac G4 Tower from OS 10.4 to OS 10.5 and it failed, even though I met all requirements. I had to reinstall 10.4 and now Bridge CS4 will not launch.  It worked fine before. I uninstalled PS CS4 and reinstalled it, I toss

  • Cash discount not accepted while posting in outgoing payments(F-53)

    Hi, Here i entered Invoice Rs.50,000 in FB60 through terms of 002, Againest this invoice i make a payment in F-53 on the same day so i get  Rs.1500 as discount againest this invoice. acctually entry like  as below Vendor account Dr         50,000 To