Am trying to fetch out a field through stored procedure and I used following query. I aimed at fetching out multiple rows, but it executes the result successfully only when a single row exists. Or else it returns an error as I mentioned below.
MySQL Query
DELIMITER ;;
DROP PROCEDURE IF EXISTS Sample1;;
CREATE PROCEDURE Sample1(IN lft1 INT, IN rgt1 INT, OUT emp1 VARCHAR(20))
BEGIN
SELECT p.emp INTO emp1
FROM personnel p
WHERE p.lft > lft1
AND p.rgt < rgt1
LIMIT 10;
END;;
CALL Sample1(1, 10, #emp);;
SELECT #emp;
Error Message
MySQL said: Documentation
#1172 - Result consisted of more than one row
NOTE
Sample1 - procedure name
emp - selected field from table personnel
lft - use to check the condition, it is also one of the field of table personnel
personnel - table name
The error is not in your procedure. The error is in your query - it returns more then one row, but you cannot set multiple result into scalar value 'emp1'.
You should limit your query so that it returns one row.
How to retreive multiple rows from stored procedure in mysql?
Plan A: Fill another table, it may be a temporary table.
Plan B: Just execute your SELECT statement without INTO clause from the procedure; then you could read data-set from the application (c#, PHP+mysqli,...)
Plan C: Do not use the procedure, just execute the SELECT query.
Just had the same question. After a little research I found a solution in the official MySQL documentation:
Calling Stored Procedures with Statement Objects
It requires MySQL 5.5.3 or higher.
In contrast to the inital stored procedure from #Bala.C it doesn't use an out parameter.
CREATE PROCEDURE get_data ()
BEGIN
SELECT Code, Name, Population, Continent
FROM Country
WHERE Continent = 'Oceania'
AND Population < 10000;
SELECT Code, Name, Population, Continent
FROM Country
WHERE Continent = 'Europe'
AND Population < 10000;
SELECT Code, Name, Population, Continent
FROM Country
WHERE Continent = 'North America'
AND Population < 10000;
END;
You can use a cursor in MySQL.
CREATE PROCEDURE Sample1(IN lft1 INT,IN rgt1 INT, OUT emp1 VARCHAR(20))
BEGIN
DECLARE p_emp INT;
DECLARE cur_emp CURSOR FOR
SELECT p.emp
FROM personnell p
WHERE p.lft > lft1
and p.rgt < rgt1
LIMIT 10;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET noMoreRow = 0;
OPEN cur_emp;
LOOPROWS: LOOP
IF noMoreRow = 0 THEN
CLOSE cur_emp;
LEAVE LOOPROWS;
END IF;
FETCH cur_emp INTO p_emp;
SELECT p_emp;
END LOOP;
END;;
Related
I have this stored procedure
DELIMITER $$
USE `testdb`$$
CREATE DEFINER=`root`#`localhost` PROCEDURE `TestProcedure`(
IN year_number YEAR,
IN month_name VARCHAR(12),
IN input_region VARCHAR(20)
)
BEGIN
DECLARE total_regions_count INT DEFAULT 0;
## Get Distinct Regions.
SELECT
total_regions_count = COUNT(DISTINCT region)
FROM aws_cost AS AC
WHERE AC.year = year_number;
SELECT total_regions_count;
END$$
DELIMITER ;
When I call this stored procedure total_regions_count I get is 0 but when I execute the query directly, I get the correct count of distinct values (Which is 9 and not 0.).
Why is the variable returning me default value of the variable as the result? Why 9 is not getting returned?
I have tried INTO keyword also to set the value but still the same result.
SELECT COUNT(DISTINCT region) INTO total_regions_count ...
It doesn't work properly inside the stored procedure because you're attempting to make a comparison between the value stored in "total_regions_count" (defaulted to 0) and COUNT(DISTINCT region), which is a number bigger than 0. Since the comparison fails, you get the value 0.
Try instead using INTO as follows:
DELIMITER $$
USE `testdb`$$
CREATE DEFINER=`root`#`localhost` PROCEDURE `TestProcedure`(
IN year_number YEAR,
IN month_name VARCHAR(12),
IN input_region VARCHAR(20)
)
BEGIN
DECLARE total_regions_count INT DEFAULT 0;
## Get Distinct Regions.
SELECT COUNT(DISTINCT region) INTO total_regions_count
FROM aws_cost AS AC
WHERE AC.year = year_number;
SELECT total_regions_count;
END$$
DELIMITER ;
In MySQL expressions, = is an equality comparison operator, not an assignment operator.
You could use := if you want to make an assignment in an expression. But this syntax is now discouraged.
The preferred syntax is to use SELECT ... INTO to assign the results of queries to variables:
SELECT
COUNT(DISTINCT region)
FROM aws_cost AS AC
WHERE AC.year = year_number
INTO total_regions_count;
Is it possible that the count of matching rows is in fact zero? You could test this by making the default value of total_regions_count some other value like -1. Then you'll be sure that the value is overwritten by the count computed by your query.
The variable usage is obviously excess. W/o it this SP contains one stmt hence BEGIN-END and DELIMITER are excess too.
CREATE DEFINER=`root`#`localhost` PROCEDURE `TestProcedure`(
IN year_number YEAR,
IN month_name VARCHAR(12),
IN input_region VARCHAR(20)
)
SELECT COUNT(DISTINCT region) AS total_regions_count
FROM aws_cost AS AC
WHERE AC.year = year_number;
Also month_name and input_region parameters are used nowhere and hense they're excess too.
You use SELECT variable = expression. This is SQL Server (MS SQL) syntax. In MySQL this construction performs another task - not assignment but compare. With obvious FALSE result - the variable value is zero whereas the expression will return zero only when there exists at least one row in this table and all rows in the table contains NULL in region column.
Write a script that creates and calls a stored procedure named invoice_balance. This stored procedure should use two variables to store (1) the count of all of the invoices in the Invoices table that have a balance due and (2) the sum of the balances due for all of those invoices. If that total balance due is greater than or equal to $30,000, the stored procedure should display a result set that displays the values of both variables. Otherwise, the procedure should display a result set that displays a message like this: Total balance due is less than $30,000.
SELECT sum(dueBalance) FROM invoice
DROP PROCEDURE IF EXISTS test; ;//drop if already test name procedure avilable
DELIMITER //
CREATE PROCEDURE test()
BEGIN
DECLARE countInvoice int; //declaring two variable countInvoice and sumdueBalance
DECLARE sumdueBalance decimal(10,8);
SELECT count(*) into countInvoice //put total count in countInvoice
FROM invoice;
SELECT sum(dueBalance) into sumdueBalance //put sum in sumdueBalance
FROM invoice;
if countprod>=30000 then
select countInvoice , sumdueBalance as col1; //col1 is name for new column
else
select 'Total balance due is less than $30,000.';
end if;
END //
DELIMITER ;
call test()
I wrote this script but it is giving me an error 1064.
SCHEMA GIVEN
https://drive.google.com/file/d/1JAeBc2h_5-z7La6nizFgIRDL1pjKDDz2/view?usp=sharing
as i remember there is sql syntax error in your script and this part the select into is not how it suppose to be in mysql.
SELECT count(*) into countInvoice can be rewrite in mysql:
insert into countInvoice
select count(*) from invoice;
I was asked to write a stored procedure for calculating the net salary of the employee if we pass
employee Id as a parameter and the formulas were given and the I had to write a Java program for the same.
I write this procedure in MY SQL WORKBENCH first and then wrote the Java program in eclipse IDE.
When I am executing this procedure in MY SQL WORKBENCH it is returning NULL as the result rather than the salary of the employee.
In the output of Java program also the Salary of the employee is printed as 0.0 for all the employees.
This the schema of the employee table.
After this Stored procedure I ran the below queries in QUERY SCRIPT:
call Get_Salary(101, #SALARY);
SELECT #SALARY;
CREATE DEFINER=root#localhost` PROCEDURE Get_Salary(IN ID int, OUT SALARY double )
BEGIN
declare Sal, e_commission, Gross_Sal, IT double;
select Salary,Commission into Sal, e_commission from employee where Employee_id = ID;
set Gross_Sal= Sal + e_commission;
if e_commission is null then
set IT= 0.1 * Gross_Sal;
else if e_commission < 500 then
set IT= 0.15 * Gross_Sal;
else
set IT= 0.2 * Gross_Sal;
end if;
set SALARY = Gross_Sal - IT;
END
You had a simple issue yet very minor to observe. Anyway, your output variable Salary has the same name as selecting value from table. So, basically you are selecting Salary from employee as well as you are having a local variable Salary. Despite the different cases, they are similar.
Also, you have forgot an end if at the end. Each if needs an End.
Here is the reference for study
I am a MySQL rookie and have been trying to create a stored procedure. The code below returns the error Error Code: 1172. Result consisted of more than one row. What am I doing wrong? (I'm using MySQL workbench)
CREATE DEFINER=`root`#`localhost` PROCEDURE `season_private_league_user`(
IN user_id INT,
OUT league_name VARCHAR(25),
OUT host_user VARCHAR(30))
BEGIN
DECLARE userteamid INT;
DECLARE var_league_name VARCHAR(25);
DECLARE var_host_user VARCHAR(30);
# Retrieve user team from user_id
SELECT CS_USER_TEAMS_ID INTO userteamid
FROM classicseasonmodel_classicseasonuserteam
WHERE user_id = user_id;
#LEAGUE NAME
SELECT classicseasonmodel_classicseasonprivateleague.private_league_name INTO var_league_name
FROM classicseasonmodel_classicseasonuserteamprivateleague
INNER JOIN classicseasonmodel_classicseasonprivateleague
ON classicseasonmodel_classicseasonuserteamprivateleague.private_league_id=classicseasonmodel_classicseasonprivateleague.CS_PRIVATE_LEAGUE_ID
WHERE user_team_id = userteamid;
#HOST_USER
SELECT classicseasonmodel_classicseasonprivateleague.host_user_id INTO var_host_user
FROM classicseasonmodel_classicseasonuserteamprivateleague
INNER JOIN classicseasonmodel_classicseasonprivateleague
ON classicseasonmodel_classicseasonuserteamprivateleague.private_league_id=classicseasonmodel_classicseasonprivateleague.CS_PRIVATE_LEAGUE_ID
WHERE user_team_id = userteamid;
SET league_name = var_league_name;
SET host_user = var_host_user;
END
CALL season_private_league_user(2, #league_name, #host_user);
SELECT #league_name AS league_name;
SELECT #host_user AS host_user;
Your column name and parameter name are identical. Rename your input parameter and change the command to this:
SELECT CS_USER_TEAMS_ID INTO userteamid
FROM classicseasonmodel_classicseasonuserteam
WHERE user_id = #user_id;
One of the SELECTs of you stored procedure that store the result in a variable returns more than one row, which returns in this error. This way you can only store single values in a variable, not multiple ones.
You can read about the SELECT...INTO statement here. The part that might be most interesting for you is:
The selected values are assigned to the variables. The number of
variables must match the number of columns. The query should return a
single row. If the query returns no rows, a warning with error code
1329 occurs (No data), and the variable values remain unchanged. If
the query returns multiple rows, error 1172 occurs (Result consisted
of more than one row). If it is possible that the statement may
retrieve multiple rows, you can use LIMIT 1 to limit the result set to
a single row.
It appears that performing a where clause on a table with Mysql works as expected (first code example).
However, when a where clause is performed on a view, the where clause appears to be ignored.
To keep things simple, I've tested a simple where clause on a standard table- this performs as expected, additionally a 'proof test' was ran to see if a mysql procedure can do a simple select * on a view (it did). Thus, it's only when the where clause is added to quiers on views.
How can I perform a WHERE query within a stored procedure on a View?
Example code 1 (working with normal table):
DELIMITER //
CREATE PROCEDURE p1 (id INT, fname VARCHAR(250))
BEGIN
DECLARE staffId INT;
DECLARE name VARCHAR(250);
SET name = fname;
SET staffId = id;
SELECT * FROM Staff WHERE ID_Staff = staffId AND Fname = name;
END; //
DELIMITER
Result set returned from the above performs as expected, acting upon the where clause.
However, with when using a where clause on a view the where clause is ignored:
Example code (not working as expected)
DELIMITER //
CREATE PROCEDURE p2 (year INT)
BEGIN
DECLARE a CHAR(4);
SET a = year;
SELECT * FROM TotalHoursView WHERE Year = "2014";
END; //
DELIMITER ;
Note: 'TotalHoursView' is a view, not a table.
The result of the second procedure ignores the where clause, always returning the full contents of the view (SELECT * FROM TotalHoursView).
Does Mysql not support where clauses on views when called in a stored procedure?
http://dev.mysql.com/tech-resources/articles/mysql-storedprocedures.pdf
Try to use another names for your variables, it's not CASE sensitive