Mysql prevent insert after some date - mysql

Is possible prevent the insertion in a mysql table after some date and time?
for example i have 2 tables:
TABLE exams
(
...
examID int primary key auto_increment,
examDate DATE,
examTime TIME,
...
)
TABLE inscripts
(
...
examID int not null references exams(examID),
insDate DATE,
insTime TIME,
...
)
i want to prevent the insertion of new inscriptions when the exam is playing.
There are some function to prevent this or check easily if current date and current time are equal or bigger than the date and time in matches table?

You could create a trigger that validates the insert before proceeding. Pseudo-code, but something like:
DELIMITER |
CREATE TRIGGER `Stop_Insert_During_Exam`
BEFORE UPDATE ON `inscripts`
FOR EACH ROW
BEGIN
DECLARE msg VARCHAR(255);
-- Check
-- Test if an exam is going on. If so:
SET msg = "You cannot add an inscription while an exam is going on.';
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = msg;
-- /Check
END;
|

Looking at your table, you already know the examid when you try to insert an inscription. So you can just grab the exam before you insert the inscription and check if it is ongoing. If it is just dont insert it and if it is not then insert it.

Related

Recursive table SQL

I´m new to SQL so I´m sorry if I make some simple mistakes. Having said that, I wanted to create a recursive table but I´m not sure how.
I have this table:
CREATE TABLE employee(
employee_id INT NOT NULL ,
Bdate DATETIME,
address VARCHAR(80),
PRIMARY KEY(supervisor_number)
);
And I have a 1:N cardinality in which 1 supervisor can supervise N supervisees. That´s why i need a recursive table, because an employee can either be a supervisor or a supervisee.
I don´t know how to create the recursive table so if anyone knows how I would be extremely grateful!
If there´s anything that isn´t clear let me know.
Thanks!
create a table of relation , you can call it supervision;
it the new table , put 2 fields : supervisor and supervisee;
these two fields are foreign keys to the table Employee ;
for example, employee number 1 is a supervisor for the employee 2 and 3, you insert two lines in the new table :
insert into supervision (supervisor, supervisee) values (1, 2), (1, 3);
Possible realization.
The table
CREATE TABLE employee(
employee_id INT NOT NULL ,
Bdate DATETIME,
address VARCHAR(80),
PRIMARY KEY(employee_id),
supervisor_id INT,
FOREIGN KEY (supervisor_id) REFERENCES employee(employee_id)
ON DELETE SET NULL ON UPDATE CASCADE );
The triggers which checks for subordinates amount (the value of 3 is hardcoded)
CREATE TRIGGER tr_bi_check_subordinates_amount
BEFORE INSERT
ON employee
FOR EACH ROW
BEGIN
IF 3 <= ( SELECT COUNT(*)
FROM employee
WHERE supervisor_id = NEW.supervisor_id ) THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'No available slots for specified supervisor';
END IF;
END
CREATE TRIGGER tr_bu_check_subordinates_amount
BEFORE UPDATE
ON employee
FOR EACH ROW
BEGIN
IF 3 <= ( SELECT COUNT(*)
FROM employee
WHERE supervisor_id = NEW.supervisor_id ) THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'No available slots for specified supervisor';
END IF;
END
DEMO fiddle

check date in create table sql

edit: version 8.0.20
I'm learning sql just now, I try to fix it but I'm not able to do it.
I have 3 table
create table order(
id_order int primary key,
order_date date
);
create delivery(
id_delivery int primary key,
delivery_date date,
cod_order int,
foreign key (cod_order) references order(id_order)
);
create purchased_product(
id_product int,
cod_order int,
return_date date,
foreign key (cod_order) references order(id_order)
primary key (id_product, cod_order)
);
This is an easier scheme but it's enough.
The return_date must be less than delivery_date + 30 days
I tried to use a check on return_date but no work, so I created a view to select the delivered products only
create view product_order_delivery(date_delivered_product) as
select date_delivery
from purchased_product P right join (select date_delivery, id_order
from order right join delivery
on order.id_order = delivery.cod_order
where date_delivery is not null) OD
on P.cod_order = OD.id_order
and I tried again with check on return_date.
Can someone help me to understand how fix it?
thanks in advance :)
Two common options for solving this are:
Write a trigger to be sure the condition is true.
Write a user-defined function and use that in a check constraint.
An alternative method might suffice in your case. Change the definition of return_date so it is days_to_return. Then you can use a check constraint:
check (days_to_return between 0 and 30)
Of course, to get the actual date, you will need to join the two tables to fetch the delivery date.
EDIT:
The insert trigger would look something like this:
delimiter $$
create trigger trig_purchased_product_return_date
before insert on purchased_product
for each row
begin
select #delivery_date = delivery_date
from delivery d
where d.cod_order = new.cod_order;
if new.return_date < #delivery_date or new.return_date > #delivery_date + interval 30 day then
signal sqlstate '45000' set message_text = 'invalid return_date'
end if
end;
delimiter ;

Script/workflow insert not exist and auto increment

I create a script/workflow exportation/importation from 2 system.
I have Table1 {id, name, description}
I want to create a script (not a procedure). I could (I didnt succed) adding procedure into my workflow. (create and delete at the end)
id is auto increment
I cant change the table
I can be sure that between the time I start execution of my script and the end, there will not be an insertion of one of my items into the database.
The script insert {name,description} but I want to NOT insert if the element (name or name and description) is there.
BASE QUERY :
INSERT INTO TABLE1 (name,description) VALUES ('itemX','this is item X')
BASE Script :
Use database1;
BEGIN;
SELECT * FROM TABLE1 ;
SELECT * FROM TABLE3 ;
INSERT INTO TABLE1 (name,description) VALUES ('itemX','this is item X');
set #idTable1 = LAST_INSERT_ID();
INSERT INTO TABLE3 (idTable1,idTable2) VALUES (#idTable1,1);
INSERT INTO TABLE3 (idTable1,idTable2) VALUES (#idTable1,2);
SELECT * FROM TABLE1 ;
SELECT * FROM TABLE3 ;
ROLLBACK;
I want to protect the multiple insertion on TABLE1. But without changing the table.
Maybe I did it wrong
I tried IF but not working outside procedure.
I tried IGNORE (valid only if id is the same, but never the same, its
auto increment)
I tried WHEN
I tried ON DUPLICATE KEY
Because of #idTable1, I will need change the " set #idTable1 = LAST_INSERT_ID();" if I doesnt have if else. But if my item is the only one with the same "name", I can get this instead of last_insert_id.
I opted for creating procedure before my "BEGIN" and removed them at the end of the script.
Just create the table with name as primary key, then be sure that you take care of the key capitalization (uppercase or lowercase) to avoid duplicates.
CREATE TABLE TABLE1(
id INT AUTO_INCREMENT,
name CHAR(30),
description CHAR(100),
PRIMARY KEY (name)
)
create unique constraint on name field if possible.
Otherwise, create trigger before insert in order to ignore duplicate insertion.
Trigger for checking duplicate on two fields a and b:
delimiter //
drop trigger if exists aborting_trigger //
create trigger aborting_trigger before insert on t
for each row
begin
set #found := false;
select true into #found from t where a=new.a and b=new.b;
if #found then
signal sqlstate '45000' set message_text = 'duplicate insert';
end if;
end //
delimiter ;
The trigger here provides feature similar to unique constraint. After creation you should use INSERT IGNORE or INSERT ...ON DUPLICATE KEY UPDATE

creating triggers and functions in postgresql

how can i create a trigger function before adding/updating,the function should check records that have the same id (i.e comparison by id with existing objects that have the same property as the temporary_object)If a record with the id is found, then that entry is set to the time_dead, and then it adds an entry containing the corresponding values ​​of the attributes found in that record (except those that are set for a new record), when time_dead is empty then time_create of a new time is equal to that time at the current moment . Thus,a new record time_create is like the time_dead's ancestor.
If a record with that id is found then it is added to the database with the establishment as the time_create of the current time.
for example here is a simple explanation(just for explanation purposes)
id time_create time-dead student amount
1 06.12 07.12 henry 500
1 07.12 henry 1000
so if a student called henry with id 1 entered a room at 06.12 and left at 07.12 the next time he enters another room again time_dead will be equal to time_create(so time_dead of old entry and time_create of new entry - will be equal)
these are my tables below in sql format
CREATE TABLE temporary_object
(
id integer NOT NULL,
time_create timestamp without time zone NOT NULL,
time_dead timestamp without time zone,
CONSTRAINT temporary_object_pkey PRIMARY KEY (id, time_create)
)
CREATE TABLE persons
(
fname text,
fsurname text,
)
INHERITS (temporary_object)
CREATE TABLE rooms
(
roomnum integer,
course integer,
passport text,
students_number text
)
INHERITS (temporary_object)
this is what i am trying to do but im afraid i do not know how to finish it but im 100% not right may some help out
CREATE TRIGGER trigger2
BEFORE INSERT OR UPDATE
ON persons
FOR EACH ROW
EXECUTE PROCEDURE func1();
and this is the function
CREATE OR REPLACE FUNCTION func1() RETURNS TRIGGER AS $persons$
DECLARE
time_create integer;
time_dead timestamp;
id timestamp;
BEGIN
IF (TG_OP = 'INSERT') THEN
time_create=
I can't tell you what I'm missing from your question, but I try to answer what I think I understood.
Row level triggers can access the version of the row affected with the NEW and OLD variables (depending on TG_OP). In this case, you can use NEW:
CREATE OR REPLACE FUNCTION func1()
RETURNS TRIGGER AS
$persons$
DECLARE
i integer;
BEGIN
IF TG_OP = 'INSERT'
THEN
UPDATE persons
SET time_dead = NEW.time_create
WHERE
id = NEW.id -- we are looking for the same ID
AND time_dead IS NULL
;
ELSE -- UPDATE
-- do here something
END IF;
END;
$persons$
LANGUAGE plpgsql;
This is only a starter, modify it to your needs.

help with mysql triggers (checking values before insert)

hi I'm quite new to mysql and I'm trying to figure out how to use triggers.
what I'm trying to do:
I have 2 tables, max and sub_max, when I insert a new row to sub_max I want to check if the SUM of the values with the same foreign_key as the new row are less than the value in the max table. I think this sounds confusing so here are my tables:
CREATE TABLE max(
number INT ,
MaxAmount integer NOT NULL)
CREATE TABLE sub_max(
sub_number INT ,
sub_MaxAmount integer NOT NULL,
number INT,
FOREIGN KEY ( number ) REFERENCES max( number ))
and here is my code for the trigger, I know the syntax is off but this is the best I could do from looking up tutorials.
CREATE TRIGGER maxallowed
after insert on sub_max
FOR EACH ROW
BEGIN
DECLARE submax integer;
DECLARE maxmax integer;
submax = select sum(sub_MaxAmount) from sub_max where sub_number = new.sub_number;
submax = submax + new. sub_MaxAmount;
maxmax = select MaxAmount from max where number = new.number ;
if max>maxmax
rollback?
END
I wanted to know if I'm doing this remotely correctly. Thanks in advance.
Caveat - I am also learning triggers.
For the section:
if max>maxmax
rollback?
Would the syntax be something like?:
IF max > maxmax THEN
DELETE the id of the new record?
ELSE
do nothing?
END IF;