Create function in MySQL - mysql

I'm just needing a little jump start, I'm a little confused how to do this. What I need to do is pull a 'customer_id' from the table and see how many items the customer has rented. If there are no 'customer_id' then it'll return 0. I'm just no quite grasping how to do this so any help is appreciated.
Create Table:
CREATE TABLE Customer
(name VARCHAR(30) NOT NULL,
address VARCHAR(70),
phone CHAR(10) NOT NULL,
customer_id INT(10) PRIMARY KEY NOT NULL);
Create Function: Have this partially started, but unsure if I'm doing it correctly.
DELIMITER $$
CREATE FUNCTION Num_Of_Rented(IN customer_id INT(10))
RETURNS INT(10)
BEGIN
DECLARE num INT(10);
SELECT IFNULL()
FROM
WHERE
RETURN num;
END $$
DELIMITER;

Inside your function, you need to select your value into your variable and then return your variable:
DECLARE num INT(10);
SELECT COUNT(field) INTO num
FROM table
WHERE condition;
RETURN num;
In your case:
DELIMITER $$
CREATE FUNCTION Num_Of_Rented(IN custId INT(10))
RETURNS INT(10)
BEGIN
DECLARE num INT(10);
SELECT COUNT(*) INTO num
FROM Customer C
WHERE C.customer_id = custId ;
RETURN num;
END $$
DELIMITER;

Related

Mysql Dynamic SQL is not allowed in stored function or trigger

To not publicly disclose our amount of invoices, we want to add random value between 2 ids.
Instead of [1,2,3] we want something like [69,98,179]
UUID is not an option in that project, unfortunately.
Using Mysql 5.7, 8, or MariaDb get the same results.
Here is the approach is taken:
Consider a simple table invoices as follows:
CREATE TABLE `invoices` (
`id` bigint(20) NOT NULL,
`name` varchar(255) DEFAULT NULL,
`created_at` datetime NOT NULL,
`updated_at` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=42 DEFAULT CHARSET=utf8mb4;
The function to get random values:
DROP FUNCTION IF EXISTS random_integer;
CREATE FUNCTION random_integer(value_minimum INT, value_maximum INT)
RETURNS INT
LANGUAGE SQL
NOT DETERMINISTIC
RETURN FLOOR(value_minimum + RAND() * (value_maximum - value_minimum + 1));
The function to get the next id:
DROP FUNCTION IF EXISTS next_invoice_id_val;
DELIMITER //
CREATE FUNCTION next_invoice_id_val ()
RETURNS BIGINT(8)
LANGUAGE SQL
NOT DETERMINISTIC
BEGIN
DECLARE lastId BIGINT(8) DEFAULT 1;
DECLARE randId BIGINT(8) DEFAULT 1;
DECLARE newId BIGINT(8) DEFAULT 1;
DECLARE nextId BIGINT(8) DEFAULT 1;
SELECT (SELECT MAX(`id`) FROM `invoices`) INTO lastId;
SELECT (SELECT random_integer(1,10)) INTO randId;
SELECT ( lastId + randId ) INTO nextId;
IF lastId IS NULL
THEN
SET newId = randId;
ELSE
SET newId = nextId;
END IF;
RETURN newId;
END //
DELIMITER ;
SELECT next_invoice_id_val();
and the trigger:
DROP TRIGGER IF EXISTS next_invoice_id_val_trigger;
DELIMITER //
CREATE TRIGGER next_invoice_id_val_trigger
BEFORE INSERT
ON invoices FOR EACH ROW
BEGIN
SET NEW.id = next_invoice_id_val();
END//
DELIMITER ;
That work like a charm, now if we want to generalize the behaviour to all tables.
We need a procedure to execute the query on any specific tables:
DROP PROCEDURE IF EXISTS last_id;
DELIMITER //
CREATE PROCEDURE last_id (IN tableName VARCHAR(50), OUT lastId BIGINT(8))
COMMENT 'Gets the last id value'
LANGUAGE SQL
NOT DETERMINISTIC
READS SQL DATA
BEGIN
SET #s := CONCAT('SELECT MAX(`id`) FROM `',tableName,'`');
PREPARE QUERY FROM #s;
EXECUTE QUERY;
DEALLOCATE PREPARE QUERY;
END //
DELIMITER ;
CALL last_id('invoices', #nextInvoiceId);
SELECT #nextInvoiceId;
The procedure for the next id value:
DROP PROCEDURE IF EXISTS next_id_val;
DELIMITER //
CREATE PROCEDURE next_id_val (IN tableName VARCHAR(50), OUT nextId BIGINT(8))
COMMENT 'Give the Next Id value + a random value'
LANGUAGE SQL
NOT DETERMINISTIC
READS SQL DATA
BEGIN
DECLARE randId BIGINT(8) DEFAULT 1;
SELECT (SELECT random_integer(1,10)) INTO randId;
CALL last_id(tableName, #currentId);
IF #currentId IS NULL
THEN
SET nextId = randId;
ELSE
SELECT ( #currentId + randId ) INTO nextId;
END IF;
END //
DELIMITER ;
CALL next_id_val('invoices', #nextInvoiceId);
SELECT #nextInvoiceId;
and the trigger:
# Call the procedure from a trigger
DROP TRIGGER IF EXISTS next_invoice_id_val_trigger;
DELIMITER //
CREATE TRIGGER next_invoice_id_val_trigger
BEFORE INSERT
ON invoices FOR EACH ROW
BEGIN
CALL next_id_val('invoices', #nextInvoiceId);
SET NEW.id = #nextInvoiceId;
END//
DELIMITER ;
and we get => Dynamic SQL is not allowed in stored function or trigger
I've read that storing in a temporary table might be a workaround, but as all posts have between 5 to 10 years old, I think we might have a better solution for such a straightforward case.
What is the workaround for using dynamic SQL in a stored Procedure
#1336 - Dynamic SQL is not allowed in stored function or trigger
Calling stored procedure that contains dynamic SQL from Trigger
Alternatives to dynamic sql in stored function

stored procudure variaibles in mysql

I am declaring variables inside the procedure and setting those values to result from another query.when executed it is giving null.
version:8.0.16
call putrequest('x',"jiraUPM","ASE-12345","inprogress","testcybsjira.com");
requestId and reqid are not null.but it taking null value .
create procedure `putrequest`(in `employeeId` varchar(15),in `reqtype`
varchar(15),in `ticketId` varchar(15),in `status` varchar(15),in `details`
varchar(100))
begin
declare `rid` int;
declare `reqType` int;
select `requestId` into `reqType` from `requesttype` where `request`=`reqtype`;
select `reqId` into `rid` from `employee` where `empId`=`employeeId`;
insert into `requests` values(rid,reqType,`ticketId`,NOW(),NOW(),`status`,`details`);
end
Error executing SQL statement. Column 'reqId' cannot be null - Connection: Connection 1: 93ms
If either of the SELECT queries doens't find a matching row, the corresponding variable will be NULL, and you'll get an error when you try to insert it. You need to check for that before doing the INSERT.
But there's no need for separate SELECT queries and variables, use INSERT INTO ... SELECT ...
INSERT INTO requests
SELECT e.reqId, r.requestId, ticketId, NOW(), NOW(), status, details
FROM requesttype AS r
CROSS JOIN employee AS e
WHERE r.request = reqtype
AND e.empId = employeeId
If reqtype or employeeId can't be found, the join won't return any rows, so nothing will be inserted.
It creates a problem because of the same variable name "reqtype" (declare as a procedure parameter) and "reqType" (Declare as procedure variable)
It considers the null value for reqtype and not return any record.
MySQL is case insensitive . Be careful while given variable name.
DELIMITER $$
create procedure `putrequest`(in `employeeId` varchar(50),in `rtype`
varchar(50),in `ticketId` varchar(15),in `status` varchar(15),in `details`
varchar(100))
begin
declare `rid` int;
declare `reqType` int;
select `reqId` into `rid` from `employee` where `empId`=`employeeId`;
select `requestId` into `reqType` from requesttype where `request`=`rtype`;
insert into `requests` values(rid,reqType,`ticketId`,NOW(),NOW(),`status`,`details`);
end$$
DELIMITER ;
DEMO

#1064 - You have an error in your SQL syntax

I already have a table employee with columns name(String),id(int),age(int).
I can't figure out where the syntax is wrong?
CREATE PROCEDURE recins (
name1 IN employee.name%type ,
id1 IN employee.id%type ,
age1 IN employee.age%type
) AS
BEGIN
INSERT INTO employee VALUES(name1,id1,age1);
END;
create table employee2
(
name varchar(100) not null,
id int not null,
age int not null
);
DELIMITER $$
CREATE PROCEDURE recins (
IN name1 varchar(100),
IN id1 int,
IN age1 int
)
BEGIN
INSERT INTO employee2 (name,id,age) VALUES(name1,id1,age1);
END $$
DELIMITER ;
-- test:
call recins('a',1,2);
delimiter is a special wrapper for stored procs, events, functions. Delimiter ; at the end of the stored proc sets it back to the normal/default delimiter of a semi-colon.
The above was tested.

Oracle function for auto increment using in procedure

I have table name render and i create a procedure for it.
My table is
CREATE TABLE ROOM(
ROOM_ID NUMBER(10) NOT NULL,
ROOM_NO NUMBER(10) NOT NULL,
ROOM_DETAILS VARCHAR2(100) NOT NULL,
PRICE NUMBER(30) NOT NULL,
ROOM_PACKAGE VARCHAR2(100) NOT NULL
);
And procedure is
CREATE OR REPLACE PROCEDURE P_ROOM(
p_room_id IN ROOM.ROOM_ID%TYPE,
p_room_no IN ROOM.ROOM_NO%TYPE,
p_room_details IN ROOM.ROOM_DETAILS%TYPE,
p_price IN ROOM.PRICE%TYPE,
p_room_package IN ROOM.ROOM_PACKAGE%TYPE)
IS
BEGIN
INSERT INTO ROOM("ROOM_ID","ROOM_NO","ROOM_DETAILS","PRICE","ROOM_PACKAGE")
VALUES(p_room_id,p_room_no,p_room_details,p_price,p_room_package);
COMMIT;
END;
/
But i want to make a function which will call in procedure and will use to increment ROOM_ID. How i create a function for doing this?
I am trying to create a function but really i can`t
CREATE OR REPLACE FUNCTION AUTO_GEN
ID IN ROOM.ROOM_ID%TYPE
RETURN NUMBER
BEGIN
F_ID NUMBER(5);
F_ID=SELECT MAX(ROOM_ID) FROM ROOM;
IF(ROOM_ID NULL) THEN
ID=0;
ELSE
ID=ROOM_ID+1;
END IF;
RETURN ID;
END;
/

MySQL Select into Multiple Variables Doesn't Work

delimiter //
drop function if exists get_rating;
create function get_rating(id tinyint(1) unsigned)
returns tinyint(1)
begin
declare rating int unsigned;
declare rating_count int unsigned;
select sum(rating), count(rating)
into rating, rating_count
from comments
where review_id = id;
return rating_count;
end //
delimiter ;
When I call the function, neither rating nor rating_count returns the right value (3) they both return 0 when it should be adding three fields with values of 1. Any ideas why this doesn't work?
There would be ambiguity on names of columns and local variables when they match by name.
You declared rating as variable but counting on a field with same name rating and assigning to again rating. It was causing an ambiguity.
Maintain them different.
Change your code as below:
delimiter //
drop function if exists get_rating //
create function
get_rating( _id tinyint(1) unsigned )
returns tinyint(1)
begin
declare _rating int unsigned;
declare _rating_count int unsigned;
select sum(rating), count(rating)
into _rating, _rating_count
from comments
where review_id = _id;
return _rating_count;
end;
//
delimiter ;