Trying to get Count single value from mysql stored procedure - mysql

I am trying to do a count in a mysql stored procedure but cant get the syntax right help1
delimiter//
create procedure get_count_workmen_type(
IN employee_payroll int,
OUT mycount int
)
begin
SELECT count(*) into mycount from workman
where employee_payroll = employee_payroll
end //
delimiter;

You should prefix your parameter names (personally I use "p_") to differentiate them from column names, etc. For example where employee_payroll = employee_payroll will always be true because it's comparing the column to itself.
Also you should add a semi-colon to the end of your select statement.
Putting those two changes together gives you something like this:
delimiter //
create procedure get_count_workmen_type(
IN p_employee_payroll int,
OUT p_mycount int
)
begin
SELECT count(*)
into p_mycount
from workman
where employee_payroll = p_employee_payroll;
end //
delimiter ;

Related

Ask how to pass in a parameter that returns the value of 2 columns in a table in the mysql function

DELIMITER $$
CREATE DEFINER=`root`#`localhost` FUNCTION `sumwhere`(`mus_level` INT) RETURNS int(11)
READS SQL DATA
begin
declare tong int;
select sum(us_id) into tong
from members
where us_level = mus_level
group by us_level;
return tong;
end$$
DELIMITER ;
CREATE FUNCTION FUNC_1_MANV
(
#MANV CHAR(10)
)
RETURNS #TABLE TABLE(HOTEN NVARCHAR(30), CHUCVU NVARCHAR(30))
AS
BEGIN
INSERT INTO #TABLE
SELECT TENNV , CHUCVU
FROM NHANVIEN
WHERE MANV=#MANV
RETURN
END
GO
--THỰC THI
SELECT * FROM dbo.FUNC_1_MANV('NV001')
GO
enter image description here
I want to do the same as below code func "FUNC_1_MANV" but using MySQL.
I want to display one more column of mine, like count(us_id) , or the value of a column (us_id) when I have where run on create function MySQL how. I see MySQL only return 1 parameter.

"Delimiter" is not valid at this position, expecting CREATE

I was getting an error of "Delimiter" is not valid at this position, expecting CREATE" as I was writing a stored procedure and couldn't figure out the cause. I think it might be an issue with MySQL workbench possibly, because the following code gives the same error but was copied straight off of this website.
DELIMITER $$
CREATE PROCEDURE GetTotalOrder()
BEGIN
DECLARE totalOrder INT DEFAULT 0;
SELECT COUNT(*)
INTO totalOrder
FROM orders;
SELECT totalOrder;
END$$
DELIMITER ;
Edit: My real stored procedure is:
DELIMITER //
CREATE PROCEDURE GetSimilar(inputdate char(10))
BEGIN
Declare id(tinyint) DEFAULT 0;
Set id := (select t.IdTimelineinfo
From timelineinfo t
WHERE t.Date = inputdate);
SELECT t.Date From timelineinfo t where t.date = inputdate;
SELECT o.Name, o.Race, o.Sex, o.IdOfficer
FROM timelineinfo
JOIN timelineinfo_officer ON timelineinfo.IdTimelineinfo = timelineinfo_officer.IdTimelineinfo
JOIN officers o ON timelineinfo_officer.IdOfficer = o.IdOfficer
WHERE timelineinfo.IdTimelineinfo = id
UNION
SELECT s.IdSubject, s.Name, s.Race, s.Sex
FROM timelineinfo
JOIN timelineinfo_subject ON timelineinfo.IdTimelineinfo = timelineinfo_subject.IdTimelineinfo
JOIN subjects s ON timelineinfo_subject.IdSubject = s.IdSubject
WHERE timelineinfo.IdTimelineinfo = id;
UNION
Select *
From media m
Where (m.IdTimelineinfo = id);
END //
DELIMITER ;
Watch out where you edit the procedure SQL code. There's a dedicated routine object editor (just like there are for tables, triggers, views etc.), which only accept SQL code for their associated object type. Hence they don't need a delimiter and even signal an error if you use one.
On the other hand you can always directly edit SQL code in the SQL IDE code editors, where no such special handling is implemented. In this case you need the delimiter.

SQL Median Value Undeclared Variable

I am trying to create a stored procedure to obtain the median age within a table but am getting an undeclared variable error. My code is:
DELIMITER //
CREATE PROCEDURE MedianAge()
BEGIN
SET #row_count = (SELECT COUNT(*) FROM employee);
SET #median_index = (#row_count/2);
SELECT TIMESTAMPDIFF(YEAR, bdate, CURDATE()) AS age
FROM employee ORDER BY bdate DESC
LIMIT median_index, median_index;
END //
DELIMITER ;
I am receiving the error:
Error Code: 1327. Undeclared variable: median_index
As far as I am aware I have declared the variable correctly and am unsure why the SELECT statement does not work.
You are using user-defined variables (prefixed with #). However, within the stored procedures you should use local variables (with no prefix). These variables have to be declared prior to use. The difference is well explained here.
You would get something like this:
DELIMITER //
CREATE PROCEDURE MedianAge()
BEGIN
DECLARE row_cnt INT unsigned;
DECLARE median_index INT unsigned;
SET row_cnt = (SELECT COUNT(*) FROM employees);
SET median_index = (row_cnt/2);
SELECT TIMESTAMPDIFF(YEAR, bdate, CURDATE()) AS age
FROM employee ORDER BY bdate DESC
LIMIT median_index, median_index;
END //
DELIMITER ;
Also, keep in mind that row_count is a reserved word in MySQL (a function name). It's better to avoid using it as a variable name.

GROUP_CONCAT as input of MySQL function

Is it possible to use a GROUP_CONCAT in a SELECT as the input of a MySQL function? I cannot figure out how to cast the variable it seems. I've tried blob. I've tried text (then using another function to break it up into a result set, here) but I haven't had any success.
I want to use it like this:
SELECT
newCustomerCount(GROUP_CONCAT(DISTINCT items.invoicenumber)) AS new_customers
FROM items;
Here is the function:
DROP FUNCTION IF EXISTS newCustomerCount;
DELIMITER $$
CREATE FUNCTION newCustomerCount(invoicenumbers BLOB)
RETURNS INT
DETERMINISTIC
BEGIN
DECLARE new_customers INT;
SET new_customers = 0;
SELECT
SUM(nc.record) INTO new_customers
FROM (
SELECT
1 AS customer,
(SELECT COUNT(*) FROM person_to_invoice ps2 WHERE person_id = ps1.person_id AND invoice < ps1.invoice) AS previous_invoices
FROM person_to_invoice ps1
WHERE invoice IN(invoicenumbers)
HAVING previous_invoices = 0
) nc;
RETURN new_customers;
END$$
DELIMITER ;
Because Mysql functions do not support dynamic queries, I recommend you re-think your basic strategy to pass in a list of invoice numbers to your function. Instead, you could modify your function to accept a single invoice number and return the number of new customers just for the one invoice number.
Also, there are some optimizations you can make in your query for finding the number of new customers.
DROP FUNCTION IF EXISTS newCustomerCount;
DELIMITER $$
CREATE FUNCTION newCustomerCount(p_invoice INT)
RETURNS INT
DETERMINISTIC
BEGIN
DECLARE new_customers INT;
SET new_customers = 0;
SELECT
COUNT(DISTINCT ps1.person_id) INTO new_customers
FROM
person_to_invoice ps1
WHERE
ps1.invoice = p_invoice
AND NOT EXISTS (
SELECT 1
FROM person_to_invoice ps2
WHERE ps1.person_id = ps2.person_id
AND ps2.invoice < ps1.invoice
);
RETURN new_customers;
END$$
DELIMITER ;
Then you can still get the total number of new customers for a given list of invoice numbers like this:
SELECT
SUM(newCustomerCount(invoice)) as total_new_customers
FROM items
WHERE ...
You could try FIND_IN_SET() instead of IN(). The performance will probably be horrible when passing in a long list of invoice numbers. But it should work.
WHERE FIND_IN_SET(invoice, invoicenumbers)
You are looking in the wrong place.
WHERE invoice IN(invoicenumbers) will not do the desired substitution. Instead you need to use CONCAT to construct the SQL, then prepare and execute it.

How i can use variable from a select to call a stored procedure?

My problem it's this code.
DELIMITER $$
DROP PROCEDURE IF EXISTS agregar_abono$$
CREATE PROCEDURE agregar_abono(IN pid_cliente BIGINT, IN pfecha_abono DATE, IN pmonto_abono FLOAT)
BEGIN
DECLARE #idabono BIGINT;
-- OTHER CODE ...
SELECT id_abono AS idabono FROM abono WHERE fk_cliente = pid_cliente ORDER BY id_abono DESC LIMIT 1;
SELECT CONCAT('>', idabono);
CALL cobrar_abono(pid_cliente, vid_abono);
END $$
The procedure of the two SELECT return:
idabono = 52 --> good! (in the first select)
CONCAT('>', idabono) = null ---> what??
I don't know because don't stored the result in this variable to use in a stored procedure. I use a AS to store the variable.
The header of stored procedure to call is :
CREATE PROCEDURE cobrar_abono(IN pid_cliente BIGINT, IN pid_abono BIGINT)
Are you looking for this?
...
DECLARE idabono BIGINT;
-- OTHER CODE ...
SET idabono = (SELECT id_abono
FROM abono
WHERE fk_cliente = pid_cliente
ORDER BY id_abono DESC
LIMIT 1);
The SELECT statement itself probably can be replaced with
SET idabono = (SELECT MAX(id_abono)
FROM abono
WHERE fk_cliente = pid_cliente);