Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 3 months ago.
Improve this question
hello guys can you help me here
CREATE TRIGGER operation
AFTER UPDATE ON COMPTE
for each row
BEGIN
IF :old.solde > :new.solde THEN
INSERT INTO HISTORY VALUES(NUMEROCOMPTE,DATESOLDE,'Retrait');
end if;
IF :old.solde < :new.solde THEN
INSERT INTO HISTORY VALUES(NUMEROCOMPTE,DATESOLDE,'Versement');
end if;
end;
/
this is what i get
3/1 PL/SQL: SQL Statement ignored
3/41 PL/SQL: ORA-00984: Column Not Allowed
6/1 PL/SQL: SQL Statement ignored
6/41 PL/SQL: ORA-00984: Column Not Allowed
Errors : check compiler log
i'm new so i dont know what to do
Do as Ken commented.
Problem is with insert statements (both of them) and values you're trying to insert into the history table. You can't insert column names as such - you have to precede their names with :new or :old pseudorecord identifier, just as you did in if.
I don't know which values (old or new) you want to store into the history table so it is just my guess, but you should know it and you'll therefore be able to fix
it.
Sample tables:
SQL> create table compte (solde number, numerocompte number, datesolde date);
Table created.
SQL> create table history (muberocompte number, datesolde date, description varchar2(20));
Table created.
Trigger:
SQL> CREATE TRIGGER operation
2 AFTER UPDATE ON COMPTE
3 for each row
4 BEGIN
5 IF :old.solde > :new.solde THEN
6 INSERT INTO HISTORY VALUES(:old.NUMEROCOMPTE, :old.DATESOLDE, 'Retrait');
7 ELSIF :old.solde < :new.solde THEN
8 INSERT INTO HISTORY VALUES(:new.NUMEROCOMPTE, :new.DATESOLDE, 'Versement');
9 END IF;
10 end;
11 /
Trigger created.
SQL>
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
fix this error pls
CREATE OR REPLACE TRIGGER BELITIKET
AFTER INSERT ON PENUMPANG FOR EACH ROW
BEGIN
INSERT INTO TIKET(NIK,NAMA_PENUMPANG, NAMA_KERETA,RUTE,HARGA)
SELECT p.NIK, p.NAMA, k.NAMA_KERETA, p.RUTE, k.HARGA
FROM PENUMPANG p, KERETA_API k
WHERE p.RUTE = k.RUTE and p.WAKTU = k.WAKTU_KEBERANGKATAN;
END;
this is the error
SQL Error: ORA-04098: trigger 'SCOTT.TRIGGER1' is invalid and failed re-validation
04098. 00000 - "trigger '%s.%s' is invalid and failed re-validation"
*Cause: A trigger was attempted to be retrieved for execution and was
found to be invalid. This also means that compilation/authorization
failed for the trigger.
*Action: Options are to resolve the compilation/authorization errors,
disable the trigger, or drop the trigger.
Mutating table error, I presume (it would be easier if you stated it yourself). You can't select from the same table that is just being updated. Use :new pseudorecord instead:
CREATE OR REPLACE TRIGGER belitiket
AFTER INSERT
ON penumpang
FOR EACH ROW
BEGIN
INSERT INTO tiket (nik,
nama_penumpang,
nama_kereta,
rute,
harga)
SELECT :new.nik,
:new.nama,
k.nama_kereta,
:new.rute,
k.harga
FROM kereta_api k
WHERE :new.rute = k.rute
AND :new.waktu = k.waktu_keberangkatan;
END;
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 3 years ago.
Improve this question
I create a trigger
create or replace TRIGGER trj2
BEFORE INSERT OR UPDATE OF
customer_ID ON Reserve
FOR EACH ROW
DECLARE
new_fk1_NR VARCHAR2(7);
BEGIN
SELECT NR
INTO new_fk1_NR
FROM customers
WHERE :NEW.customer_ID= customers.ID;
:NEW.NR_K := new_fk1_NR;
END;
It is working fine for update statements, but for insert it give this error
ORA-01403: no data found ORA-06512: at "SYSTEM.WRITERESPROT", line 76
ORA-06512: at "SYSTEM.LRES_PROTOKOLL", line 38
ORA-04088: error during execution of trigger 'SYSTEM.LRES_PROTOKOLL'
I couldn't find links or explanations about what does this mean,
any help please?
The problem is when no rows are returned. A simple way to ensure that exactly one row is returned is to use aggregation:
SELECT MAX(NR)
INTO new_fk1_NR
FROM customers
WHERE :NEW.customer_ID = customers.ID;
An aggregation query with no GROUP BY returns exactly one row, even when no rows match. If no rows match, the result is NULL.
This error is raised becaue your SELECT ... INTO ... query returned no record. You would need to either ensure that the query always returns one record, or to handle that exception.
Something like this will handle exceptions:
create or replace trigger trj2
before insert or update of customer_id on reserve
for each row
declare
new_fk1_nr varchar2(7);
begin
select nr into new_fk1_nr from customers where :new.customer_id= customers.id;
:new.nr_k := new_fk1_nr;
exception
when NO_DATA_FOUND
then raise_application_error(
-20010,
'this could not happen since customer does not exist'
);
when others
then raise_application_error(-20011,'Unknown Exception');
end;
/
This question already has answers here:
Table is mutating, trigger/function may not see it (stopping an average grade from dropping below 2.5)
(6 answers)
Closed 5 years ago.
I just started learning Trigger. And I want to make a trigger which after insert on test gives user a notice 'insert successfully'.
Here is my code.
create table test (id number, name varchar2(30));
create trigger tr_test
after insert on test
for each row
begin
dbms_output.put_line('insert successfully');
end;
/
insert into test values(1, 'john');
And I get the error like this:
ERROR at line 1:
ORA-04091: table YUFENG.TEST is mutating, trigger/function may not see it
ORA-06512: at "YUFENG.TR_TEST", line 3
ORA-04088: error during execution of trigger 'YUFENG.TR_TEST'
Could anyone point out the error and tell me how to modify the code?
Sorry that I didn't notice that there are lots of simple mistakes which makes the query not able to run. And my original code declares variable in the trigger, but I didn't post it. I think probably that is the reason why I get the error mutating.
CREATE or REPLACE TRIGGER TR_TEST
AFTER INSERT ON TEST
FOR EACH ROW
DECLARE a VARCHAR2(30);
BEGIN
SELECT ID INTO a FROM TEST WHERE ID=:NEW.ID;
DBMS_OUTPUT.PUT_LINE('insert successfully');
END;
/
the output will only be displayed, if you turn it on (SQLPlus, SQLDeveloper):
set serveroutput on
Your code is incomplete. There is a missing ")" on the CREATE TABLE.
The putline is misspelled. It should be PUT_LINE.
It is an extremely bad idea to use DBMS_OUTPUT in a Trigger. A user may be using a client that cannot or does not handle DBMS_OUTPUT (unlike sqlplus)
Replace after with before as below, also the table needs ')' missing.
create table test (id number, name varchar2(30));
create or replace trigger tr_test
before insert on test
for each row
begin
dbms_output.put_line('insert successfully');
end;
/
also its good idea you specific columns in the insert
insert into test (id,name) values(1, 'john')
/
commit
/
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 7 years ago.
Improve this question
I am trying to execute the following insert query within a stored procedure to further call in a `java' class -
SQL> create or replace procedure admininsert(ID IN varchar2, UEMAIL IN varchar2, PASSWORD IN varchar2, FLAG IN number)
as
begin
insert into user values(ID, UEMAIL, PASSWORD, FLAG);
end;
/
Procedure created.
However, the issue I have is that, when I try to run the same by using the following -
exec admininsert("ABC","DEF","GHIJKLM",2);
I get the following error -
ERROR at line 1:
ORA-06550: line 1, column 20:
PLS-00201: identifier 'ABC' must be declared
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
Am I executing the procedure in a right way? If not so, then how should I go along with the same?
For string literals, you want single quotes ' around your values.
exec admininsert('ABC','DEF','GHIJKLM',2);
Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 10 years ago.
Improve this question
I have finished my first real PL/SQL stored proc, this stored proc works as expected. I am new to PL/SQL, could you please point anything wrong or bad coding ?
This code is assuming a naming convention, for example, 't_company' table will use 'companyId' as its primary key and its type is number.
Thank you very much.
create or replace
package body test_erp AS
procedure init_data is
begin
logMessage('procedure init_data');
SAVEPOINT do_insert;
insert into t_company(companyId, companyName) values(gen_key('t_company'), 'IBM');
COMMIT;
exception
WHEN OTHERS THEN
rollback to do_insert;
logMessage('roll back , due to '|| SQLERRM);
end init_data;
end test_erp;
It will call this function
create or replace
function gen_key(tblName varchar2)
return number is
l_key number := 1000;
l_tmpStr varchar(2000); -- not good, how to fix it ?
begin
l_tmpStr := substr(tblName, 3, length(tblName));
EXECUTE IMMEDIATE ' SELECT CASE WHEN MAX('||l_tmpStr||'Id) IS NULL THEN 1000 ELSE MAX('||l_tmpStr||'Id)+1 END FROM '|| tblName into l_key;
logmessage('gen primary key '|| tblName ||' '||l_key);
return l_key;
end;
Your key_gen procedure is rather problematic. Generating keys by doing a MAX(key)+1 is slow and will not work in a multiuser environment. Assuming you have two users, it is relatively easy for both users to see the same MAX(key) and try to insert rows with the same primary key.
Oracle provides sequences in order to efficiently generate primary keys in a multi-user environment. You would be much better served using sequences to generate your keys. Conventionally, you would create one sequence per table, i.e.
CREATE SEQUENCE company_seq;
Your INSERT statement would then be something like
insert into t_company(companyId, companyName) values(company_seq.nextval, 'IBM');
Or you could create a trigger on the table to automatically populate the primary key.
Additionally, while it is fine to catch exceptions in order to log them, you really want to re-raise that exception so that the caller is aware that the INSERT failed.
Using function in your case gen_key is very slow and it's incorrect database-written and also very inefficiently.
So my advice is to create SEQUENCE that is generally used for this.Then you should create TRIGGER for generating new PK for each INSERT or directly add it with NEXTVAL.
So, your SEQUENCE can looks like this:
CREATE SEQUENCE YOUR_COMP_SEQ
MINVALUE 1
MAXVALUE 999999
START WITH 1
INCREMENT BY 1
NOCACHE
;
Then i recommend to you use meant TRIGGER:
CREATE OR REPLACE TRIGGER AUTOSET_ID_COMP
BEFORE INSERT ON t_company
FOR EACH ROW
BEGIN
SELECT YOUR_COMP_SEQ.NEXTVAL INTO :NEW.companyId FROM DUAL;
END;
And finally just call query:
INSERT INTO t_company(companyName) VALUES('SomeValue');
If you don't want to create TRIGGER so you can do it directly like this:
INSERT INTO t_company(companyId, companyName)
VALUES(YOUR_COMP_SEQ.NEXTVAL, 'SomeValue');
Note: Of course, you can create for every TABLE its own SEQUENCE and then use TRIGGERS for each TABLE.
Note 2: Sequences are very good but there is some problem that for example you added to table 20 rows, so IDs are 1,2,3, ... etc. and for example you will delete 15. row and since this ID 15 you can't use, anymore.
Update:
Answer and Solution is updated after a little discussion with #Ben, thanks.