Returning procedure execution code in MySQL - mysql

I have a stored procedure
CREATE DEFINER=`root`#`localhost` PROCEDURE `GetNotExecutedOrders`(IN contractID INT(11))
BEGIN
SELECT idContract, idOrder, ProductID, Quantity, (SUM(`order`.Quantity))*(product.Price) as 'Total amount'
FROM typography.contract
JOIN typography.`order` ON contract.idContract=`order`.ContractID
JOIN typography.product ON `order`.ProductID=product.idProduct
WHERE idContract=contractID and ExecutionDate IS NULL
GROUP BY idOrder
ORDER BY idOrder;
END
I need to fix it so it returns an execution code <> 0 if there is no contract with such contract ID, and a list of contracts and an execution code = 0 if there is a contract with that contract ID.

Use an OUT parameter for the code. Then use a COUNT(*) query to set it.
CREATE DEFINER=`root`#`localhost` PROCEDURE `GetNotExecutedOrders`(IN contractID INT(11), OUT executionCode INT)
BEGIN
SELECT COUNT(*) > 0 INTO executionCode
FROM typography.contract
JOIN typography.`order` ON contract.idContract=`order`.ContractID
JOIN typography.product ON `order`.ProductID=product.idProduct
WHERE idContract=contractID and ExecutionDate IS NULL;
IF (executionCode)
SELECT idContract, idOrder, ProductID, Quantity, (SUM(`order`.Quantity))*(product.Price) as 'Total amount'
FROM typography.contract
JOIN typography.`order` ON contract.idContract=`order`.ContractID
JOIN typography.product ON `order`.ProductID=product.idProduct
WHERE idContract=contractID and ExecutionDate IS NULL
GROUP BY idOrder
ORDER BY idOrder;
END IF;
END

Related

Fetch all employees if not employee selected from UI else select specific employee data

I want to select all employees if no employee is selected else need data for selected employee.
I have written this query but it is throwing error.
DECLARE #emp_id INT
SET #emp_id=0 -- This will change based on the selected employee from UI
SELECT * FROM employees
WHERE employee_id in (CASE WHEN #emp_id=0 THEN (SELECT employee_id FROM employees) ELSE #emp_id END)
Sample Script for reproducing issue
CREATE TABLE employees (
employee_id INT ,
first_name VARCHAR (20) DEFAULT NULL,
last_name VARCHAR (25) NOT NULL
);
INSERT INTO employees values (1, '1_fname', '1_lname'),(2, '2_fname', '2_lname'),(3, '3_fname', '3_lname'),(4, '4_fname', '4_lname'),(5, '5_fname', '5_lname')
I want to this in single query.
Assuming that you're using prepared statements, you will need to provide the selected employee 2 times - as argument 1 and 2:
SELECT * FROM employees
WHERE CASE WHEN COALESCE(?,0) = 0 THEN TRUE ELSE id = ? END
For single query, we can INNER JOIN with same table to emulate whether employees should shown or not. Using this query will produce desired output.
select e.*
from employees e
inner join (
select employee_id,
case
when #emp_id = 0 then true -- will display all employees
when #emp_id = #emp_id then true -- only display selected employee
else false
end as is_shown
from employees
) filter on e.employee_id = filter.employee_id and filter.is_shown = 1;
Or using another approach
select employee_id, first_name, last_name
from (
select e.*,
case
when #emp_id = 0 then true
when #emp_id = employee_id then true
else false
end as is_shown
from employees e
) employees
where is_shown = 1;
Simple flow control inside stored procedure
delimiter $$
use `precise`$$
drop procedure if exists `GetEmployee`$$
create definer=`user`#`%` procedure `GetEmployee`(empID int)
begin
case when empID = 0 then
select *
from employees;
else
select *
from employees
where employee_id = empID;
end case
;
end$$
delimiter ;

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.

How to convert this PHP/MYSQL call add_order routine to one with less fields?

The textbook version is a call to add order and add the contents of the order from a pre=defined enumeration of non-coffee and coffee products. However I am selling prints, so I don't know how I can properly change the enumeration. Any suggestions?
DELIMITER $$
CREATE PROCEDURE add_order (cid INT, uid CHAR(32), ship INT(10), cc MEDIUMINT, OUT total INT(10), OUT oid INT)
BEGIN
DECLARE subtotal INT(10);
INSERT INTO orders (customer_id, shipping, credit_card_number, order_date) VALUES (cid, ship, cc, NOW());
SELECT LAST_INSERT_ID() INTO oid;
INSERT INTO order_contents (order_id, product_type, product_id, quantity, price_per) SELECT oid, c.product_type, c.product_id, c.quantity, IFNULL(sales.price, ncp.price) FROM carts AS c INNER JOIN non_coffee_products AS ncp ON c.product_id=ncp.id LEFT OUTER JOIN sales ON (sales.product_id=ncp.id AND sales.product_type='goodies' AND ((NOW() BETWEEN sales.start_date AND sales.end_date) OR (NOW() > sales.start_date AND sales.end_date IS NULL)) ) WHERE c.product_type="goodies" AND c.user_session_id=uid UNION SELECT oid, c.product_type, c.product_id, c.quantity, IFNULL(sales.price, sc.price) FROM carts AS c INNER JOIN specific_coffees AS sc ON c.product_id=sc.id LEFT OUTER JOIN sales ON (sales.product_id=sc.id AND sales.product_type='coffee' AND ((NOW() BETWEEN sales.start_date AND sales.end_date) OR (NOW() > sales.start_date AND sales.end_date IS NULL)) ) WHERE c.product_type="coffee" AND c.user_session_id=uid;
SELECT SUM(quantity*price_per) INTO subtotal FROM order_contents WHERE order_id=oid;
UPDATE orders SET total = (subtotal + ship) WHERE id=oid;
SELECT (subtotal + ship) INTO total;
END$$
DELIMITER ;
My fields for the prints (alternate coffee are:
My first successful version is:
BEGIN
DECLARE subtotal INT(10);
INSERT INTO orders (customer_id, shipping, credit_card_number, order_date) VALUES (cid, ship, cc, NOW());
SELECT LAST_INSERT_ID() INTO oid;
END
Here is the table for prints.
I also don't have the carts table in my version so with or without the carts table.

Procedure Limit

I need help please! I tried searching for answers but didn't find anything.
I am using MYSQL6.
What I did is create 2 views and I want to limit these views to get a specific amount of results that is calculated through a function.
FUNCTION:
DELIMITER $$
CREATE FUNCTION `get_total_customers`() RETURNS int(11)
BEGIN
DECLARE TotalCustomers INT;
SELECT (count(customer_id)*0.2) INTO TotalCustomers FROM customer;
RETURN TotalCustomers;
END
VIEW1:
CREATE VIEW PreferredStatus AS
SELECT customer_id, SUM(amount) AS TotalAmount, get_total_customers() AS Total FROM payment
GROUP BY customer_id
ORDER BY TotalAmount DESC;
VIEW2:
CREATE VIEW RegularStatus AS
SELECT customer_id, SUM(amount) AS TotalAmount, get_total_customers() AS Total FROM payment
GROUP BY customer_id
ORDER BY TotalAmount ASC
LIMIT Total;
This is the procedure that would use the view.
> DELIMITER $$
CREATE PROCEDURE `CustomerStatus`(in custID int, out status varchar(200))
BEGIN
declare number1 int;
declare totalvar int;
declare limit2 int;
IF custID in (SELECT customer_id FROM PreferredStatus) THEN
set status = "preferred";
ELSEIF custID in (SELECT customer_id FROM RegularStatus) THEN
set status = "casual";
ELSE
set status = "regular";
End If;
END
HELP PLEASE!
-Thanks.
You can add LIMIT to the SELECT that creates the VIEW:
CREATE VIEW PreferredStatus AS
SELECT customer_id,
SUM(amount) AS TotalAmount,
get_total_customers() AS Total
FROM payment
GROUP BY customer_id
ORDER BY TotalAmount DESC
LIMIT 20;
sqlfiddle demo
A warning from the docs:
If a view definition includes a LIMIT clause, and you select from the
view using a statement that has its own LIMIT clause, it is undefined
which limit applies.

Get total value in stored procedure

While executing this query i always got the concession result as '0' only, totally i got 2 lakh customer data's, but for all customer's i got the concession value as '0' only, what mistake i did in these query?
-- 4. Concession & Other pre-purchases
if (select count(*) FROM tbl_OrderFoodLog where OrderLog_ID in
(select OrderLog_ID from #MemberOrderLog where Member_MailId=#EmailId))>0
if (select count(*) from #CustTrans where OrderLog_IsFoodOrder='Y')>0
begin
select #Concession=(select SUM( FoodLog_Total) FROM tbl_OrderFoodLog where OrderLog_ID --in ( select OrderLog_ID from #MemberOrderLog where Member_MailId=#EmailId))/
--(select -COUNT(*) from #MemberOrderLog where Member_MailId=#EmailId)
select #FoodAmount=cast(SUM( FoodLog_Total) as float) FROM tbl_OrderFoodLog where OrderLog_ID in ( select OrderLog_ID from #CustTrans where OrderLog_IsFoodOrder='Y')
select #Concession=(#FoodAmount)/#Frequency
end
else
begin
select #Concession=0.00
end
Thanks in Advance