Create trigger that gives warning/error - mysql

Need help for creating trigger using phpmyadmin that will give warning before inserting data. The situation is much like this:
CREATE OR REPLACE TRIGGER secure_item
BEFORE INSERT
ON item
BEGIN
IF (TRIM(TO_CHAR (SYSDATE, 'DAY')) IN ('SATURDAY', 'SUNDAY'))
OR ( TO_NUMBER(TO_CHAR(SYSDATE, 'HH24')) NOT BETWEEN 8 AND 15 )
THEN
raise_application_error (-20500,
'You may insert into test table only during business hours.'
);
END IF;
END;
/

Replace sysdate with
NOT hour(now()) between 8 and 15 OR weekday(now()) > 4

Related

I'm getting an error while excuting a trigger statement

enter image description here CREATE OR REPLACE TRIGGER weekd_tri
BEFORE INSERT OR UPDATE ON payment
FOR EACH ROW
BEGIN
IF TO_CHAR(SYSDATE, 'D') = '1' THEN
RAISE_APPLICATION_ERROR(-20000, 'Cannot make a payment on weekends');
END IF;
END;
error msg
ORA-06512: at "SCOTT.WEEKD_TRI", line 3
ORA-04088: error during execution of trigger 'SCOTT,WEEKD_TRI
can you tell me why i'm getting this error and how to solve this error
*
*this trigger should not accept payment by customer when made on Sat/Sun so i wrote this trigger but when I stried to insert data on Sun it did Fire a triger ORA - 20000 Cannot make a payment on weekends and I was not able to update the values but apart from that I got the other two Erros ORA-06512 & ORA:04088 **
As from your screenshot I see there are 3 error message lines
ORA-20000 - which is the real error message that has been caused from your logic
ORA-6512 - service message to identify the line of code error occured
ORA-4088 - another service message to identify trigger name where error occured
So, the reason why you're getting ora-4088 is raise_application_error command you're using for exception firing. It is just a part of service message for developers
There's no "error", except the one you created yourself, intentionally.
Which day is it today?
SQL> select to_char(sysdate, 'D') from dual;
T
-
1 --> OK, that's the value you're checking in a trigger
SQL>
Sample table:
SQL> create table payment (id number);
Table created.
Trigger:
SQL> create or replace trigger weekd_tri
2 before insert or update on payment
3 for each row
4 begin
5 if to_char(sysdate, 'D') = '1' then
6 raise_application_error(-20000, 'Cannot make a payment on weekends');
7 end if;
8 end;
9 /
Trigger created.
Testing:
SQL> insert into payment (id) values (1);
insert into payment (id) values (1)
*
ERROR at line 1:
ORA-20000: Cannot make a payment on weekends
ORA-06512: at "SCOTT.WEEKD_TRI", line 3
ORA-04088: error during execution of trigger 'SCOTT.WEEKD_TRI'
Right; that's EXACTLY what you wanted to do: IF concluded that today really is '1' and raised an error.
If it were e.g. '2' you checked, today you'd be able to insert a row:
SQL> create or replace trigger weekd_tri
2 before insert or update on payment
3 for each row
4 begin
5 if to_char(sysdate, 'D') = '2' then
6 raise_application_error(-20000, 'Cannot make a payment on weekends');
7 end if;
8 end;
9 /
Trigger created.
SQL> insert into payment (id) values (2);
1 row created.
SQL>

MYSQL BEFORE INSERT trigger does not insert record into table

I am using MYSQL 5.7.19 on ubuntu 16.04 (local mashine). I have 2 tables schema:
CREATE TABLE raw (rdate DATE, pim int(3));
CREATE TABLE indx (idate DATE, ipim int(2));
INSERT INTO raw (rdate, pim)
VALUES (20000101,50), (20000201, 52);
INSERT INTO indx (idate, ipim)
VALUES (20000101,5), (20000201, 5);
Table raw is for monthly data date and pim numbers. I want to write the trigger - before insert which will compare new pim with latest (is new pim higher or lower compared to previous pim value) and then according to number ranges (for example: if pim is between 40 and 50 than ipim = 5) insert particular number into column ipim in table indx and the new rdate into new idate.
Here is my trigger code:
DELIMITER //
CREATE TRIGGER sortpim BEFORE INSERT ON raw
FOR EACH ROW
BEGIN
DECLARE new_pim,old_pim,max_d INT;
SET new_pim = NEW.pim;
SET old_pim = (SELECT pim FROM raw WHERE rdate > CURDATE());
IF (old_pim <= new_pim) THEN
CASE WHEN new_pim BETWEEN 50 AND 59 THEN
INSERT INTO indx(idate,ipim) VALUES(NEW.rdate,6);
WHEN new_pim BETWEEN 60 AND 70 THEN
INSERT INTO indx(idate,ipim) VALUES(NEW.rdate,7);
END CASE;
ELSEIF (old_pim > new_pim) THEN
CASE
WHEN new_pim BETWEEN 50 AND 60 THEN
INSERT INTO indx(idate,ipim) VALUES(NEW.rdate,5);
WHEN new_pim BETWEEN 40 AND 49 THEN
INSERT INTO indx(idate,ipim) VALUES(NEW.rdate,4);
END CASE;
END IF;
END; //
DELIMITER ;
The trigger code is accepted with no errors but when I try to trigger it by inserting new record into raw table:
INSERT INTO raw(rdate,pim) VALUES(20000301,55);
record is inserted with no errors and the trigger does not do anything - the indx table is not inserted with new record.
I'm new in MYSQL thus it is likely I choose wrong logic or methods. And it could be mistakes in algorithm or syntax. Any suggestions to solve this is appreciated. Thanx.
UPDATE!
Thanx for suggestions and point where are my mistake.
I have found the solution for getting the latest date as there was the mistake in trigger code on line 7. Here is what works:
` SELECT pim FROM raw ORDER BY rdate DESC LIMIT 1; `

MySQL trigger working on one table but not the other

I have created a mysql trigger to update on insert a value from another table:
DROP TRIGGER IF EXISTS `CourseCode`//
CREATE TRIGGER `CourseCode` BEFORE INSERT ON `race`
FOR EACH ROW BEGIN
SET NEW.Course_Code = (
SELECT
course_code
from
tb_course
where
tb_course.course_name = NEW.course_name
)
END
//
This works perfectly. It returns the 4 character code for the course_name based on the tb_course table.
What I'm trying to do is the exact same thing in another table, I copy and paste the trigger and rename the trigger and the table (field names and types are also identical) it but it won't work:
DROP TRIGGER IF EXISTS `CourseCode2`//
CREATE TRIGGER `CourseCode2` BEFORE INSERT ON `fields`
FOR EACH ROW
BEGIN
SET NEW.Course_Code = (
SELECT
course_code
from
tb_course
where
tb_course.course_name = NEW.course_name
)
END
//
However this results in null values. I've tried replacing New.Course_name with a string (i.e. tb_course.course_name="String") and that updates that static value fine so the trigger appears to be working but either it isn't matching the select statement in this table for or it's not setting the Course_Code field...
Is there any sort of debugging you can suggest to figure this out? It's driving me nuts and I don't know what to do to diagnose the problem.
Cheers
I have no idea what is wrong with the second trigger.
However, the 'debugging' part i can maybe help with.
A search of the 'net' will return various software (paid for) that will allow single step debugging. Rather than pay for stuff, all i want is 'print' statements from inside stored function procedures and triggers.
a quick search lead me to someone who has done all the work already.
Debugging Stored Procedures in MySql
I have just set it up in MySql and tried it and it works fine.
Here is some sample code, based on your trigger and the output i got.
DELIMITER $$
USE `testmysql`$$
DROP TRIGGER /*!50032 IF EXISTS */ `CourseCode`$$
CREATE
/*!50017 DEFINER = 'test'#'localhost' */
TRIGGER `CourseCode` BEFORE INSERT ON `race`
FOR EACH ROW BEGIN
DECLARE v_course_code INT;
DECLARE v_course_title VARCHAR(255);
CALL procLog("line 12: Entering CourseCode");
SELECT
course_code, course_title
INTO
v_course_code, v_course_title
FROM
tb_course
WHERE
tb_course.course_name = NEW.course_name;
SET NEW.course_code = v_course_code;
CALL procLog(CONCAT("line_22: ", v_course_title, " code: ", NEW.course_code));
CALL procLog("line 24: Exiting CourseCode");
END;
$$
DELIMITER ;
Query:
CALL setupProcLog();
INSERT INTO `race` (course_name, race_info)
VALUES ('learn_it_02', 'this is another test');
CALL cleanup('query end');
procLog output:
entrytime connection_id msg
2014-02-23 12:32:21 5 line 12: Entering CourseCode
2014-02-23 12:32:21 5 line_22: Learn It Course 02 code: 2
2014-02-23 12:32:21 5 line 24: Exiting CourseCode
2014-02-23 12:32:21 5 cleanup() query end
Ok, a little clumsy maybe but it will help with debugging 'stored' programs.
I will be using it from now on.

Compare time values correctly

I am having trouble comparing MySQL Time fields, I have a NOEVENTS row starting from 09:00 to 10:00 and I am trying to insert a row into another table, but I need to compare the NOEVENTS time, to the incoming Time fields. example:
I want to insert a event from 09:15 to 09:30, and another from 10:00 to 11:00, so how can I compare that? im trying this:
select count(idNOEVENTS) into existNOEVENT from NOEVENTS b where eventInitialTime && eventFinalTime between b.initialTime and b.finalTime;
if existNOEVENT>0
SET MESSAGE_TEXT = 'Error! no events allowed at this time';
The problem is when I try to insert the 09:15 to 09:30, it throws the error message shown above. Thats fine, it works, but when I try to insert the 10:00 to 11:00 event it throw the msg, and it shouldnt, how can I fix it? or compare it better?
Thanks, and sorry for my poor english.
You can do it this way
SELECT *
FROM noevents
WHERE (? > initialTime AND ? < finalTime)
OR (? > initialTime AND ? < finalTime)
Now don't use COUNT(*) to check for existence of a row(s). Use EXIST() instead.
That being said to give an idea this how you procedure code might look like
DELIMITER $$
CREATE PROCEDURE add_event(IN _start TIME, IN _end TIME)
BEGIN
IF EXISTS(SELECT *
FROM noevents
WHERE (_start > initialTime AND _start < finalTime)
OR (_end > initialTime AND _end < finalTime)) THEN
SIGNAL sqlstate '45000'
SET message_text = 'Error! no events allowed at this time';
ELSE
-- Do whatever you have to do to insert an event
SELECT 'Success: event added';
END IF;
END$$
DELIMITER ;
Here is SQLFiddle demo

trigger to duplicate rows in same table in mysql for class timetable

I'm making a class timetable. There are 5 classes, each class occurs once every week. I have two tables a class table and a schedule table.
I'm trying to make a trigger where the row will be duplicated on the same table, but entered on a different date. I also need that row to be deleted after insert.
I have this so far:
DROP TRIGGER IF EXISTS `erase`//
CREATE TRIGGER `erase` BEFORE DELETE ON `flsch`
FOR EACH ROW INSERT INTO flsch SELECT * FROM flsch WHERE DATE_ID=old.DATE_ID
Is there any way this can be done?
#Devart I've added the new piece of code as requested below:
DELIMITER $$
CREATE PROCEDURE add_f(IN param_DATEID TIMESTAMP, IN param_SNO VARCHAR(6), IN param_sub VARCHAR(20), IN param_SCHD INT(4))
BEGIN
IF SNO ='math01'
INSERT INTO schtt VALUES(param_DATEID, param_SNO, param_SUB, param_SCHD);
INSERT INTO schtt VALUES(param_DATEID + INTERVAL 7 DAY, param_SNO, param_SUB, param_SCHD);
END IF;
ELSE IF SNO='eng101'
INSERT INTO schtt VALUES(param_DATEID, param_SNO, param_SUB, param_SCHD);
INSERT INTO schtt VALUES((param_DATEID + INTERVAL 1 DAY) + INTERVAL 7 DAY, param_SNO, param_SUB, param_SCHD);
END IF;
END
$$
DELIMITER ;
Can I enter a string which will delete a record after a certain date with a PROCEDURE, or can that only be done through a Trigger
This cannot be done with a help of trigger because of restriction - Within a stored function or trigger, it is not permitted to modify a table that is already being used (for reading or writing) by the statement that invoked the function or trigger.
Write a stored procedure to perform logic or do it in the application.
OK, suppose that we have a table, and we need to add a record and duplicated record with different date, the stored procedure can help us:
CREATE TABLE table1 (
name VARCHAR(255) DEFAULT NULL,
dt DATE DEFAULT NULL
);
DELIMITER $$
CREATE PROCEDURE add_two_records(IN param_name VARCHAR(255), IN param_dt DATE)
BEGIN
INSERT INTO table1 VALUES(param_name, param_dt);
INSERT INTO table1 VALUES(param_name, param_dt + INTERVAL 1 DAY);
END
$$
DELIMITER ;
Add records:
CALL add_two_records('Rick', '2012-01-16');
Let's check result:
SELECT * FROM table1;
+------+------------+
| name | dt |
+------+------------+
| Rick | 2012-01-16 |
| Rick | 2012-01-17 |
+------+------------+
Syntax error fixes:
DELIMITER $$
CREATE PROCEDURE add_f(IN param_DATEID TIMESTAMP, IN param_SNO VARCHAR(6), IN param_sub VARCHAR(20), IN param_SCHD INT(4))
BEGIN
IF param_SNO ='math01' THEN
INSERT INTO schtt VALUES(param_DATEID, param_SNO, param_SUB, param_SCHD);
INSERT INTO schtt VALUES(param_DATEID + INTERVAL 7 DAY, param_SNO, param_SUB, param_SCHD);
ELSE IF param_SNO='eng101' THEN
INSERT INTO schtt VALUES(param_DATEID, param_SNO, param_SUB, param_SCHD);
INSERT INTO schtt VALUES((param_DATEID + INTERVAL 1 DAY) + INTERVAL 7 DAY, param_SNO, param_SUB, param_SCHD);
-- You can use this one -
-- INSERT INTO schtt VALUES(param_DATEID + INTERVAL 8 DAY, param_SNO, param_SUB, param_SCHD);
END IF;
END$$
DELIMITER ;
You asked:
Can I enter a string which will delete a record after a certain date with a PROCEDURE...
Yes, you can do it with a DELETE statement + WHERE clause.