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.
Related
I am new to mySQL my background is SQL Server
I have this SP that has this statement
DELIMITER //
create PROCEDURE spTest ()
BEGIN
declare vCnt int;
declare vMax int;
select vCnt = count(*), vMax=Max(ShortID) from ShrtMain;
select vCnt * vMax as Total;
END
I am expecting to one result with one field called Total
but what I actually get 2 results
one with 2 columns as shown here
and the other is what I actually want
how can I get just one result ?
To set a variable from a SELECT inside a MySQL stored procedure you use the SELECT ... INTO form of the query:
SELECT COUNT(*) INTO LimitCount
FROM Locations
WHERE IPAddress = IPAddress;
Note that it's inadvisable to use variables with the same name as columns (e.g. IPAddress in your query) as there is the potential for MySQL not to be able to determine which you want to use.
I have the following stored procedure in a MYSQL database. The stored procedure gets lon,lat and than I'm doing an update on a different database and table.
DROP PROCEDURE IF EXISTS annuals.updateSalesFlorida;
CREATE DEFINER=`dddd`#`%` PROCEDURE `updateSales`(propertyId int)
BEGIN
DECLARE lat FLOAT;
DECLARE lon FLOAT;
SELECT SitusLongitude,SitusLatitude
INTO lon,lat
FROM annuals.florida
WHERE PropertyID=propertyId
LIMIT 1 FOR UPDATE;
UPDATE sales.florida
SET
`SitusLongitude` = lon,
`SitusLatitude` = lat
WHERE PROPERTYUNIQUEID=propertyId;
END;
Every time I run the stored procedure the SitusLongitude and SitusLatitude columns are 0. I know for a fact that the previous selected SitusLongitude and SitusLatitude have actual values in there. For some reason the variables are not being set in lat,lon. Any idea what I'm dong wrong?
The problem is that the procedure parameter has the same name as a column in the tables. When you refer to propertyid in the queries, it uses the column, not the parameter. Column and variable names are case-insensitive, so it doesn't matter that you spelled one of them PropertyID and the other propertyId.
Use a different name for the parameter, e.g. p_propertyId
Also, there's no need for two queries, you can do it in one with a JOIN.
UPDATE sales.florida AS s
CROSS JOIN (
SELECT *
FROM annuals.florida
WHERE propertyId = p_propertyId
LIMIT 1) AS a
SET s.SitusLongitude = a.SitusLongitude, s.SitusLatitude = a.SitusLatitude
WHERE s.PROPERTYUNIQUEID = p_propertyId
Note that using LIMIT without ORDER BY means that the row that's selected will be unpredictable.
I have created one procedure which take 2 parameter and it check the count.
But when I pass "" blank value It still return 1 count.
Did not get it why it is working like this.
Thanks for the help below is my procedure
DELIMITER $$
CREATE DEFINER=`dadclient`#`123.63.249.169` PROCEDURE `checkInOut`(IN grid varchar(50),OUT count INT)
begin
select count(GRIDID) into count from GRIDID where GRIDID=grid;
select count;
END
when I call
checkInOut("",#aaa);
select #aaa;
When I call this,it return me 1 which is wrong.
But when I pass "" blank value It still return 1 count.
Because when you say it is blank by providing an empty string it is a value. Empty string is also treated as a value in database and hence you get count as 1
The MySQL docs says:
COUNT(expr)
Returns a count of the number of non-NULL values of expr in the rows
retrieved by a SELECT statement. The result is a BIGINT value.
So if you want the count to return 0 then instead of making the string as empty "" you need to make the value as NULL.
Yo mate, try this:
DELIMITER $$
CREATE
DEFINER=`dadclient`#`123.63.249.169`
PROCEDURE `checkInOut`(
IN `grid` VARCHAR(50),
OUT `count` INT
)
BEGIN
-- insert value into variable
SET `count` = (
select count(GRIDID)
from GRIDID
where GRIDID=grid;
);
END$$
DELIMITER ;
So in your application, e.g. php you can CALL checkInOut($input, $output);. No need for the final SELECT... part in your initial code, afaik, because you already declared count as an OUT in the procedure parameter
Note:
Is the name GRIDID the name of your table? because as I see, you also used it in your WHERE statement as a key filter
Regarding your query, supposedly it is expected to contain one row of result. Kindly check that also mate
I have declared the variables (total,order_num,order_stts,id_cust,reMarks). But it have error that said result consisted of more than one row. How can i fix this error? Please help me fix this error, i'm new to sql.
From this code, there's several task to do:
(1) update tble customer by setting the address to '90 TYT' if c_id= 1
(2) view order_no,status,c_id,item_total remarks.
(3) if item_total 0, then update table order_status by setting remarks = 'UNAVAILABLE',
else select order_no,status,item_total,remarks where status = 'waiting'.
#drop procedure if exists usp_GetAnything;
delimiter //
create procedure usp_GetAnything()
begin
declare total int default 0;
declare order_num varchar(45) default 000;
declare order_stts varchar(45) default 000;
declare id_cust int default 0;
declare reMarks varchar (45) default 000;
select c_id,lname,address,city
from customer;
update customer
set address = '90 TYT'
where c_id = 1;
select o.order_no,o.o_status,c.c_id,o.item_total,o.remarks
into order_num,order_stts,id_cust,total,reMarks
from customer c, order_status o
where c.c_id=o.c_id;
if (total > 0) then
update order_status o
set reMarks = 'UNAVAILABLE'
where order_num > '123';
else
select order_num,order_stts,total,reMarks
from order_status
where order_stts = 'waiting';
end if;
end
The error is due to the INTO clause in the second SELECT statement. That wouldn't be an error if the SELECT returned no more than one row.
But if that SELECT returns more than one row, MySQL will throw 1172 error. (You can test this by adding a "LIMIT 1" clause on that "SELECT ... INTO" statement, and verifying that the error is not thrown.
The procedure runs a SELECT to return a resultset, then issues an UPDATE statement to modify zero or more rows in a table.
The next part of the procedure is confusing; it's not clear what we are trying to achieve. The SELECT can return zero, one or more rows. If the intent is to perform a conditional test to determine whether there are any rows with item_total > 0,
Then one possible "fix" (to avoid the 1172 error) would be to add
AND o.item_total > 0 LIMIT 1
to the "SELECT ... INTO" statement.
Without an "ORDER BY", it's indeterminate which row would be returned. But it doesn't really look like it matters. Apart from the comparison of the returned o.item_total value, it doesn't look like the procedure is doing anything else with the columns returned.
The following UPDATE statement is only going to be executed if an item_total>0 row was found.
And the UPDATE statement will update all rows that have an order_number greater than a specified constant.
There doesn't appear to be any relationship to the row(s) returned by the previous SELECT ... INTO statement.
If the intent is to update the rows in order_status (that are related to a customer) if "any" row returned by the previous query has an item_total > 0, then the proposed "fix" would accomplish that.
The procedure then (conditionally) returns a second resultset (all rows from order_status with `order_stts = 'waiting'), but only if there wasn't any order_status row with and item_total>0.
We can fix the 1172 error, but this procedure has much bigger problems than that error. The whole procedure seems like bizarre approach to solving whatever problem it's supposed to be solving. It just looks like a jumble of SQL statements kludged together without a clear design.
This means
select o.order_no,o.o_status,c.c_id,o.item_total,o.remarks
from customer c, order_status o
where c.c_id=o.c_id;
the query above return multiple rows which is not acceptible if you are trying to store the result in a variable. So if you dont expect multiple rows, check your data, or if you are OK with the first row values, add limit 1 in the query
select o.order_no,o.o_status,c.c_id,o.item_total,o.remarks
into order_num,order_stts,id_cust,total,reMarks
from customer c, order_status o
where c.c_id=o.c_id limit 1;
You may try searching for Result consisted more than one row in Stackoverflow and you should be getting plenty of answers!!!
I am trying to create an sql trigger statement using phpmyadmin trigger interface.
Trying to do something for table 1 as shown below :
BEGIN
declare #valid_number int ;
select id into #valid_number from table 2 ;
if 10 does not exist in #valid_number then
{do something here}
end if;
END
how to achieve it?
First: a variable in a stored routine can't store multiple values, just a single one. Your statement
select id into #valid_number from table 2 ;
will only work, if the query returns exactly one row. An error will occur, if the query returns multiple rows, a warning, if the query returns no row at all, see the manual page to SELECT ... INTO:
The INTO clause can name a list of one or more variables, which can be
user-defined variables, stored procedure or function parameters, or
stored program local variables. [...]
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).
Solution:
It's not difficult to create a statement that gives you the desired answer in exact one row, i.e.
SELECT COUNT(*) into valid_number FROM example WHERE id = 10;
This query will return 0, if the id 10 does not exists in column id and the count of occurences else. Of course there are several ways to achieve this, this is just one of them. You could rewrite your stored routine to:
BEGIN
-- prefer local variables, don't use user defined, if not needed.
DECLARE valid_number int;
SELECT COUNT(*) into valid_number FROM example WHERE id = 10;
IF valid_number = 0 THEN
-- do something here
END IF;
SELECT result;
END
Note
You could use a cursor to traverse the result of a query, but most times one wants to avoid a cursor. To use a cursor under similar conditions as of this question would not be the SQL way to do it and most times very inefficient.