I am trying to create a trigger for a cinema database.
I need it to update once a rating is added for a movie showing the text "rating added". The table name is
movie_ratings
the primary key is = movie_rating
I am not really sure how to do it, I have looked online but still are not too sure. I was wondering if anyone could help.
Thanks
Here is the syntax to create a trigger which will fire when a row is inserted.
create trigger movie_rating_added on movie_ratings for insert
as
-- trigger code goes here
go
Inside the trigger, you have access to a virtual table called inserted, which has the same schema as movie_ratings, but which contains only the rows which were inserted.
I'm not clear on exactly what you want the trigger to do, but for example you could do something like this:
create trigger movie_rating_added on movie_ratings for insert
as
update m set last_action = "rating added"
from movies m
join inserted i on i.movie_id=m.id
go
Which is supposing the existence of some fields and tables that you might not have, but hopefully it gives you a useful example.
Related
I've read and tried other posts/answers but am having a hard time getting this to work. I feel like it should be pretty simple for an experienced SQL programmer, but for me I'm ready to ask for help.
When I insert a record into the HistoricalWorkorders table, I simply want to delete any records with the same workorder # in the ActiveWorkorders table.
I'm trying to accomplish this using a trigger on insert.
I started simple by using the following code to insert into ActiveWorkorders every time a record is inserted into HistoricalWorkorders. That code works.
How do I modify this query such that upon insert to the HistoricalWorkorders table, any records with the same workorder # within the ActiveWorkorders table get deleted?
On a seperate note, everyone says you can reference the inserted record simply by referencing 'inserted', but it doesn't work for me? For example, shouldn't inserted.workorder return the workorder value being inserted to the table?
ALTER trigger [dbo].[WOArchive] on [dbo].[HistoricalWorkOrders]
after update,insert
as
begin
insert into ActiveWorkorders
(Workorder,Grindcount,Status)
select i.workorder, i.grindcount, i.status
from HistoricalWorkorders t
inner join inserted i on t.workorder=i.workorder
end
I'm a new SQL developer. After recommendations I have altered my trigger (for this task I need to use a trigger so can't avoid it), but I have re-altered my trigger. I want it to prevent a duplication in the Rentals table of the BikeID foreign key contained within it.
This is my code at the moment:
CREATE TRIGGER BikeNotAvailable
ON dbo.SA_Rental
AFTER INSERT
AS
IF EXISTS (SELECT *
FROM SA_Rental
INNER JOIN inserted i ON i.BikeID = dbo.SA_Rental.BikeID)
BEGIN
ROLLBACK
RAISERROR ('This bike is already being hired', 16, 1);
END
go
But when I enter the BikeID in the Rentals table, even though the BikeID is not present inside a row yet, it still raises the error - why? (I have also tested this on an empty table and it still raises the error)
Just some context on my data, the BikeID is a primary key from the 'Bike' table that is shared as a foreign key to the Rentals table, not sure if this has anything to do with the error.
Can someone please help me fix this trigger so it works.
Thanks.
Well, as it's an AFTER trigger, the trigger is run after the new record is added to the table (at least visible for your trigger).
Supposing that your table has an automatically generated ID column, you should exclude the inserted row from your check like this:
CREATE TRIGGER BikeNotAvailable ON dbo.SA_Rental
AFTER INSERT
AS
if exists ( select * from SA_Rental
inner join inserted i on i.BikeID=dbo.SA_Rental.BikeID
where SA_Rental.RentalID <> i.RentalID)
begin
rollback
RAISERROR ('This bike is already being hired', 16, 1);
end
go
A far simpler way to achieve what you are after is to create a unique index:
CREATE UNIQUE INDEX BikeRented ON SA_Rental (BikeID);
This, of course, assumes that you delete the row from your table when the bike is no longer rented (as this is the implied logic in your post). If this is not the case, then we need more detail; what specifies on your table that the rental has completed?
If we assume you have a return date, and the return date is NULL when the bike is yet to be returned, then you would use a filtered index like so:
CREATE UNIQUE INDEX BikeRented ON SA_Rental (BikeID)
WHERE ReturnedDate IS NULL;
I am trying to find some workaround to create and execute multiple triggers for different tables on one table. I have 2 tables
Person Detail
Address
The way this table is designed is when a user updates Person's address it creates a new record into address table instead of updating the existing one and I want to insert the changes into auditlog table when a user updates person details or address.
I was able to create a trigger for person table but dont know how can i make it work by using or calling multiple triggers on Person Table
Following is the code for Person table update trigger
CREATE TRIGGER [dbo].[tr_tblPersonDetail_ForUpdate]
ON [dbo].[PersonDetail]
FOR Update
AS
BEGIN
Declare #Id int,
Declare #OldFirstName varchar(50), #NewFirstName varchar(50)
BEGIN
Select #Id=personId,#NewFirstName = NewFirstName from Inserted
select #OldFirstName = NewFirstName from deleted where #id = personId
if(#OldFirstName <> #NewFirstName )
Insert into AuditLog values('some value','AfterValue','Before Value')
Yes, one table may have multiple triggers. You do need to exercise caution, however - you may not want every update to fire both triggers, or you may have need to execute the triggers in a particular order.
It really sounds like you want an INSTEAD OF UPDATE trigger for the requirement of
creates a new record into address table instead of updating the existing one
If you need your trigger to execute only if specific field(s) were updated, use UPDATED() to test for them.
You can use sp_settriggerorder to dictate which trigger should execute and which one last.
In your case, I would suggest an AFTER UPDATE for any operation that changes only the person's name, and then an INSTEAD OF UPDATE which handles cases where the address is changed (which will also need to handle the name change).
If you choose to continue down the path of using triggers at all.
I have never really worked with Triggers before in MSSQL but I think it'll be what I need for this task.
The structure of the table is as such:
ID|****|****|****|****|****|****|****|TOUROPERATOR
The Tour Operator Code is the code that tells us what company owned the flight we carried out for them. Two of those codes (there are 24 in total) are outdated. Our users requested that those two be changed but the tour operator code is pulled from a database we don't control. The FlightData table however, we do control. So I was thinking a trigger could change the tour operator code if it was one of the two outdated ones, to the correct ones instead respectively when they were inserted.
So I went into good ol' SQL Management Studio and asked to make a trigger. It gave me some sample code and here is my Pseudo Code below:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TRIGGER ChangeProvider
ON FlightData
AFTER INSERT
AS
BEGIN
IF(TheInsertedValue == Criteria)
UPDATE FlightData
SET TheInsertedValue = NewValue
ENDIF
END
GO
I am not that good with this type of Database Programming so excuse my mistakes.
How would I go about doing this?
You could add a computed column to your table instead of adding a trigger.
Then the new column could just use a case statement to either show
the original TourOperator column value or the new value you wanted.
You'd add a new column to your table like this
TourOperatorCorrect = CASE WHEN TourOperator = 'Whatever value' THEN 'ChangedValue'
--I just want to use what I have already in the TourOperator column
ELSE TourOperator
END AS VARCHAR(50)
Basics of computed columns are here - https://msdn.microsoft.com/en-ie/library/ms188300.aspx
Your misconception here is that the trigger runs once per inserted value - it is in fact run once per insert statement, so you can and will find more than one row inserted at once.
You'll find that your inserted values are in the pseudo table inserted, which has the same structure as your FlightData table in this case. You write a select statement against that, specifying any criteria you wish.
However, it's not immediately clear what your logic is - does the FlightData table you are updating in your trigger only have one row? Do you update every row in the table with the newest inserted value? It is hard to understand what you are trying to now, and what the purpose of the table and this trigger are - let alone what you would want to do if you inserted more than one row at once.
When inserted table contains mutiple rows,your code will fail,so change code to work with inserted table as whole
UPDATE F
SET f.TheInsertedValue = i.value
from inserted i
join
Flighttable F
on f.matchingcolumn=i.matchingcolumn
and i.somevalue='criteria'
I want to update two tables when a user wants to update a view.
create trigger update_mID
instead of update of mID on LateRating
for each row
begin
update Movie, Rating
set mID = new.mID
where mID = Old.mID;
end;
I want to update bot the Movie relation and the Rating relation, however, I have not yet experienced a trigger that is able to update multiple tables. Can someone please indicate how I can overcome this?
UPDATE: This is for a exercise to test my trigger scripting skills. The requirement is that I have to write it in one trigger query. #CL. I tried putting two update statements between the begin and end keywords, however, it says that there is a syntax error.... is there a specific way to put two updates between the begin and end?
A single UPDATE statement can modify only a single table.
Use two UPDATEs:
UPDATE Movie SET mID = NEW.mID WHERE mID = OLD.mID;
UPDATE Rating SET mID = NEW.mID WHERE mID = OLD.mID;
You could do a REPLACE INTO statement like the following:
DROP TRIGGER IF EXISTS `update_mID`;CREATE DEFINER=`USER`#`localhost` TRIGGER
`update_mID` AFTER UPDATE ON `tblname` FOR EACH ROW REPLACE INTO
USER_DATABASENAME.TBLNAME (COLUMNNAME1,COLUMNNAME1) SELECT COLUMNNAME1,COLUMNNAME1
FROM USER_DBNAME.TBLNAME
This can even be two separate databases like the example below:
DROP TRIGGER IF EXISTS `update_mID`;CREATE DEFINER=`USER`#`localhost` TRIGGER
`update_mID` AFTER UPDATE ON `tblname from DB1` FOR EACH ROW REPLACE INTO
USER_DATABASENAME1.TBLNAMEDB2 (COLUMNNAME1,COLUMNNAME1) SELECT
COLUMNNAME1,COLUMNNAME1 FROM USER_DBNAME2.TBLNAME