Stored Procedure in mySQL workbench (INSERT INTO error) - mysql

I'm running into an error in my stored procedure, and after numerous YT videos and forums, I still have no clue where I'm going wrong. Given what I'm trying to do, it all seems to look correct.
Here's the deal. I take in some information to buy some stock, I use an IF to make sure that I have enough money to make the purchase, I then insert the purchase information into my TRADES table and update the cash balance in ACCOUNTS to reflect the spending of $$.
I can't even test to see if it works correctly because it won't run. The only error I'm getting is at INSERT INTO, in which it says error: INTO (into) is not valid input at this position
I have done ALL of my insert statements the exact same way, and have no idea why this particular syntax is incorrect? Any help would be greatly appreciated! Below are two approaches, both with errors.
CREATE PROCEDURE `BUY` (TID INT,ID INT, CASH INT, T_NAME VARCHAR(4) ,
TCOUNT INT, TBUYDATE DATE, TBUYPRICE INT )
BEGIN
IF (ACCOUNT.CASH_BALANCE >= (TCOUNT * TBUYPRICE),
INSERT INTO TRADES (TRADE_ID, ACCOUNT_ID, TRADE_NAME, TRADE_COUNT, TRADE_BUYDATE, TRADE_BUYPRICE)
VALUES (TID, ID, T_NAME, TCOUNT, TBUYDATE, TBUYPRICE)
AND UPDATE ACCOUNT.CASH_BALANCE
WHERE ACCOUNT.ACCOUNT_ID = ID
SET ACCOUNT.CASH_BALANCE = (ACCOUNT.CASH_BALANCE - (TCOUNT * TBUYPRICE)),
NULL
)
END
I have also tried the following, however I get an error on END missing subclause or other elements before end
CREATE PROCEDURE `BUY` (TID INT,ID INT, CASH INT, T_NAME VARCHAR(4) , TCOUNT
INT, TBUYDATE DATE, TBUYPRICE INT )
BEGIN
IF (ACCOUNT.CASH_BALANCE >= (TCOUNT * TBUYPRICE))
THEN
INSERT INTO TRADES (TRADE_ID, ACCOUNT_ID, TRADE_NAME, TRADE_COUNT,
TRADE_BUYDATE, TRADE_BUYPRICE)
VALUES (TID, ID, T_NAME, TCOUNT, TBUYDATE, TBUYPRICE);
UPDATE ACCOUNT.CASH_BALANCE
SET ACCOUNT.CASH_BALANCE = (ACCOUNT.CASH_BALANCE - (TCOUNT * TBUYPRICE))
WHERE ACCOUNT.ACCOUNT_ID = ID;
ELSE #noinsert
END

There are multiple errors/corrections:
The Delimiter command was not used, so he gets confused on the end of statement and the end of the procedure definition
The account table needs to be selected in an exists statement
I've used a local variable l_cash instead of repeating TCOUNT * TBUYPRICE (Not an error).
The ELSE statement was not necessary and an END IF; was missing.
Update statement corrected.
Here is the corrected code:
DELIMITER $$
CREATE PROCEDURE `BUY` (TID INT,ID INT, CASH INT, T_NAME VARCHAR(4) , TCOUNT
INT, TBUYDATE DATE, TBUYPRICE INT)
BEGIN
DECLARE l_cash INT DEFAULT 0;
SET l_cash = TCOUNT * TBUYPRICE;
IF EXISTS(SELECT 1 FROM Account WHERE ACCOUNT_ID = ID AND CASH_BALANCE >= l_cash) THEN
INSERT INTO TRADES (TRADE_ID, ACCOUNT_ID, TRADE_NAME, TRADE_COUNT,
TRADE_BUYDATE, TRADE_BUYPRICE)
VALUES (TID, ID, T_NAME, TCOUNT, TBUYDATE, TBUYPRICE);
UPDATE ACCOUNT
SET CASH_BALANCE = (CASH_BALANCE - l_cash)
WHERE ACCOUNT_ID = ID;
END IF;
END$$
DELIMITER ;

Related

Updating a table entry tells me the table does not exist in a procedure

I'm trying to create a stored procedure that attempts to update an order if the stock is sufficient, however when the update is attempted (but only if it is done within the procedure) I'm given the error
"
15:20:05 call plswork(#LatestOrder, 2, 20) Error Code: 1109. Unknown table 'Product' in field list 0.000 sec
"
So far I've attempted to see if there are any mistakes in table names and table keys. I've also tried to do the update outside of the procedure, here it works.
Delimiter ¤
create procedure plswork(
in NewOrder INT,
in ProductID INT,
in PurchaseQuantity INT)
begin
start transaction;
insert into Order_items(Oid, Pid, Quantity)
values (NewOrder, ProductID, PurchaseQuantity);
update Product p
set p.Stock = p.Stock - PurchaseQuantity
where p.Pid = p.ProductID;
if((select Product.Stock
where Pid = ProductID) < 0) then
rollback;
else
commit;
end if;
end ¤
Delimiter ;
INSERT INTO Orders(Cid,Order_date, Order_status)
VALUES (1, '2040-01-31 12:11:00' , "SENT");
select #LatestOrder := max(Oid)
from Orders;
call plswork(#LatestOrder, 2, 20);
What can I do to fix my issue?
I don't think the error is from the UPDATE statement.
I think the error is being thrown with this SQL statement:
select Product.Stock where Pid = ProductID
There's no FROM clause, so qualifying Stock with table name Product is not valid.

MySQL stored procedure if statement not working

I have the following stored procedure in MySQL
CREATE DEFINER=`test_db`#`%` PROCEDURE `ADD_ATTENDANCE`(IN `programID` INT, IN `clientID` INT, IN `insDate` DATETIME, IN `updDate` DATETIME, IN `insUser` INT, IN `updUser` INT, IN `lessonDate` DATE, IN `lessonTime` TIME)
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT 'Add attedance to my calendar'
BEGIN
DECLARE max_sub, availability INT;
DECLARE cursor_max_sub CURSOR FOR SELECT max_sub FROM app_lesson WHERE id = programID;
DECLARE cursor_availability CURSOR FOR SELECT count(*) FROM attendance WHERE program_id = programID AND lesson_date = lessonDate AND lesson_time = lessonTime;
OPEN cursor_max_sub;
OPEN cursor_availability;
read_loop: LOOP
FETCH cursor_max_sub INTO max_sub;
FETCH cursor_availability INTO availability;
IF (availability < max_sub) THEN
insert into attendance (program_id, client_id, ins_date, upd_date, ins_user, upd_user, lesson_date, lesson_time)
values (programID, clientID, insDate, updDate, insUser, updUser, lessonDate, lessonTime);
LEAVE read_loop;
ELSE
insert into attendance_hold (program_id, client_id, ins_date, upd_date, ins_user, upd_user, lesson_date, lesson_time)
values (programID, clientID, insDate, updDate, insUser, updUser, lessonDate, lessonTime);
END IF;
END LOOP;
CLOSE cursor_max_sub;
CLOSE cursor_availability;
END;
Even though the cursor_max_sub is equal to 6 and the cursor_availability is equal to 4 my procedure always executes the else insert statement. Can you please help me out?
Thanks!!!
OK that was tricky... For some reason when i change the max_sub variable into maxNumberOfSubscription everything worked perfectly... Is max_sub some kind of reserved key word for MySQL or there was a complication because my variable had the same name with the returned field of select statement?

mysql stored procedure checking if record exists

I created the following stored procedure:
CREATE DEFINER=`root`#`localhost` PROCEDURE `add_summit`(IN `assoc_code` CHAR(5), IN `assoc_name` CHAR(50), IN `reg_code` CHAR(2), IN `reg_name` CHAR(100), IN `code` CHAR(20), IN `name` CHAR(100), IN `sota_id` CHAR(5), IN `altitude_m` SMALLINT(5), IN `altitude_ft` SMALLINT(5), IN `longitude` DECIMAL(10,4), IN `latitude` DECIMAL(10,4), IN `points` TINYINT(3), IN `bonus_points` TINYINT(3), IN `valid_from` DATE, IN `valid_to` DATE)
BEGIN
declare assoc_id SMALLINT(5);
declare region_id SMALLINT(5);
declare summit_id MEDIUMINT(8);
-- ASSOCIATION check if an association with the given code and name already exists
SELECT id INTO assoc_id FROM association WHERE code = assoc_code LIMIT 1;
IF (assoc_id IS NULL) THEN
INSERT INTO association(code, name) VALUES (assoc_code, assoc_name);
set assoc_id = (select last_insert_id());
END IF;
-- REGION check if a region with the given code and name already exists
SET region_id = (SELECT id FROM region WHERE code = reg_code AND name = reg_name AND association_id = assoc_id);
IF (region_id IS NULL) THEN
INSERT INTO region(association_id, code, name) VALUES (assoc_id, reg_code, reg_name);
set region_id = (select last_insert_id());
END IF;
-- SUMMIT check if a summit with given parameters already exists
SET summit_id = (SELECT id FROM summit WHERE association_id = assoc_id AND region_id = region_id);
IF (summit_id IS NULL) THEN
INSERT INTO summit(code, name, sota_id, association_id, region_id, altitude_m, altitude_ft, longitude,
latitude, points, bonus_points, valid_from, valid_to)
VALUES (code, name, sota_id, assoc_id, region_id, altitude_m, altitude_ft, longitude, latitude,
points, bonus_points, valid_from, valid_to);
END IF;
END$$
basically, it should check if a record exists in some tables and, if it doesn't, it should insert it and use the inserted id (auto increment).
The problem is that even if the record exists (for instance in the association table), assoc_id keeps returning null and that leads to record duplication.
I'm new to stored procedures so I may be doing some stupid errors. I've been trying to debug this SP for hours but I cannot find the problem.
A newbie mistake.
I forgot to specify the table name in the field comparison and that leads to some conflicts with param names (for example the param name).
A good idea is to specify some kind of prefix for parameters (like p_) and always specify the name of the table in the SP.

Stored Procedure Can't drop temp table it don't exist

SQL Server 2008
This is a continuation of my last question. Now I'm trying to create a stored procedure, however I can't execute it. When I execute it, an error message displays
"Cannot drop the table #MyReport", because it does not exist or you do not have permissions.
Please guide me in the right direction.
Below is my stored Procedure
Create PROCEDURE [dbo].[SEL_MyReport]
(
#employeeid int,
#date1 datetime,
#date2 datetime
)
AS
BEGIN
drop table #MyReport
Create Table #MyReport
(
employeeid int,
name varchar(30),
department varchar(30),
checkTime datetime
)
if (#employeeid > 0)
Begin
INSERT INTO #MyReport (employeeid,name, department, checkTime)
select emp.EmpolyeeID, emp.Name,dep.DeptName,tm.checkTime
from TimeInOut tm
left join Employee emp on emp.EmpolyeeId = tm.EmployeeId
left join Department dep on dep.DeptID = emp.defaultDeptID
where (DATEDIFF(s,#date1,tm.checktime) >=0
and DATEDIFF(s,#date2,tm.checktime)<=0) and emp.employeeID = #employeeid
SELECT
employeeid
,name
,department
,[Time In] = MIN(checkTime)
,[Time Out] = MAX(checkTime)
FROM #MyReport
GROUP BY employeeid,name, department, CAST(checktime AS DATE)
End
Else
Begin
INSERT INTO #MyReport (employeeid,name, department, checkTime)
select emp.EmpolyeeID, emp.Name,dep.DeptName,tm.checkTime
from TimeInOut tm
left join Employee emp on emp.EmpolyeeId = tm.EmployeeId
left join Department dep on dep.DeptID = emp.defaultDeptID
where (DATEDIFF(s,#date1,tm.checktime) >=0
and DATEDIFF(s,#date2,tm.checktime)<=0)
SELECT
employeeid
,name
,department
,[Time In] = MIN(checkTime)
,[Time Out] = MAX(checkTime)
FROM #MyReport
GROUP BY employeeid,name, department, CAST(checktime AS DATE)
End
END
Go
exec SEL_MyReport('639','05/01/2014','05/08/2014')
There is quite a bit I would change - here is the code.
You will notice
branching logic (if #employeeid > 0) has been replaced by a slightly more verbose WHERE clause
no need for #tables as far as I can tell, the SELECT should suffice
Unfortunately, I do not have anything to test against, but you should understand the general impression of it.
Further, your date filtering seemed quite strange, so I assumed you may have meant something else - I could be mistaken. Either way, the way the date filtering is now done is SARGable
CREATE PROCEDURE [dbo].[SEL_MyReport]
(
#employeeid INT,
#date1 DATETIME,
#date2 DATETIME
)
AS
BEGIN
SET NOCOUNT ON;
SELECT emp.EmpolyeeID
,emp.Name
,dep.DeptName
,[Time In] = MIN(tm.checkTime)
,[Time Out] = MAX(tm.checkTime)
FROM TimeInOut tm
LEFT
JOIN Employee emp on emp.EmpolyeeId = tm.EmployeeId
LEFT
JOIN Department dep on dep.DeptID = emp.defaultDeptID
WHERE tm.checktime >= #date1
AND tm.checktime <= #date2
/***********************************************************************************************************
* I've assumed what you may be trying to express, above
* You might also want to look at the BETWEEN() operator, remembering that it is inclusive in its behaviour
* (DATEDIFF(s,#date1,tm.checktime) >=0
* AND DATEDIFF(s,#date2,tm.checktime)<=0)
***********************************************************************************************************/
AND (emp.employeeID = #employeeid OR #employeeid <= 0)
GROUP BY emp.EmpolyeeID, emp.name, dep.department, CAST(tm.checktime AS DATE)
END
GO
Well, since the very first step of your Stored Procedure attempts to drop a table, this will obviously result in an error if that table does not exist.
To work around this, make sure you check whether the table exists, before you drop it:
IF OBJECT_ID('tempdb..#MyReport') IS NOT NULL DROP
TABLE #MyReport

Stored Procedure (mysql) fails with "can't return a result set in the given context"

I'm trying to get this SP to return (leave) if some conditions fails and so forth.
This code validates and it saves the procedure, but when I call the procedure with:
CALL ACH_Deposit(30027616,3300012003,200.00,"USD", "127.0.0.1")
It fails with error: "Procedure can't return a result set in the given context"
Does anyone have any idea on what the error is?
Procedure code:
CREATE DEFINER=`redpass_web_urs`#`%` PROCEDURE `ACH_Deposit`(
IN __Account_ID BIGINT,
IN __To_Bank_Account BIGINT,
IN __Amount DECIMAL(10,2),
IN __Currency CHAR(3),
IN __IP_Address VARCHAR(50)
)
COMMENT 'Makes a ACH deposit'
BEGIN
-- Declare Account Parameters
DECLARE _Account_Status INT;
DECLARE __Transaction_ID INT;
DECLARE _Account_Type INT DEFAULT 0;
DECLARE _Fee INT;
SELECT
Account_Status AS _Account_Status,
Account_Type AS _Account_Type
FROM Account_Users
WHERE Account_ID = __Account_ID;
main: BEGIN
-- Step 1, is account active ?
IF _Account_Status <> 1 THEN
-- Account must be active (not restricted, closed etc)
SELECT Response_Code, Description FROM ResponseCodes WHERE Response_Code = 106;
LEAVE main; -- Here we die..
END IF;
-- Step 2, Calculate the FEE (Loading Funds with ACH)
IF _Account_Type = 1 THEN
-- Personal Account
SET _Fee = (SELECT Fee_Template_Personal_1 FROM Fees WHERE Fee_Type_ID = __Fee_Type_ID);
ELSE
-- Business Account
SET _Fee = (SELECT Fee_Template_Business_1 FROM Fees WHERE Fee_Type_ID = __Fee_Type_ID);
END IF;
-- Step 3, Check that Fee is not bigger then the actual amount
IF _Fee > __Amount THEN
SELECT Response_Code, Description FROM ResponseCodes WHERE Response_Code = 108;
LEAVE main; -- Here we die..
END IF;
-- If we come here, we can make the transactions
INSERT INTO Bank_Transaction
(Bank_Account_ID
,Transaction_Type
,Amount
,IP_Address
,Pending)
VALUES
(__To_Bank_Account
,11
,__Amount
,__IP_Address
,1); -- Reserverade pengar
-- Transaction ID
SET __Transaction_ID = (SELECT LAST_INSERT_ID());
-- Deduct the Fee
INSERT INTO Bank_Transaction
(Bank_Account_ID
,Transaction_Type
,Amount
,Fee_Type_ID
,Fee_Transaction_ID)
VALUES
(__To_Bank_Account
,4
,-__Fee
,21
,__Transaction_ID);
END main;
SELECT Response_Code, Description, __Transaction_ID AS Transaction_ID
FROM ResponseCodes
WHERE Response_Code = 1;
END
To retrieve multiple resultsets from the stored procs, you should use a client which supports multiple queries.
If you use PHP, use MySQLi extension and call the procedure using mysqli_multi_query.
MySQL extension is only able to retrieve the first recordset returned by the proc. To be able to use ti, you should set CLIENT_MULTI_RESULTS (decimal 131072) in the parameter $client_flags to mysql_connect