Modify column value Oracle - oracle
Hello I have made a Trigger it compiles
CREATE OR REPLACE TRIGGER livraisonfinie
BEFORE UPDATE ON Expedition
FOR EACH ROW
DECLARE
BEGIN
IF :NEW.date_livraison <> TO_DATE('3000/01/01 00:00:00', 'yyyy/mm/dd hh24:mi:ss')
THEN
INSERT INTO Commande (etat) VALUES ('livree');
DELETE FROM cmdalivrer CMD WHERE :NEW.numero_commande=CMD.id_cmd WHERE :NEW.numero_commande= Commande.numero_commande;;
END IF ;
END;
/
When I try to update a value of expedition table I get this error
ORA-01400: cannot insert NULL into ("HAMZA"."COMMANDE"."NUMERO_COMMANDE")
ORA-06512: at "HAMZA.LIVRAISONFINIE", line 10
ORA-04088: error during execution of trigger 'HAMZA.LIVRAISONFINIE'
And I have used this update request but not sure if I have to use INSERT INTO or UPDATE and how corretly even after reading many manuals.
Here's the table
Expedition(Id_Expedition ,#id_chauffeur,#Immatriculation, #Id_Itineraire,Date_Deb_Expedition , Date_Livraison)
Commande (numero_commande,Date_commande,adresse_livraison,id_part,ville_livraison,code_postal_livraison,etat,id_expedition)
EDIT: I solved it by adding "where :NEW.numero_commande= Commande.numero_commande;" to my trigger.
Thanks
There is NOT NULL constraint on column NUMERO_COMMANDE in table COMMANDE.
More on this constraint you can find here:
http://www.w3schools.com/sql/sql_notnull.asp
By default, a table column can hold NULL values.
SQL NOT NULL Constraint
The NOT NULL constraint enforces a column to
NOT accept NULL values.
The NOT NULL constraint enforces a field to always contain a value.
This means that you cannot insert a new record, or update a record
without adding a value to this field.
Either provide a value for this field in your trigger:
INSERT INTO Commande (etat,NUMERO_COMMANDE)
VALUES ('livree', some-value-for-numero-commande-column);
or remove NOT NULL constraint on this column from the table.
Related
Why do I keep getting this error when creating a trigger?
I am creating a trigger that checks if the Majorcode column is null BEFORE INSERT OR UPDATE and if it is it enters the default value "100" My code: CREATE TRIGGER MUmajorcode_changes BEFORE INSERT OR UPDATE ON M_Students FOR EACH ROW BEGIN IF NEW.Majorcode = null THEN SET NEW.Majorcode = '100'; END IF; I get the following message after running it Warning: Trigger created with compilation errors. Then when I actually insert a new value with blank major code. I receive the following message/error: ERROR at line 1: ORA-04098: trigger 'SCOTT.MUMAJORCODE_CHANGES' is invalid and failed re-validation. This is how I setup the table initially: CREATE TABLE M_Students ( ID CHAR(3) PRIMARY KEY, FName VARCHAR2(25), LName VARCHAR2(25), Status VARCHAR2(25), Majorcode CHAR(3) REFERENCES Departments(DeptCode), GPA NUMBER (4,2), AdmittedDate DATE ); Cannot figure out where I am going wrong?
When you get the message "created with compilation errors" it means your script is invalid, it has compile time errors. If your IDE does not show them you to you then if you are using sqlplus then run "show errors" if you are using an IDE run the query "select * from user_errors" (and get a new IDE). Either will show the errors in the script, they must be corrected; your script will not run until they are. The suggestions of setting a DEFAULT value in the table definition has merit but will fail on a couple conditions. When Inserting the default will be taken when the column name is not mentioned in column list. (Note Omitting the column list is implicitly mentioning all columns so the default would not be set.) Nor would it handle update condition. Your trigger itself can be reduced to a single statement with the coalesce function: create or replace trigger mumajorcode_changes before insert or update of mumajorcode on m_students for each row begin :new.majorcode := coalesce(:new.majorcode, '100'); end;
You have some syntax errors: CREATE OR REPLACE TRIGGER MUmajorcode_changes /* better use REPLACE to avoid dropping the trigger */ BEFORE INSERT OR UPDATE ON M_Students FOR EACH ROW BEGIN IF :new.Majorcode IS NULL /* :new, with the colon (:) */ THEN :new.Majorcode := '100'; /* :new, and no SET */ END IF; END; /* a missing END */ Also, never check null values with =, but always use is [not] null.
There are some obvious syntax errors such as wrong assignment, missing or superfluous keywords, but you don't need to create a database trigger to handle this operation. Just modify the related columns property by ALTER TABLE M_Students MODIFY Majorcode DEFAULT '100' NOT NULL Through this property, Majorcode column is already populated by the value '100' during the insertion automatically, and updating that column to NULL won't be possible because of the NOT NULL constraint. Demo
Trigger before delete
I created a before delete trigger: create or replace trigger myTrigger3 before delete on emp for each row begin update emp set mgr = 'Null' where mgr = :old.emp_name; end; Where table is emp(emp_id integer primary key, emp_name varchar(20), mgr varchar(20)) But when I run this statement the trigger is not running. delete from emp where emp_id = 1004; select * from emp; Error report - ORA-04091: table DB20178004.EMP is mutating, trigger/function may not see it ORA-06512: at "DB20178004.MYTRIGGER3", line 2 ORA-04088: error during execution of trigger 'DB20178004.MYTRIGGER3'
You can prefer adding a foreign key constraint with set null option instead of such a trigger. Of course you need a primary key should already been defined on emp_id column : alter table emp add constraint fk_mgr foreign key(mgr) references emp(emp_id) on delete set null; Whenever you delete the record with an emp_id which has matching values with mgr column those will be emptied after deletion of the record with that emp_id. But please prefer a data type(numeric) for mgr conforming with the column emp_id such as integer to be able to define a foreign key constraint. Demo By the way, I recommend you to use soft-deletion. e.g. adding a column active to the table and set value of it to zero whenever want to delete, and do not show the records with active=0 on the application. If you insisting on deletion do not filter by emp_name column, since there can be more than one people with the common name, but using emp_id is better by far as being unique within the table.
Trigger to raise raise an application error with a meaningful message if og_id refers to a cancelled Olympic Game
These are the following tables I have created: CREATE TABLE Country ( country_id NUMBER(3) PRIMARY KEY, country_name VARCHAR(3) UNIQUE NOT NULL, CONSTRAINT check_country_id CHECK (country_id > 0) ); CREATE TABLE OG_Type ( og_type_id NUMBER(3) PRIMARY KEY, og_type_title VARCHAR(20) UNIQUE NOT NULL ); CREATE TABLE Olympic_Game ( og_id NUMBER(3) PRIMARY KEY, og_type_id NUMBER(3) NOT NULL, og_year NUMBER(4) NOT NULL, og_website VARCHAR(150), og_cancel VARCHAR(1) NOT NULL, country_id NUMBER(3) NOT NULL, CONSTRAINT check_og_id CHECK (og_id > 0), CONSTRAINT check_og_year_og_type UNIQUE (og_type_id, og_year), CONSTRAINT fk_og_type_id FOREIGN KEY(og_type_id) REFERENCES OG_Type(og_type_id), CONSTRAINT fk_country_id FOREIGN KEY(country_id) REFERENCES Country(country_id) ); CREATE TABLE Sport ( sport_id NUMBER(3) PRIMARY KEY, sport_title VARCHAR(100) UNIQUE NOT NULL, CONSTRAINT check_sport_id CHECK (sport_id > 0) ); CREATE TABLE Event ( event_id NUMBER(6) PRIMARY KEY, sport_id NUMBER(3) NOT NULL, og_id NUMBER(3) NOT NULL, event_title VARCHAR(100) NOT NULL, event_team VARCHAR(1) NOT NULL, no_per_team NUMBER(2) NOT NULL, event_gender VARCHAR(1) NOT NULL, CONSTRAINT check_event_id CHECK (event_id > 0), CONSTRAINT check_event_title_sport_id_og_id_event_team_event_gender UNIQUE (event_title, sport_id, og_id, event_team, event_gender), CONSTRAINT check_event_team CHECK (event_team IN ('Y','N')), CONSTRAINT check_event_team_no_per_team CHECK ((event_team='N' AND no_per_team=1) OR (event_team='Y' AND no_per_team>1)), CONSTRAINT check_event_gender CHECK (event_gender IN ('M','F')), CONSTRAINT fk_sport_id FOREIGN KEY(sport_id) REFERENCES Sport(sport_id), CONSTRAINT fk_og_id FOREIGN KEY(og_id) REFERENCES Olympic_Game(og_id) ); After creating these 4 tables, I have inserted the values for these 4 tables: insert into country(country_id,country_name) values (country_seq.nextval,'FRA'); insert into country(country_id,country_name) values (country_seq.nextval,'GBR'); insert into country(country_id,country_name) values (country_seq.nextval,'GRE'); insert into country(country_id,country_name) values (country_seq.nextval,'USA'); insert into og_type(og_type_id, og_type_title) values(og_type_seq.nextval,'Summer'); insert into og_type(og_type_id, og_type_title) values(og_type_seq.nextval,'Winter'); insert into og_type(og_type_id, og_type_title) values(og_type_seq.nextval,'Special'); insert into og_type(og_type_id, og_type_title) values(og_type_seq.nextval,'Youth'); insert into og_type(og_type_id, og_type_title) values(og_type_seq.nextval,'Senior'); insert into olympic_game(og_id,og_type_id,og_year,og_website,og_cancel,country_id) values(og_seq.nextval,1,1896,null,'N',3); insert into olympic_game(og_id,og_type_id,og_year,og_website,og_cancel,country_id) values(og_seq.nextval,1,1900,null,'N',1); insert into olympic_game(og_id,og_type_id,og_year,og_website,og_cancel,country_id) values(og_seq.nextval,1,1904,null,'N',4); insert into olympic_game(og_id,og_type_id,og_year,og_website,og_cancel,country_id) values(og_seq.nextval,1,1908,'op1908.org','N',2); insert into olympic_game(og_id,og_type_id,og_year,og_website,og_cancel,country_id) values(og_seq.nextval,2,1924,null,'N',1); insert into olympic_game(og_id,og_type_id,og_year,og_website,og_cancel,country_id) values(og_seq.nextval,1,1944,null,'Y',2); insert into olympic_game(og_id,og_type_id,og_year,og_website,og_cancel,country_id) values(og_seq.nextval,3,1944,null,'Y',2); insert into olympic_game(og_id,og_type_id,og_year,og_website,og_cancel,country_id) values(og_seq.nextval,4,1944,null,'Y',2); insert into olympic_game(og_id,og_type_id,og_year,og_website,og_cancel,country_id) values(og_seq.nextval,5,1944,null,'Y',2); insert into olympic_game(og_id,og_type_id,og_year,og_website,og_cancel,country_id) values(og_seq.nextval,1,2012,'https://www.olympic.org/london-2012','N',2); insert into sport(sport_id,sport_title) values(sport_seq.nextval, 'Track and Field'); insert into sport(sport_id,sport_title) values(sport_seq.nextval, 'Tennis'); insert into sport(sport_id,sport_title) values(sport_seq.nextval, 'Speed Skating'); insert into event(event_id,sport_id,og_id,event_title,event_team,no_per_team,event_gender) values(event_seq.nextval,1,1,'100m','N',1,'M'); insert into event(event_id,sport_id,og_id,event_title,event_team,no_per_team,event_gender) values(event_seq.nextval,2,1,'Double','Y',2,'M'); insert into event(event_id,sport_id,og_id,event_title,event_team,no_per_team,event_gender) values(event_seq.nextval,1,2,'200m','N',1,'M'); insert into event(event_id,sport_id,og_id,event_title,event_team,no_per_team,event_gender) values(event_seq.nextval,2,2,'Single','N',1,'M'); insert into event(event_id,sport_id,og_id,event_title,event_team,no_per_team,event_gender) values(event_seq.nextval,1,3,'400m','N',1,'F'); insert into event(event_id,sport_id,og_id,event_title,event_team,no_per_team,event_gender) values(event_seq.nextval,1,3,'100m','N',1,'F'); insert into event(event_id,sport_id,og_id,event_title,event_team,no_per_team,event_gender) values(event_seq.nextval,1,4,'1500m','N',1,'F'); insert into event(event_id,sport_id,og_id,event_title,event_team,no_per_team,event_gender) values(event_seq.nextval,3,5,'800m','N',1,'F'); insert into event(event_id,sport_id,og_id,event_title,event_team,no_per_team,event_gender) values(event_seq.nextval,1,10,'100m','N',1,'M'); insert into event(event_id,sport_id,og_id,event_title,event_team,no_per_team,event_gender) values(event_seq.nextval,1,10,'100m','N',1,'F'); Now this is the question: Create a trigger called TR_event_on_cancelled_og. This trigger fires before inserting or updating a row in the Event table. The trigger should raise an application error with a meaningful message if og_id refers to a cancelled Olympic Game. Now this is the solution I came up with: CREATE OR REPLACE TRIGGER TR_event_on_cancelled BEFORE INSERT OR UPDATE ON Event FOR EACH ROW BEGIN DECLARE v_og_cancel Olympic_Game.og_cancel%TYPE; BEGIN SELECT og_cancel INTO V_og_cancel FROM Olympic_Game, Event WHERE Olympic_Game.og_id = Event.og_id AND Olympic_Game.og_id = :NEW.og_id; IF (v_og_cancel = 'N') THEN RAISE_APPLICATION_ERROR(-20001, 'This Olympic Game is cancelled already'); END IF; END; END; Trigger TR_EVENT_ON_CANCELLED compiled The trigger is compiled successfully but the problem is when I was trying to test the trigger I got the following error messages: insert into event(event_id,sport_id,og_id,event_title,event_team,no_per_team,event_gender) values(event_seq.nextval,1,8,'400m','N',1,'F'); Error report - SQL Error: ORA-01403: no data found ORA-06512: at "OG_JC480454.TR_EVENT_ON_CANCELLED", line 5 ORA-04088: error during execution of trigger 'OG_JC480454.TR_EVENT_ON_CANCELLED' 01403. 00000 - "no data found" *Cause: No data was found from the objects. *Action: There was no data from the objects which may be due to end of fetch. insert into event(event_id,sport_id,og_id,event_title,event_team,no_per_team,event_gender) values(event_seq.nextval,1,2,'400m','N',1,'F'); Error report - SQL Error: ORA-01422: exact fetch returns more than requested number of rows ORA-06512: at "OG_JC480454.TR_EVENT_ON_CANCELLED", line 5 ORA-04088: error during execution of trigger 'OG_JC480454.TR_EVENT_ON_CANCELLED' 01422. 00000 - "exact fetch returns more than requested number of rows" *Cause: The number specified in exact fetch is less than the rows returned. *Action: Rewrite the query or change number of rows requested Where did I exactly go wrong ? ... It would be really helpful if the trigger solution code is provided.
I think your problem is that your trigger code is selecting from EVENT. It doesn't need to do this because the rule applies only to the current event you're inserting or updating. So: SELECT og_cancel INTO V_og_cancel FROM Olympic_Game WHERE Olympic_Game.og_id = :NEW.og_id; Incidentally, the next test looks wrong: IF (v_og_cancel = 'N') Unless you're using Y/N flags in an odd manner this would be testing if the Games have not been cancelled. Surely that should be = 'Y'? " I want to get this error message" I have created an Oracle LiveSQL with your data and my version of the trigger. Find it here (but you will need an OTN account to look at it). When I attempt this INSERT ... insert into event(event_id,sport_id,og_id,event_title,event_team,no_per_team,event_gender) values(event_seq.nextval,2,9,'Double','Y',2,'M'); it fails on ORA-20001: This Olympic Game is cancelled already Quite rightly, because the games where og_id = 9 has og_cancel='Y'. Now you say you're getting ORA-20977: the game was cancelled. That's a user-defined error (in the range -20999 to -20000. So it's some part of your codebase which is hurling it. If you don't know what part it is you will need to dig into your data dictionary. I can't solve that for you. But here's a thought: have you got more than one trigger on the table? Your homework says to create a trigger called TR_event_on_cancelled_og but the code you published does CREATE OR REPLACE TRIGGER TR_event_on_cancelled. Perhaps you previously created a trigger with the other name, and that's what is raising the ORA-20977.
date Not null , error ora_01758
why I am getting this error ? In the table DDL I only have 2 columns , id (number) and name (varchar) ALTER TABLE mytable ADD SUSPEND date NOT NULL ORA-01758: table must be empty to add mandatory (NOT NULL) column ORA-06512: at line 7
ORA-01758: table must be empty to add mandatory (NOT NULL) column ORA-06512: at line 7 And is your table empty? I think not. There's probably a way around this involving adding the column as nullable, then populating every row with a non-NULL value, the altering the column to be not null. Alternatively, since the problem is that these current rows will be given NULL as a default value, and the column is not allowed to be NULL, you can also get around it with a default value. From the Oracle docs: However, a column with a NOT NULL constraint can be added to an existing table if you give a default value; otherwise, an exception is thrown when the ALTER TABLE statement is executed. Here is a fiddle, how you could do it
Would a date in the future be acceptable as a temporary default? If so, this would work: ALTER TABLE MYTABLE ADD (SUSPEND_DATE DATE DEFAULT(TO_DATE('21000101', 'YYYYMMDD')) CONSTRAINT SUSPEND_DATE_NOT_NULL NOT NULL);
If table already contain the records then table won't allowes to add "Not null" column. If you need same then set default value for the column or truncate the table then try.
What do references to OLD evaluate to in the WHEN cause of an Oracle insert trigger?
When writing a row-level trigger in Oracle, I know that you can use the OLD and NEW pseudo-records to reference the old and new state of the row that fired the trigger. I know that in an INSERT trigger OLD doesn't contain any data, but I'm not sure how this affects the evaluation of a WHEN clause for that trigger. For example, if I have the following trigger: CREATE OR REPLACE TRIGGER mung_row BEFORE INSERT OR UPDATE ON some_table FOR EACH ROW BEGIN :NEW.foo = 'some val'; END; and I want to modify this trigger to only run on an update when foo was previously null, but always run on an insert, I could satisfy the update part of the change by adding a WHERE clause: CREATE OR REPLACE TRIGGER mung_row BEFORE INSERT OR UPDATE ON some_table FOR EACH ROW WHEN (OLD.foo IS NULL) BEGIN :NEW.foo = 'some val'; END; Will this cause problems in the insert case? What will OLD.foo evaluate to in the INSERT? I'm aware that I could split the INSERT and UPDATE triggers or use INSERTING/UPDATING/DELETING in the trigger body, but I'd rather not in the case that inspired this question.
When a record is being inserted, every field of OLD will be NULL, including the fields marked as NOT NULL in the table's definition. For example, suppose your table has a non-nullable column named id: CREATE TABLE some_table ( id NUMBER NOT NULL, foo VARCHAR2(100) ) When a record is inserted into this table, OLD.id will be NULL. However, when a record is updated in this table, OLD.id will not be NULL. Because you only want to change :NEW.foo if a record is being updated, you just have to check to see if OLD.id has a non-null value. CREATE OR REPLACE TRIGGER mung_row BEFORE INSERT OR UPDATE ON some_table FOR EACH ROW WHEN (OLD.id IS NOT NULL AND OLD.foo IS NULL) BEGIN :NEW.foo = 'some val'; END;