Trigger to check logic date update - sql

Building an employee database and we want to make sure the database can't be updated incorrectly with employment end date being before the start date. We want to use a trigger to block the update, throw an error, and rollback.
I know this is wrong but this is where I am:
CREATE TRIGGER EmpLeaveWarn on Employee FOR UPDATE
AS
IF(select End_Date < Start_Date)
BEGIN
RAISERROR ('The End date must come after the Start date')
ROLLBACK TRAN
RETURN
END
GO
For Microsoft SQL Server.
Thanks in advance.

No need for a trigger, just use a constraint:
alter table EmpLeaveWarn
add constraint check_end_date check (End_Date >= Start_Date);

The easiest way to acheive this would be by using a check constraint, not a trigger:
ALTER TABLE Employee ADD CONSTRAINT Employee_Date_Check CHECK ( End_Date >= Start_Date)

Related

SQL IF statements in transactions

I'm trying to make a condition where if the number of available seats within a given plane is less than zero then ROLLBACK. However, I am receiving a message stating that there is a syntax error at IF (i.e. "syntax error at or near "IF""). Why is this, can I not use if statements in transactions? And if so, how can I perform this conditional statement?
BEGIN;
UPDATE FlightBooking SET NumSeats = NumSeats + 100, TotalCost = TotalCost + 100
WHERE CustomerID = 20005;
IF (SELECT Available_Seats FROM checkAvailability(30001) < 0) THEN
ROLLBACK;
END IF;
COMMIT;
Many thanks, callum
Use a check constraint!
alter table flightbooking add constraint chk_flightbooking_availability
check (availability >= 0);
That way, the update simply fails and the data never fails to meet your condition.
Alas, if you want to use your function, you need to convert it to a scalar value:
alter table flightbooking add constraint chk_flightbooking_availability
check (checkAvailability_scalar(30001) >= 0);
That said, it is probably better to store that value somewhere and use a check constraint on that table.
Personally I would do the check before the update... that way you don't have to roll back.
Here is how to fix your if statement.
IF (SELECT Available_Seats FROM checkAvailability(30001)) < 0 THEN
ROLLBACK;
END IF;

Check future date in trigger

I want to launch a trigger if a user try to replace current date with a future date.But subquery might not allowed in trigger. How can i solve this issue? Any suggestion....
CREATE OR REPLACE TRIGGER check_join_date
BEFORE UPDATE OF join_date ON DOCTOR
FOR EACH ROW
WHEN (NEW.join_date > (SELECT CURRENT_DATE+1 FROM DUAL) )
BEGIN
RAISE_APPLICATION_ERROR(-20509,'Do not Enter Future Date..');
END check_join_date;
/
I am getting this error after running this code in Oracle.
ORA-02251: subquery not allowed here
test this
CREATE OR REPLACE TRIGGER check_join_date
BEFORE UPDATE OF join_date ON DOCTOR
FOR EACH ROW
WHEN (NEW.join_date > CURRENT_DATE+1)
BEGIN
RAISE_APPLICATION_ERROR(-20509,'Do not Enter Future Date..');
END check_join_date;
/

Trigger which check the current Date with the Date in the table

I do not know how to compare 2 Dates in a trigger (one in the table and the current Date)
Here is my draft of the trigger:
CREATE trigger check_update
BEFORE DELETE ON customer_contract
For each row
Begin
If(date_to_cancel_contract > (<date>))
Signal sqlstate ‘45000’
Set message_text = ‘Error, not allowed to cancel contract.’
END IF
What’s wrong? How can I fix the problem?
The condition should be (provided it is SQL Server)
If(date_to_cancel_contract > dateadd(day,datediff(day,0,getdate()),0))

Using Sysdate in trigger

Hello guys I'm a bit of a noob when it comes to triggers so I'm just looking for some advice on how to do the follow trigger.
I have created a trigger that will throw an error message if someone was to delete a record during office hours however I would like to create another trigger that uses SYSDATE will not delete records from say today and future dates.
I was thinking of maybe using >=SYSDATE but I'm not sure if that is a valid sql statement.
CREATE OR REPLACE TRIGGER records_delete
BEFORE DELETE
ON RECORDS FOR EACH ROW
BEGIN
IF TO_CHAR(SYSDATE, 'HH24MI') NOT >= sysdat
RAISE_APPLICATION_ERROR(-20669, 'You can not delete current or future records');
END IF;
END records_delete;
Thanks, leprejohn
The problem here is that you're not referencing any of the fields of the table that you're deleting from.
If your table had a column called record_date then you could rewrite this as:
CREATE OR REPLACE TRIGGER records_delete
BEFORE DELETE
ON RECORDS FOR EACH ROW
BEGIN
IF (:old.record_date >= SYSDATE) THEN
RAISE_APPLICATION_ERROR(-20669, 'You can not delete current or future records');
END IF;
END records_delete;
The syntax :old. and :new. are how you reference the columns of the current record being acted upon by the trigger, with :old. being the prefix for inspecting the values before the trigger acts on it and :new. being for values after the trigger is done. This syntax allows you to see the values before/after the trigger updates the data, which in your case doesn't matter since you're deleting records.
If you want to disregard the hours, mins, seconds of the date fields, use this in the IF statement
trunc(:old.record_date) >= trunc(SYSDATE)
If record_date is actually stored as a string instead of a date, you would convert it to a date before comparison:
to_date(:old.record_date, 'DDMMYYYY') >= trunc(SYSDATE)
Update the format mask 'DDMMYYYY" to the format your date is actually stored in. Check the Oracle documentation for description of to_date and date format models.
Give this a shot and see if it works.

SQL Oracle Trigger to change date

CREATE OR REPLACE TRIGGER shares_to_amount
AFTER INSERT OR UPDATE OF issued ON shares_amount
FOR EACH ROW
BEGIN
INSERT INTO shares_amount(
share_issue_id,
share_id,
issued,
date_start,
date_end
) VALUES (
:OLD.share_issue_id,
:OLD.share_id,
:NEW.issued,
:NEW.date_start,
:((NEW.date_start)-1).date_end
);
END;
I want to change the date_end to the date_new date -1 when a new share value is issued into 'issued'. The start date can be today's date but the end date will have to display the day before.
Fist of all your trigger can't work because of mutating table problem. You can't execute DMLs or queries in row-level triggers agains the table which is being changed by triggering DML (if the trigger is not autonomous but this is dangeros and exceptionac case). If I understand your question right you want to keep the history of changes made for shares. Th best way is to create PL/SQL package, incapsulate logic into procedures and provide this interface to end-users or other programms.