I need to Write a stored procedure to find out the joining date of teachers and if it is a Monday it should display Monday else it should display Weekday. I am very new in stored procedure how i can display 'weekday?
I have prepared a code but am geting error.(dat_teacher_doj is in date datatype)
Delimiter //
CREATE PROCEDURE check_date(IN doj date)
BEGIN
select dayname(dat_teacher_doj)as day from tbl_teachers where dat_teacher_doj=doj;
IF day!='Monday' THEN
SET day='Weekday';
END IF
END //
Delimiter ;
AM GETTING ERROR: UNKNWN SYSTEM VARIABLE 'day'
You first need to DECLARE your variable. Then use SELECT ... INTO after you have declared your variable.
DELIMITER //
CREATE PROCEDURE check_date (IN teacher_id VARCHAR(100))
BEGIN
DECLARE day VARCHAR(100);
SELECT dayname(dat_teacher_doj) INTO day FROM tbl_teachers WHERE id = teacher_id;
SELECT CASE WHEN day != 'Monday' THEN 'Weekday' ELSE day END;
END;
//
DELIMITER ;
When you call your procedure, you need to put quotes around your input date.
call check_date('1982-01-11');
Related
Could someone please help me? I don't know what the problem here
DROP PROCEDURE IF EXISTS insertRandom;
CREATE PROCEDURE insertRandom()
BEGIN
DECLARE mytime timestamp;
SET mytime := '2009-01-01 00:00:00'
BEGIN
test_loop : LOOP
while mytime < now()
mytime = mytime + interval '8 hours';
insert into tempdata(temp_val, datum) values((select random()*(110)-10), mytime);
END LOOP;
END;
CALL insertRandom;
SELECT * FROM `temp_table`;
You have many errors in your code
Use this Procedure instead
DELIMITER $$
CREATE DEFINER=`root`#`localhost` PROCEDURE `insertRandom`()
BEGIN
DECLARE mytime timestamp;
SET mytime := '2009-01-01 00:00:00';
DROP TEMPORARY TABLE IF EXISTS tempdata;
CREATE TEMPORARY TABLE tempdata (temp_val BIGINT, datum timestamp);
test_loop : LOOP
IF mytime >= now() THEN
LEAVE test_loop;
END IF;
SET mytime = TIMESTAMPADD(HOUR,8,mytime);
insert into tempdata(temp_val, datum) values((select (rand()*110)-10), mytime);
END LOOP;
END$$
DELIMITER ;
And then
call insertRandom();
SELECT * FROM tempdata;
Looks like a semicolon in the procedure body is terminating the statement. We need MySQL to see the CREATE PROCEDURE as a single statement, but MySQL is chopping the statement off, seeing a complete statement when it sees a semicolon.
The default statement delimiter in MySQL is semicolon ; character. The default delimiter can be overridden; we change with the DELIMITER statement.
Example here of temporarily modifying the statement delimiter to be two dollar sign characters $$. Within the procedure body, occurrences of the semicolon character won't terminate the statement... MySQL will keep reading until it finds two dollar sign characters. (Goes without saying that the procedure body shouldn't contain $$)
DELIMITER $$
DROP PROCEDURE IF EXISTS insertRandom $$
CREATE PROCEDURE insertRandom()
...
...
...
END$$
DELIMITER ;
CALL insertRandom();
Note that we use the DELIMITER statement to change the delimiter back to the semicolon character. I did not check the body of the procedure for other syntax errors; but some things stick out. For example, this looks wrong
mytime = mytime + interval '8 hours';
that should probably be SET statement, and the syntax is like this:
SET mytime = mytime + INTERVAL 8 HOUR;
In the SET statement, we can use the := in place of = as the assignment operator, so equivalent
SET mytime := mytime + INTERVAL 8 HOUR;
For looping withing a MySQL stored program, we can do a LOOP ... END LOOP and include a LEAVE statement, or we can use a WHILE loop, or ...
Syntax documented here:
https://dev.mysql.com/doc/refman/5.7/en/while.html
https://dev.mysql.com/doc/refman/5.7/en/loop.html
I need to write a MySql Event to select some values from a table under some conditions and put those values in a second table. By the select statement. I get multiple rows, so I need to store data in the second table as a batch. How can I achieve this? I wrote an event to select one row. But what I need to do is select multiple rows and store as a batch.
The event I wrote is as below.
DELIMITER $$
CREATE EVENT salary_add
ON SCHEDULE EVERY 24 HOUR
DO
BEGIN
DECLARE month_end DATETIME;
DECLARE today DATETIME;
DECLARE reg_id VARCHAR(6);
DECLARE sal INT(8);
SET month_end = LAST_DAY(DATE(NOW()));
SET today = DATE(NOW());
IF month_end=today THEN
SELECT register_id,salary INTO reg_id,sal FROM employees
WHERE status ='1' LIMIT 1;
INSERT INTO tbl_salary (register_id,amount,salary_date,status) VALUES (reg_id,sal,today,'0');
END IF;
END $$
DELIMITER ;
You can insert selected rows into the target table at once. For example:
DELIMITER $$
CREATE EVENT salary_add
ON SCHEDULE EVERY 24 HOUR
DO
BEGIN
DECLARE month_end DATETIME;
SET month_end = LAST_DAY(CURDATE());
IF month_end=CURDATE() THEN
INSERT INTO tbl_salary (register_id, amount, salary_date, status)
SELECT register_id,
salary,
CURDATE(),
'0'
FROM employees
WHERE status ='1'
END IF;
END $$
DELIMITER ;
DELIMITER $$
CREATE FUNCTION current_age (birthdate date)
RETURNS date
BEGIN
DECLARE age_return date;
DECLARE rightnow date;
SET rightnow = date(now());
SET age_return = timestampdiff(year, rightnow, date(birthdate));
RETURN age_return;
END $$
DELIMITER ;
select current_age(date('2017-06-30'));
I am trying to create a function which years the difference in years. I cant get it to work and I dont understand why, because the following works fine outside the function.
SET #birthdate = '2001-01-01';
SET #rightnow = date(now());
SELECT timestampdiff(year, #rightnow, date(#birthdate))
If we want to return a number of years, then the return type would be a numeric type like INT or DECIMAL. We wouldn't return a DATE datatype.
DELIMITER $$
CREATE FUNCTION current_age(birthdate DATE)
RETURNS INT
BEGIN
RETURN TIMESTAMPDIFF(YEAR,birthdate,DATE(NOW()));
END$$
DELIMITER ;
I want to call multiple procedures from within a procedure. In the following SQL, I create three procedures. upd_r_money and upd_r_fuel both work as expected when called individually from the command line. When I call upd_all, only the first call within upd_all is run; the second call to upd_r_money doesn't run.
I can't figure out why this happens - maybe something in my upd_r_fuel procedure causes my upd_all procedure to end early? I am a newby to writing procedures, and SQL in general.
There was another question here about this problem, but the answer is exactly what I'm already doing, and the answer's link was down.
drop procedure upd_r_money;
delimiter //
CREATE procedure upd_r_money(row_id int)
BEGIN
DECLARE money_rate INT DEFAULT 1;
DECLARE period INT DEFAULT 0;
SET period = (select timestampdiff(second, (select lastaccessed from gamerows where id = row_id), now()));
update gamerows
set money = money + period * money_rate,
lastaccessed = now()
where id = row_id;
END;
//
delimiter ;
drop procedure upd_r_fuel;
delimiter //
CREATE procedure upd_r_fuel(row_id int)
fuel: BEGIN
DECLARE fuel_rate INT DEFAULT 1;
DECLARE period INT DEFAULT 0;
SET period = (select timestampdiff(second, (select lastaccessed from gamerows where id = row_id), now()));
update gamerows
set fuel = fuel + period * fuel_rate,
lastaccessed = now()
where id = row_id;
END fuel;
//
delimiter ;
drop procedure upd_all;
delimiter //
CREATE PROCEDURE upd_all(row_id int)
BEGIN
call upd_r_fuel(row_id);
call upd_r_money(row_id);
END;
//
delimiter ;
If I copy and paste the above SQL commands, my procedures are created successfully with no errors and I can call all three of them. However as I wrote earlier, upd_all seems to stop after calling its first procedure within. If I switch upd_r_money with upd_r_fuel, the same behavior occurs - the first procedure is called and not the second.
I suspect that it doesn't work as expected because you update lastaccessed time and calculate difference with NOW. First work because there is significant difference. But with second stored procedure you have timestammpdiff between NOW() and NOW() - miliseconds.
Check if removing in first stored procedure lastaccessed from update helps.
drop procedure upd_r_money;
delimiter //
CREATE procedure upd_r_money(row_id int)
BEGIN
DECLARE money_rate INT DEFAULT 1;
DECLARE period INT DEFAULT 0;
SET period = (select timestampdiff(second, (select lastaccessed from gamerows where id = row_id), now()));
update gamerows
set money = money + period * money_rate
where id = row_id;
END;
//
delimiter ;
Warning: Now the order of execution matters.
Also your stored procedures are so similiar that I would combine them in one UPDATE:
update gamerows
set fuel = fuel + period * fuel_rate,
money = money + period * money_rate,
lastaccessed = now()
where id = row_id;
i am trying to write a stored procedure for mysql, and basicly, it will select one id, and update selected id's operationdate.
DELIMITER //
CREATE PROCEDURE getID(
IN proc_intervaldate datetime
)
BEGIN
DECLARE RUserID BIGINT;
SELECT
UserID
INTO RUserID
FROM Tasks
WHERE OperationDate < proc_intervaldate
LIMIT 1 ;
UPDATE Tasks SET OperationDate = now() WHERE UserID = RUserID;
SELECT RUserID ;
END //
DELIMITER ;
but when i use this, procedure, it will return UserID but not update, if i comment
SELECT RUserID
then, it updates, but no data returns.
when I use this, procedure, it will return UserID but not update, if I comment 'SELECT RUserID;' then, it updates, but no data returns.
You can change definition of stored procedure to use an OUT parameter rather than just IN. With that, you can just capture the OUT value on the same OUT parameter, in your scripting language. Meaning you need not execute:
SELECT RUserID ;
in your stored procedure.
Change your SP definition as below:
DELIMITER //
CREATE PROCEDURE getID( IN proc_intervaldate datetime, OUT RUserID bigint )
BEGIN
SELECT
UserID INTO RUserID
FROM Tasks
WHERE
OperationDate < proc_intervaldate
LIMIT 1 ;
UPDATE Tasks SET OperationDate = now() WHERE UserID = RUserID;
END;
//
DELIMITER ;
You can call this stored procedure like, for example, at MySQL console:
SET #RUserID := 0;
CALL getID( now(), #RUserID );
SELECT #RUserID;
Refer to:
MySQL: CALL procedure syntax
To get back a value from a procedure using an OUT or INOUT parameter,
pass the parameter by means of a user variable, and then check the
value of the variable after the procedure returns.