I have two tables, item and item_price_history. I want to create a trigger that inserts records of the old prices after an item's price is changed in the price table. Here are the two tables:
CREATE TABLE item(
item_id DECIMAL(10) NOT NULL,
description VARCHAR(30),
price DECIMAL(10),
PRIMARY KEY (item_id));
CREATE TABLE item_price_history(
item_id DECIMAL(10) NOT NULL,
old_price DECIMAL(10) NOT NULL,
new_price DECIMAL(10) NOT NULL,
date_of_change DATE NOT NULL,
FOREIGN KEY (item_id) references ITEM);
I have tried numerous ways just to get it to compile but this is what I have as the trigger:
CREATE OR REPLACE TRIGGER price_hist
AFTER UPDATE ON item
FOR EACH ROW
WHEN (new.price <> old.price)
BEGIN
INSERT INTO item_price_history(item_id, old_price, new_price, date_of_change)
VALUES (:NEW.item_id, :OLD.price, :NEW.price, SYSDATE);
END;
I receive the following error after updating the price on item:
Error starting at line : 1 in command -
UPDATE item
SET price = 11
WHERE item_id = 1
Error at Command Line : 1 Column : 8
Error report -
SQL Error: ORA-04098: trigger 'KEVIN.PRICE_UPDATE' 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.
Please let me know what you suggest, I've searched high and low but am not able to find a solution.
This error only indicates a problem with the trigger.
You will need to view the USER_ERROR table
select *
from
user_errors
where
type = 'TRIGGER'
and
name = 'price_hist';
Check also SHOW ERRORS TRIGGER price_hist.
You should receive more information from this source. Reasons can be many, largely due to errors on the object.
I checked on my schemat and everything went perfectly, so probably something is wrong on your database schema.
Try creating the same tables on another user and see if the problem repeats itself.
Related
CREATE TABLE production.product_colors (
color_id INT PRIMARY KEY IDENTITY,
color_name VARCHAR (50) NOT NULL,
created_at DATETIME2
);
I created table production,product_colors and column name created_at datetime2 data type and now I want change data type but I cannot. Not only one table, I cannot alter any table in the database.
ALTER TABLE production.product_colors
ADD CONSTRAINT df_current_time
DEFAULT CURRENT_TIMESTAMP FOR created_at;
When I am running above query I get this error:
Msg 208, Level 16, State 1, Procedure TR_ALTERTABLE, Line 6 [Batch Start Line 86]
Invalid object name 'TableSchemaChanges'.
I cannot understand why this error occurring. I searched google and nothing helps me.
I think the issue caused by schema. Please double-check it.
Here is a correct sample using 'dbo' schema.
Demo
Please refer to the documentation
The following example creates a DDL trigger safety with database scope, and then disables and enables it.
CREATE TRIGGER safety
ON DATABASE
FOR DROP_TABLE, ALTER_TABLE
AS
PRINT 'You must disable Trigger "safety" to drop or alter tables!'
ROLLBACK;
GO
DISABLE TRIGGER safety ON DATABASE;
GO
ENABLE TRIGGER safety ON DATABASE;
GO
I want to add a column which's also a primary key if it doesn't already exist on the table. If I do a simple
ALTER TABLE webinars_identities ADD COLUMN IF NOT EXISTS id uuid
It will work but if I do
ALTER TABLE webinars_identities ADD COLUMN IF NOT EXISTS id uuid PRIMARY KEY DEFAULT uuid_generate_v4();
It says it skips the alter table, but for some reason crashes right after:
NOTICE: column "id" of relation "webinars_identities" already exists, skipping
ERROR: multiple primary keys for table "webinars_identities" are not allowed
My original working query was
ALTER TABLE webinars_identities id uuid PRIMARY KEY DEFAULT uuid_generate_v4();
But this is not repeatable without error.
What am I doing wrong here ?
Handle it using duplicate_column exception and issue a notice, because someone rightly said that errors should never pass silently.
DO $body$
BEGIN
ALTER TABLE atable ADD COLUMN id int primary key; --DEFAULT uuid_generate_v4()
EXCEPTION
WHEN duplicate_column THEN
RAISE NOTICE 'ERROR: %,%',SQLSTATE,SQLERRM;
END $body$;
This will work the first time and does not fail on all following attempts, but gives you a message. All other errors if found in your statement will be raised as exceptions.
NOTICE: ERROR: 42701,column "id" of relation "atable" already exists
DO
Try this.
DO $$ BEGIN TABLE atable ADD COLUMN IF NOT EXISTS id int primary key ; exception when others then null ; END$$;
It's a bug in postgres https://www.postgresql.org/message-id/13277.1566920001%40sss.pgh.pa.us
Will be fixed in v13.0, hopefully.
I am using the oracle database 10g express edition to execute triggers. My table structure is as shown below:
Table text:
create table text
(
tid number Not Null,
tname varchar2(5)
);
Table book:
create table book
(
bid number Not Null,
bname varchar2(5),
foreign key(bid) references text(tid)
);
Later inserted one row in text tabe: 1,abc
My question is when i am about to insert a value to text table, it should automatically insert a value in book table.
I had created a trigger named text_trig: structure is a s follows:
create trigger text_trig after insert on text
for each row
begin
insert into book set bid=NEW.tid;
end;
/
It gave me an warning message saying: Trigger created with compilation errors.
when I inserted a new value in text table, it is showing an error message as
trigger 'SYSTEM.TEXT_TRIG' is invalid and failed re-validation.
You missed a colon.
set bid = :NEW.tid
I am creating a trigger that should compare of the values being inserted with one that already exists in the table. The old referencer doesn't work here because I am inserting, but how can I reference something that already exists?
Here is my tables and trigger:
create table events(eid char(2) primary key, cid char(2));
create table activities(mid char(2), eid char(2),
primary key (mid, eid),
constraint activities_fk foreign key (eid) references events(eid));
create or replace trigger check_valid
before insert or update on activities
for each row when (old.mid=new.mid)
declare
v_eid char(2);
v_cid char(2);
n_cid char(2);
begin
select eid into v_eid from activities
where mid=:new.mid;
select cid into v_cid from events
where eid=v_eid;
select cid into n_cid from events
where eid=:new.eid;
if v_cid=n_cid then
raise_application_error(-20000, 'Error');
end if;
end check_valid;
/
show errors;
You can't generally select from the table you're inserting into in a trigger. This is the mutating table problem, or as I often call it, the "damn mutating table problem".
Basically, don't do this. It's a bad idea. What happens if you have two sessions operating on the table at once? The trigger fires and neither session sees what the other has done until the commit, which is after the trigger. Then you've got unexpected data in your database.
Tom Kyte says, "when I hit a mutating table error, I've got a serious fatal flaw
in my logic."
I'm trying to add a 'not null' constraint to a column in Oracle 9.
ALTER TABLE user_roles modify group_id varchar2(36 char) set not null;
However, the operation fails with an odd error:
Error report:
SQL Error: ORA-12987: cannot combine drop column with other operations
12987. 00000 - "cannot combine drop column with other operations"
*Cause: An attempt was made to combine drop column with other
ALTER TABLE operations.
*Action: Ensure that drop column is the sole operation specified in
ALTER TABLE.
Any ideas why this is failing?
Remove set:
ALTER TABLE user_roles modify group_id varchar2(36 char) not null
And yes, Oracle's errors can be very misleading.
It turns out the syntax of the above statement is wrong. It should be:
ALTER TABLE user_roles modify group_id varchar2(36 char) not null;
Still, the presence of an erroneous 'set' leads to a very odd error!
I'm trying to add a 'not null'
constraint to a column in Oracle 9.
If you are really trying jsut to make the column NOT NULL (i.e. you don't want to change the datatype at the same time) you just need to
ALTER TABLE user_roles modify not null;