Storing MySQL query as function - mysql

I'm new to MySQL functions. I Created a function:
CREATE FUNCTION `tems`.`<function_name>`(IN bid INT, IN cid INT)
RETURNS INT(10)
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
DECLARE min_no INT;
SELECT COALESCE(min(number),1)
FROM
(SELECT r1.number -1 AS number, r1.branch_id, r1.course_id
FROM `Room` AS r1
LEFT JOIN `Room` AS r2
ON r1.branch_id = r2.branch_id
AND r1.course_id = r2.course_id
AND (r1.number - 1) = r2.number
WHERE r1.number > 1 AND r2.number IS NULL
UNION ALL
SELECT max(number) + 1, branch_id, course_id
FROM `Room`
GROUP BY branch_id, course_id) AS q
WHERE branch_id=bid AND course_id=cid
GROUP BY branch_id, course_id
INTO min_no;
RETURN (min_no);
END;
And I want to get bid, cid and return the select value, but I'm getting an error message:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IN bid INT, IN cid INT)
RETURNS INT(10)
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS ' at line 1
What am I doing wrong?

Use a DELIMITER like below along with removing the two part identifier. Just declare the function name.
DELIMITER $$
CREATE FUNCTION MyTestFunc (bid INT, cid INT)
RETURNS INT(10)
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
DECLARE min_no INT;
SELECT COALESCE(min(number),1)
FROM
(SELECT r1.number -1 AS number, r1.branch_id, r1.course_id
FROM `Room` AS r1
LEFT JOIN `Room` AS r2
ON r1.branch_id = r2.branch_id
AND r1.course_id = r2.course_id
AND (r1.number - 1) = r2.number
WHERE r1.number > 1 AND r2.number IS NULL
UNION ALL
SELECT max(number) + 1, branch_id, course_id
FROM `Room`
GROUP BY branch_id, course_id) AS q
WHERE branch_id=bid AND course_id=cid
GROUP BY branch_id, course_id
INTO min_no;
RETURN (min_no);
END$$
DELIMITER ;

Related

Selecting all if value is zero else select with condition mysql stored procdure

I have a stored procedure like below
CREATE DEFINER=`root`#`localhost`
PROCEDURE `sp_srch_all`( IN `content_per_page` int,
IN `start` int,
IN `ag1`int,
IN `ag2` int,
IN `ht1` int,
IN `ht2` int,
IN `ms` varchar(20),
IN `rel` int,
IN `edu` varchar(30),
IN `gen` varchar(30),
IN `cas` varchar(20))
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
SET #err = edu;
ROLLBACK;
END;
SELECT a.*,b.*,c.*,d.*,e.*
FROM tbl_regisatration a
LEFT JOIN tbl_caste b on b.cst_id = a.caste
LEFT JOIN tbl_religion c on c.rel_id = a.religion
LEFT JOIN tbl_height d on d.he_id = a.height
LEFT JOIN tbl_profiles_for e on e.prof_id = a.profile_for
where a.prof_status=0
and a.gender=gen
and a.religion=rel
and DATEDIFF(CURRENT_DATE, a.dob) >= (ag1 * 365.25)
AND DATEDIFF(CURRENT_DATE, a.dob) <= (ag2 * 365.25)
and ((a.height >= ht1)
AND (a.height <= ht2))
and a.marital_status=ms
and FIND_IN_SET(a.education,#err)
and FIND_IN_SET(a.caste,cas)
order by a.prof_cat desc LIMIT content_per_page OFFSET start;
END
I want to ignore conditions like a.religion=rel ,FIND_IN_SET(a.education,#err).. if its corresponding values are null else if not null check these conditions

ERROR 1172 (42000): Result consisted of more than one row on mysql stored procedure

I am getting ERROR 1172 (42000): Result consisted of more than one row on my stored procedure when I use CALL submitOrder( 10, 100, 1, #OrderId);
What went wrong in my code? The goal is to use the procedure to insert a new row into the orders table and a new row on the order details into order_items table.
DELIMITER //
CREATE PROCEDURE submitOrder(
IN customerId INT,
IN productId INT,
IN qty INT,
OUT orderId INT)
BEGIN
DECLARE orderId, storeId, staffId, qty, customerId, productId INT;
DECLARE listPrice DECIMAL(10,2);
DECLARE discount DECIMAL(4,2);
SELECT MAX(order_id)+1 FROM orders INTO #orderId;
SELECT s.store_id
FROM stocks AS s
INNER JOIN products AS p USING (product_id)
WHERE p.product_id = s.product_id
ORDER BY s.quantity DESC
LIMIT 1
INTO #storeId;
SELECT staffs.staff_id
FROM staffs
INNER JOIN stores
WHERE staffs.store_id = stores.store_id
LIMIT 1
INTO #staffID;
SET #qty = 1;
SELECT products.product_id
FROM products
WHERE products.product_id = productId;
SELECT products.list_price
FROM products
INTO #listPrice;
INSERT INTO orders VALUES (
#orderId, #customerId, 1, CURDATE(), ADDDATE(CURDATE(), INTERVAL 7 day), NULL, #storeId, #staffId);
INSERT INTO order_items
VALUES (#orderId, 1, #productId, #qty, #listPrice,0);
END//
DELIMITER ;
You forgot to put a WHERE clause and LIMIT 1 into the query that sets $listPrice. You also forgot to set #productId anywhere.
You can do both of these in the same query.
SELECT product_id, list_price
FROM products
WHERE product_id = productId
LIMIT 1
INTO #productId, #listPrice;
I'm not sure why you need the #product_id variable, since it will be the same as productId.

Incorrect syntax near 'INSERT' and 'WHERE'

I can't figure out what's wrong with my stored procedure.
CREATE PROCEDURE duplicatecheck2
#QmemberID INT,
#InputDate DATE
AS
INSERT INTO tbl_availableMembers
SELECT memberId
FROM tbl_attendancesheet
WHERE MemberId = #QmemberId
AND [date] = #InputDate
AND [clockin] IS NOT NULL
AND [clockout] IS NULL
UNION
INSERT INTO tbl_availableMembers
SELECT memberId
FROM tbl_attendancemembers
WHERE memberId NOT IN (SELECT memberId
FROM tbl_attendanceSheet)
WHERE date = #InputDate)
I get these errors:
Msg 156, Level 15, State 1, Procedure duplicatecheck2, Line 14
Incorrect syntax near the keyword 'Insert'.
Msg 156, Level 15, State 1, Procedure duplicatecheck2, Line 18
Incorrect syntax near the keyword 'WHERE'.
My other stored procedure that union has worked in it:
CREATE PROCEDURE duplicateCheck
#inputdate DATE
AS
BEGIN
DELETE FROM tbl_availableMembers
INSERT INTO tbl_availableMembers
SELECT memberId
FROM tbl_attendancemembers
WHERE memberId NOT IN (SELECT memberId FROM tbl_attendanceSheet)
UNION
SELECT memberId
FROM tbl_attendancemembers
WHERE memberId IN (SELECT memberId
FROM tbl_attendanceSheet
GROUP BY memberId, date
HAVING COUNT(*) <= 1 AND date = #inputdate)
END
Get rid of the "UNION". The stored procedure can just run two insert statements.
Noel
You cannot apply the UNION to two INSERT statements (as in your first code snippet) - but you can apply it to two SELECT statements (as in your second code sample)
By #marc_s

#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use

I keep getting this error when trying to Run SQL query/queries on database weeki. I searched everywhere for a solution but I was just unlucky.
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 5
I am trying to add this to my databases
CREATE FUNCTION weeki.CreateGroup(GroupName VARCHAR(50), GroupIcon TEXT, GroupDescription VARCHAR(130), GroupCreator INT)
RETURNS int(11)
DETERMINISTIC
BEGIN
DECLARE groupID INT;
INSERT INTO groups (name, icon, description) VALUES (GroupName, GroupIcon, GroupDescription);
SET groupID = LAST_INSERT_ID();
INSERT INTO group_members VALUES (groupID, GroupCreator);
RETURN groupID;
END;
CREATE FUNCTION weeki.AddMessage(r VARCHAR(255), s INT, t INT, m VARCHAR(255), creation DATETIME)
RETURNS int(11)
DETERMINISTIC
BEGIN
DECLARE lastID INT;
DECLARE receiver INT;
SELECT id INTO receiver from users WHERE username=r;
INSERT INTO messages (receiver_id, sender_id, msg_type, message, created_At) values(receiver, s, t, m, creation);
SET lastID = LAST_INSERT_ID();
INSERT INTO messages_receipt (message_id, user_id, is_delivered) VALUES (lastID, receiver, 0);
RETURN lastID;
END;
CREATE FUNCTION weeki.AddGroupMessage(gid INT, s INT, t INT, m VARCHAR(255), creation DATETIME)
RETURNS int(11)
DETERMINISTIC
BEGIN
DECLARE lastID INT; DECLARE rowCount INT;
SELECT COUNT(*) INTO rowCount FROM group_members WHERE user_id = s AND group_id = gid;
IF rowCount = 1 THEN
INSERT INTO group_messages (group_id, user_id, msg_type, message, created_at) VALUES (gid, s, t, m, creation);
SET lastID = LAST_INSERT_ID();
INSERT INTO group_receipt (message_id, user_id, is_delivered) SELECT gm.message_id, gmembers.user_id, 0 FROM
group_messages gm LEFT JOIN group_members gmembers ON gmembers.group_id = gm.group_id WHERE gm.group_id = gid AND gm.message_id = lastID AND NOT gmembers.user_id = s;
RETURN lastID;
ELSE
return 0;
END IF;
END;
CREATE DEFINER = 'abdal'#'localhost'
FUNCTION weeki.AddGroupMember(GroupID INT, MemberName VARCHAR(255), Username INT)
RETURNS int(11)
BEGIN
INSERT INTO group_members VALUES (GroupID, MemberName);
RETURN 1;
END;
Anyone have any ideas on how to fix this? I appreciate all the answers.
What #GordonLinoff said!
DELIMITER ##
CREATE FUNCTION weeki.CreateGroup(GroupName VARCHAR(50), GroupIcon TEXT, GroupDescription VARCHAR(130), GroupCreator INT)
RETURNS int(11)
DETERMINISTIC
BEGIN
DECLARE groupID INT;
INSERT INTO groups (name, icon, description) VALUES (GroupName, GroupIcon, GroupDescription);
SET groupID = LAST_INSERT_ID();
INSERT INTO group_members VALUES (groupID, GroupCreator);
RETURN groupID;
END##
CREATE FUNCTION weeki.AddMessage(r VARCHAR(255), s INT, t INT, m VARCHAR(255), creation DATETIME)
RETURNS int(11)
DETERMINISTIC
BEGIN
DECLARE lastID INT;
DECLARE receiver INT;
SELECT id INTO receiver from users WHERE username=r;
INSERT INTO messages (receiver_id, sender_id, msg_type, message, created_At) values(receiver, s, t, m, creation);
SET lastID = LAST_INSERT_ID();
INSERT INTO messages_receipt (message_id, user_id, is_delivered) VALUES (lastID, receiver, 0);
RETURN lastID;
END##
CREATE FUNCTION weeki.AddGroupMessage(gid INT, s INT, t INT, m VARCHAR(255), creation DATETIME)
RETURNS int(11)
DETERMINISTIC
BEGIN
DECLARE lastID INT; DECLARE rowCount INT;
SELECT COUNT(*) INTO rowCount FROM group_members WHERE user_id = s AND group_id = gid;
IF rowCount = 1 THEN
INSERT INTO group_messages (group_id, user_id, msg_type, message, created_at) VALUES (gid, s, t, m, creation);
SET lastID = LAST_INSERT_ID();
INSERT INTO group_receipt (message_id, user_id, is_delivered) SELECT gm.message_id, gmembers.user_id, 0 FROM
group_messages gm LEFT JOIN group_members gmembers ON gmembers.group_id = gm.group_id WHERE gm.group_id = gid AND gm.message_id = lastID AND NOT gmembers.user_id = s;
RETURN lastID;
ELSE
return 0;
END IF;
END##
CREATE DEFINER = 'abdal'#'localhost'
FUNCTION weeki.AddGroupMember(GroupID INT, MemberName VARCHAR(255), Username INT)
RETURNS int(11)
BEGIN
INSERT INTO group_members VALUES (GroupID, MemberName);
RETURN 1;
END##
DELIMITER ;

Rewrite Stored Procedure

I have the next stored procedure which inserts values into 2 tables. To the 2nd table I insert id's of 2 last inserts from 1st table
However, I would like to rewrite it with one query instead of using temp table and while.
CREATE PROCEDURE CurrencyExhange
AS
DECLARE #TmpTable Table
(
ID int IDENTITY(1,1) NOT NULL PRIMARY KEY,
BillID int,
Amount decimal,
Rate decimal,
Date date
)
INSERT INTO #TmpTable
SELECT T.[BillID]
,[Amount]
,CR.Rate
,CR.Date
FROM [FinanceLabkovich].[dbo].[Transactions] T
JOIN [FinanceLabkovich].[dbo].Bills B ON B.BillID = T.BillID
JOIN [FinanceLabkovich].[dbo].Currencies C ON C.CurrencyID=B.CurrencyID
JOIN [FinanceLabkovich].[dbo].CurrencyRates CR ON CR.CurrencyRateID=FinanceLabkovich.dbo.GetRate(T.Date)
WHERE LOWER(C.Name)='usd' AND T.Income=1
ORDER BY T.Date
DECLARE #ToBillID int = (SELECT BillID FROM [FinanceLabkovich].[dbo].Bills B WHERE B.Name='Purse')
DECLARE #i int = (SELECT MIN(Id) FROM #TmpTable)
DECLARE #maxId int = (SELECT MAX(Id) FROM #TmpTable)
DECLARE #TransactionID int, #ToTransactionID int, #Amount decimal
DECLARE #date date
WHILE (#i<=#maxId)
BEGIN
SET #date = (SELECT Date FROM #TmpTable WHERE ID=#i)
SET #Amount = (SELECT AmountUSD FROM [FinanceLabkovich].[dbo].Cashflow WHERE Date=#date)
IF #Amount > 0
BEGIN
INSERT INTO [FinanceLabkovich].[dbo].[Transactions] (Name,BillID,ToBillID,Amount,Date,Income)
SELECT "Name"='Currency exhange'
,BillID
,#ToBillID
,#Amount
,T.Date
,"Income"=0
FROM #TmpTable T
WHERE ID=#i
SET #TransactionID = ##IDENTITY
INSERT INTO [FinanceLabkovich].[dbo].[Transactions] (Name,BillID,ToBillID,Amount,Date,Income)
SELECT "Name"='Currency exhange'
,#ToBillID
,BillID
,#Amount*Rate AS Total
,Date
,"Income"=1
FROM #TmpTable WHERE ID=#i
SET #ToTransactionID = ##IDENTITY
INSERT INTO [FinanceLabkovich].[dbo].[Transfers]
SELECT #TransactionID, #ToTransactionID
END
SET #i += 1
END
Any help appreciated.