Is it possible to use a procedure inside a function? For example, I would like to gather all my rows related to an id but I would also like to count the rows and use it in a select statement. This is not working:
drop procedure if exists relatives;
create procedure relatives(in parent int(11),out counted int(11))
begin
set counted=(select count(*) from category where related=parent);
end;
drop function if exists relatives_count;
create function relatives_count(parent parent(11)) returns int(11)
begin
declare count int(11);
call relatives(parent,counted);
return counted;
end;
So that I can use the count
select relatives_count(id) from category
This is just for curiosity purposes. It may look senseless since I can just call a single select query and get the same results but I want to know how I can use my procedure out variable in a function.
Yes, a MySQL FUNCTION can call a MySQL PROCEDURE.
But... the operations the procedure performs will be limited to the operations allowed by a function. (We can't use a procedure to workaround the limitations placed on a function.)
"is not working" is so nebulously vague as to be practically useless in debugging the issue. What exact behavior is being observed?
My suspicion is that the SQL statements shown are failing, because there is no override for the default statement delimiter.
Also, parent(11) is not a valid datatype.
Be aware that when an identifier for a column in a SQL statement in a MySQL stored program matches an identifier used for an argument or local variable, MySQL follows a rule about which (the column name or the variable) that is being referenced.
Best practice is to adopt a naming convention for arguments and local variables that do not match column names, and to qualify all column references with a table name or table alias.
Personally, I use a prefix for arguments and local variables (a for argument, l for local, followed by a datatype i for integer, d for date/datetime, n for decimal, ...
DELIMITER $$
DROP PROCEDURE IF EXISTS relatives$$
CREATE PROCEDURE relatives(IN ai_parent INT(11),OUT ai_counted INT(11))
BEGIN
SELECT COUNT(*)
INTO ai_counted
FROM category c
WHERE c.related = ai_parent
;
END$$
DROP FUNCTION IF EXISTS relatives_count$$
CREATE FUNCTION relatives_count(ai_parent INT(11))
RETURNS INT(11)
BEGIN
DECLARE li_counted INT(11);
CALL relatives(ai_parent,li_counted);
RETURN li_counted;
END$$
DELIMITER ;
Please identify the exact behavior you observe. Error message when creating the procedure? Error message when executing the function? Unexpected behavior. That's much more precise and informative than telling us something "is not working".
Related
I have a stored procedure in MYSQL where I am passing one parameter which is passed into an SQL statement as you can see below however the result is returning a count of 0 where I am expecting a count of 2.
Stored Procedure:
CREATE DEFINER=`admin`#`%` PROCEDURE `EmployeesRecords`(IN employee_id varchar (1000))
BEGIN
--
declare v_count int ;
--
select count(*)
into v_count
from employees
where employees_id IN (employee_id);
--
END
One or many employee Id's can be passed into the parameter employee_id.
when Calling Stored Procedure like this : CALL EmployeesRecords('2,3'); This returns a count of 0 where I am expecting a count of 2
As for the parameter itself, I have tried various methods including changing it in the procedure to have it as "IN ('2','3') in the SQL condition however it still does not work.
However what I have noticed is that when passing one employee Id, it works successfully such as CALL EmployeesRecords('2');
Can anyone guide me to what I am doing wrong please?
I'm trying out MySQL procedures for the first time, however I can't figure out how to define the variable #index_ids for the life of me. It really doesn't like the SET.
CREATE PROCEDURE #indextemp
BEGIN
SET #index_ids = (SELECT DISTINCT index_id FROM visibility_index_processing_queue WHERE process_id IS NOT NULL);
SELECT #index_ids;
END
Problem is in CREATE PROCEDURE syntax, not in setting variable. You just have to add parentheses after procedure name. Here's working sample
delimiter $
CREATE PROCEDURE indextemp()
BEGIN
SET #index_ids = (SELECT DISTINCT index_id FROM visibility_index_processing_queue WHERE process_id IS NOT NULL);
SELECT #index_ids;
END$
delimiter ;
Sometimes use of delimiter character in procedure body can cause problems too. That's why I set delimiter to $ before creating procedure and revert it to default ; after I'm done.
Also notice that I have removed # from your procedure name. In sql # is used to insert comments. If for some reason you really want to use it in your name you have to do it like that
CREATE PROCEDURE `#indextemp`()
I try to understand how functions work. I can make the equivalent in procedure but I can't create a simple function with select.
element is UNIQUE and
thing is PRIMARY
CREATE DEFINER=`root`#`localhost`
FUNCTION `get_element_by_thing`(`thing` VARCHAR(255))
RETURNS VARCHAR(255)
CHARSET utf8
NOT DETERMINISTIC
READS SQL DATA
SQL SECURITY DEFINER
DECLARE #return_element VARCHAR(255);
SET #return_element = (
SELECT
`element`
FROM
`table1`
WHERE
`thing` = thing
);
RETURN #return_element;
I use the phpmyadmin interface.
1) Don't declare user-defined variables.
The name of a local variable in MySQL stored program does not start with an at sign #. As an example:
DECLARE stored_program_local_variable VARCHAR(255);
SET stored_program_local_variable = 'somevalue';
The name of a user-defined variables start with an at sign #. (The at sign character is what distinguishes user-defined variables from other identifiers.) It's not valid to declare a user-defined variable in a stored program. To create a user-defined variable, just assign a value to it. For example:
SET #user_defined_variable = 'somevalue';
2) If we don't need to persist variables beyond the scope of a stored program, we typically use local variables, which exist only for the duration of the stored program execution. (Which is different behavior than user-defined variables which are at the session level.)
3) Use the SELECT ... INTO syntax to retrieve scalar values into user-defined or local variables. https://dev.mysql.com/doc/refman/5.7/en/select-into.html
Try:
DELIMITER $$
CREATE DEFINER=`root`#`localhost`
FUNCTION `get_element_by_thing`(`thing` VARCHAR(255))
RETURNS VARCHAR(255)
...
BEGIN
DECLARE return_element VARCHAR(255) ;
SELECT t1.element
INTO return_element
FROM table1 t1
WHERE t1.thing = thing
LIMIT 1 ;
RETURN return_element ;
END $$
DELIMITER ;
Note: with ambiguous identifiers (i.e. routine parameter and column with the same name in a SQL statement, the routine parameter takes precedence over the column name. Qualify the column reference with the table name or table alias so it's not ambiguous. I prefer to assign routine parameters (and local variables) names that do not match column names.
If for some reason you need to assign a value to a user-defined variable in a SQL statement, you can use the := assignment operator. This is also valid outside the context of a stored program.
SELECT #user_defined_variable := t.somecolumn
FROM mytable t
WHERE somecondition
ORDER BY someexpression
LIMIT 1
I am learning to write MySQL stored procedures and I have encountered some difficulties. Here I have two stored procedures:
First stored procedure:
CREATE PROCEDURE sp1 (IN `username` TEXT, OUT `user_id` INT)
BEGIN
DECLARE rowcount INT;
SELECT count(`User ID`) INTO rowcount FROM user WHERE `Username`=username;
SET user_id = rowcount;
END|
Second stored procedure:
CREATE PROCEDURE sp2 (IN `doc_id` INT, IN `content` LONGTEXT)
BEGIN
UPDATE doc SET `Content`=content WHERE `Doc ID`=doc_id;
END|
(Delimiter is |.)
Question:
I observe that the result of the first stored procedure is the same as calling SELECT count(`User ID`) FROM user;. However, the second stored procedure does its job and gets the content updated with the new content.
So why does the first stored procedure treat `Username` and username as equal identifiers but the second stored procedure treats `Content` and content as different identifiers? The two identifiers in both cases are the same except the capitalization of the first letter.
I figure it out after reading the official MySQL documentation about the scope of local variables.
It states that:
A local variable should not have the same name as a table column. If an SQL statement, such as a SELECT ... INTO statement, contains a reference to a column and a declared local variable with the same name, MySQL currently interprets the reference as the name of a variable.
I am writing a stored procedure in mysql which simply returns the row with ID provided or return all table when no ID is provided.
CREATE DEFINER=`root`#`localhost` PROCEDURE `SLICE_GET`(`slice_id` int)
BEGIN
SELECT *
FROM `thesis_db`.`SLICE_INFO`
WHERE (SLICE_ID = `slice_id` OR `slice_id` IS NULL);
END
I have used the same idea in ms-sql for years yet it doesn't seem to work for mysql since no matter which ID is passed, the procedure returns entire table.
What am I missing here ?
This is a way to write procedures in mysql
DELIMITER $$
CREATE PROCEDURE `name of procedure` (x CHAR(1), D1 DATE, D2 DATE)
BEGIN
SELECT name of columns you want to display
FROM table name
WHERE SLICE_ID= x
OR SLICE_ID IS NULL;
END
$$
Note: Moreover mysql is not case sensitive means all caps or all small will not effect it.
delimiter is used to:
If you use the mysql client program to define a stored program containing semicolon characters, a problem arises.
By default, mysql itself recognizes the semicolon as a statement delimiter, so you must redefine the delimiter temporarily to cause mysql to pass the entire stored program definition to the server.