I have write a PL/SQL insert trigger but it doesn't compile properly but I don't see the problem.
create or replace TRIGGER trg_NEWROW
BEFORE INSERT or UPDATE OF STATUS_ID ON application FOR EACH ROW
BEGIN
INSERT INTO APPLICATION_HISTORY
(APPLICATION_ID, STATUS_ID, DATE_OF_CHANGE)
VALUES
(1, 1, SYSDATE)
END;
Try this: You missed a ';' at the end of Insert statement
CREATE OR REPLACE TRIGGER TRG_NEWROW
BEFORE INSERT OR UPDATE OF STATUS_ID
ON APPLICATION
FOR EACH ROW
BEGIN
INSERT INTO
APPLICATION_HISTORY ( APPLICATION_ID,
STATUS_ID,
DATE_OF_CHANGE )
VALUES
( 1,
1,
SYSDATE );
END;
/
Related
CREATE OR REPLACE TRIGGER TR_BCK_ANAG
BEFORE DELETE OR INSERT OR UPDATE ON ANAGRAFICA
FOR EACH ROW
BEGIN
SELECT ID ,
NOME ,
COGNOME ,
DATA ,
NUMERO_DI_TELEFONO ,
COMUNE
INTO BCK_ANAG
FROM ANAGRAFICA;
END;
Why does oracle give me back error
PLS-00403:expression 'BCK_ANAG' cannot be used as an INTO-target of a
SELECT/FETCH statement
and how can i solve this?
CREATE OR REPLACE TRIGGER TR_BCK_ANAG
BEFORE DELETE OR INSERT OR UPDATE
ON ANAGRAFICA
FOR EACH ROW
BEGIN
INSERT INTO BCK_ANAG (ID,
NOME,
COGNOME,
DATA,
NUMERO_DI_TELEFONO,
COMUNE)
SELECT :NEW.ID,
:NEW.NOME,
:NEW.COGNOME,
:NEW.DATA,
:NEW.NUMERO_DI_TELEFONO,
:NEW.COMUNE
FROM DUAL;
END;
I would assume this is what you're trying to do.
here's the value of ACCOUNT_NUMBER that has been generated by a sequence and inserted in ACCOUNTS table by ACCOUNT_NUMBER_TRIG trigger that i need to insert it into the TRANSACTION TABLE by the trigger ACCOUNTS_TRANSCATION_TRIG_1
CREATE OR REPLACE TRIGGER ACCOUNT_NUMBER_TRIG
BEFORE INSERT
ON ACCOUNTS
FOR EACH ROW
WHEN (NEW.ACCOUNT_NUMBER is not null)
DECLARE
V_ACC_NO ACCOUNTS.ACCOUNT_NUMBER%TYPE;
BEGIN
SELECT ACCOUNT_NO_SEQ.nextvaL INTO V_ACC_NO FROM DUAL;
:NEW.ACCOUNT_NUMBER := V_ACC_NO;
END ACCOUNT_NUMBER_TRIG;
------------------------------------------------------------------------------
CREATE OR REPLACE TRIGGER ACCOUNTS_TRANSCATION_TRIG_1 AFTER
INSERT ON ACCOUNTS FOR EACH ROW DECLARE CURSOR ACCOUNTS_CUR IS
SELECT ACCOUNT_NUMBER FROM ACCOUNTS;
DECLARE
TEMP_1 NUMBER(5,0);
BEGIN
SELECT ACCOUNTS.ACCOUNT_NUMBER FROM INSERTED INTO TEMP_1
OPEN ACCOUNTS_CUR;
INSERT
INTO TRANSACTIONS VALUES
(
SYSDATE,
- :NEW.ACCOUNT_NUMBER,
'NEW ACCOUNT',
0
);
CLOSE ACCOUNTS_CUR;
END ACCOUNTS_TRANSCATION_TRIG_1;
CREATE TABLE accounts(
ACCOUNT_NUMBER number,
ACCOUNT_NAME varchar2(20)
);
CREATE SEQUENCE ACCOUNT_NO_SEQ;
CREATE OR REPLACE TRIGGER ACCOUNT_NUMBER_TRIG
BEFORE INSERT
ON ACCOUNTS
FOR EACH ROW
WHEN (NEW.ACCOUNT_NUMBER is not null)
BEGIN
:NEW.ACCOUNT_NUMBER :=ACCOUNT_NO_SEQ.nextvaL;
END ACCOUNT_NUMBER_TRIG;
/
CREATE TABLE transactions(
TR_DATE date,
TR_ACCOUNT_NUMBER number,
TR_TYPE varchar2(20),
TR_somenumber int
);
CREATE OR REPLACE TRIGGER ACCOUNTS_TRANSCATION_TRIG_1 AFTER
INSERT ON ACCOUNTS FOR EACH ROW
BEGIN
INSERT INTO TRANSACTIONS( TR_DATE, TR_ACCOUNT_NUMBER, TR_TYPE, TR_somenumber )
VALUES
(
SYSDATE,
:NEW.ACCOUNT_NUMBER,
'NEW ACCOUNT',
0
);
END ACCOUNTS_TRANSCATION_TRIG_1;
/
INSERT INTO accounts( ACCOUNT_NUMBER, ACCOUNT_NAME ) VALUES (1111,'My Name' );
select * from accounts;
ACCOUNT_NUMBER ACCOUNT_NAME
-------------- --------------------
2 My Name
select * from transactions;
TR_DATE TR_ACCOUNT_NUMBER TR_TYPE TR_SOMENUMBER
---------- ----------------- -------------------- -------------
2017/07/11 2 NEW ACCOUNT 0
You can use CURVAL to get the most recent value returned by NEXTVAL:
CREATE OR REPLACE TRIGGER ACCOUNTS_TRANSCATION_TRIG_1 AFTER
INSERT ON ACCOUNTS FOR EACH ROW DECLARE CURSOR ACCOUNTS_CUR IS
BEGIN
INSERT
INTO TRANSACTIONS VALUES
(
SYSDATE,
- ACCOUNT_NO_SEQ.curval,
'NEW ACCOUNT',
0
);
CLOSE ACCOUNTS_CUR;
END ACCOUNTS_TRANSCATION_TRIG_1;
However in this case there is no need, as it has been used to set the ACOUNT_NUMBER:
INSERT
INTO TRANSACTIONS VALUES
(
SYSDATE,
- :NEW.ACCOUNT_NUMBER,
'NEW ACCOUNT',
0
);
BTW unless you are on an old version of Oracle this should work for first trigger:
CREATE OR REPLACE TRIGGER ACCOUNT_NUMBER_TRIG
BEFORE INSERT
ON ACCOUNTS
FOR EACH ROW
WHEN (NEW.ACCOUNT_NUMBER is not null)
BEGIN
:NEW.ACCOUNT_NUMBER := ACCOUNT_NO_SEQ.nextvaL;
END ACCOUNT_NUMBER_TRIG;
(I suspect the WHEN clause is wrong - should be when is null?)
I am trying to find the Date and time when QTY for Item A and Loc UK gets updated.
Can I have where clause in trigger??
CREATE TABLE tr_test (
item VARCHAR2 (10),
loc VARCHAR2 (10),
WHEN DATE,
qty );
insert into TR_TEST values ('A','UK',to_date('01/01/2013','MM/DD/YYYY',100);
insert into TR_TEST values ('B','US',to_date('01/01/2013','MM/DD/YYYY',200);
CREATE OR REPLACE TRIGGER "TEST_TRIGGER"
BEFORE UPDATE
ON tr_test
FOR EACH ROW
BEGIN
IF UPDATING ('QTY')
THEN
INSERT INTO tr_test_1
(item, loc, WHEN, qty)
SELECT :OLD.item, :OLD.loc, SYSDATE, :OLD.qty
FROM DUAL;
INSERT INTO tr_test_1
(item`enter code here`, loc, WHEN, oh)
SELECT :OLD.item, :OLD.loc, SYSDATE, :NEW.qty
FROM DUAL;
END IF;
END;
/
I have the following stored procedure which we use to insert data into a table:
CREATE OR REPLACE PROCEDURE mySproc
(
invoiceId IN NUMBER
customerId IN NUMBER
)
IS
BEGIN
INSERT INTO myTable (INVOICE_ID)
VALUES (invoiceId);
END mySproc;
/
What I am trying to do is to get the last inserted ID (this is the primary key field on myTable and auto incremented using a sequence) and insert it into another table, I have tried the following but could not get it working:
CREATE OR REPLACE PROCEDURE mySproc
(
invoiceId IN NUMBER
customerId IN NUMBER
)
IS
BEGIN
INSERT INTO myTable (INVOICE_ID)
VALUES (invoiceId)
returning id into v_id;
INSERT INTO anotherTable (ID, customerID)
VALUES (v_id, customerId);
END mySproc;
/
I am getting this error: [Error] PLS-00049 (59: 26): PLS-00049: bad bind variable 'V_ID' I think I need to declare v_id somewhere but I tried before and after the BEGIN statement but that gave another error.
Any ideas as to how to do this?
Thanks
Change your procedure to
CREATE OR REPLACE PROCEDURE mySproc
(
invoiceId IN NUMBER, -- Added comma
customerId IN NUMBER
)
IS
v_id NUMBER; -- ADDED
BEGIN
INSERT INTO myTable (INVOICE_ID)
VALUES (invoiceId)
returning id into v_id;
INSERT INTO anotherTable (ID, customerID)
VALUES (v_id, customerId);
END mySproc;
Share and enjoy.
How can I work around the Oracle's limitation of not allowing subqueries in triggers.
Here's an example trigger I'm trying to create, but am unable to because I can't use a subquery.
CREATE OR REPLACE TRIGGER trigger_w_subquery
AFTER UPDATE OR INSERT ON project_archiving
FOR EACH ROW WHEN (old.archiving_status <> new.archiving_status
AND new.archiving_status = 1
AND (SELECT offer FROM projects WHERE projnum = :new.projnum) IS NULL
)
BEGIN
INSERT INTO offer_log (offer, status, date)
VALUES (null, 9, sysdate);
END;
This trigger would do it:
CREATE OR REPLACE TRIGGER trigger_w_subquery
AFTER UPDATE OR INSERT ON project_archiving
FOR EACH ROW WHEN (old.archiving_status <> new.archiving_status
AND new.archiving_status = 1
)
DECLARE
l_offer projects.offer%TYPE;
BEGIN
SELECT offer INTO l_offer
FROM projects
WHERE projnum = :new.projnum;
IF l_offer IS NULL THEN
INSERT INTO offer_log (offer, status, date)
VALUES (null, 9, sysdate);
END IF;
END;
I have assumed that the select from projects will always find a row; if not it will raise a NO_DATA_FOUND exception that you may need to handle.
I expect that you want something like
CREATE OR REPLACE TRIGGER trigger_w_subquery
AFTER UPDATE OR INSERT ON project_archiving
FOR EACH ROW
WHEN (old.archiving_status <> new.archiving_status
AND new.archiving_status = 1)
DECLARE
l_offer projects.offer%TYPE;
BEGIN
SELECT offer
INTO l_offer
FROM projects
WHERE projnum = :new.projnum;
IF( l_offer IS NULL )
THEN
INSERT INTO offer_log (offer, status, date)
VALUES (null, 9, sysdate);
END IF;
END;
Can you put the condition into the action (between BEGIN and END) instead of in the 'whether it fires'? Yes, it means that the trigger body might be fired more often - but if it gets you around the problem...