Error 1172 : Result consisted more than one row (in SQL) - mysql

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!!!

Related

SQL- Selecting NULL columns only

I need to write a query which will look at a table, and select from it any/all columns(s) that have ALL NULL rows.
I would prefer to not have to say "SELECT (each column name)", but would rather say "SELECT (from whole table, those columns) WHERE (rows are all NULL).
I know about CASE and WHEN statements, but my understanding is that columns must be specifically referenced in the select statement. I'll be using this query on many different tables, with many different dimensions and column names, so I would like the query to be versatile.
I'm using SQL in Toad with a Vertica db.
This is what my tables look similar to:
This table contains the columns i need the query. The columns i need to query are such as "owner_id", NOT TYPE_NAME, NULLABLE, etc. Each row in THIS table, is actually a column with such and such many values, and it is these values I need to run my query against.
'Simply' put: If a column has ALL NULL rows, I need to identify and/or select it.
Any Suggestions? %Solved^^^%
I found this example of a way to loop through columns, but despite my research, I'm still having trouble making sense of it all.
Such as: how is col_names difference from column_name? Same for the text in the FROM statement and WHERE. Should those not both the table name? Then what does the found_rows() signify?
DECLARE col_names CURSOR FOR
SELECT column_name
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = 'tbl_name'
ORDER BY ordinal_position;
select FOUND_ROWS() into num_rows;
SET i = 1;
the_loop: LOOP
IF i > num_rows THEN
CLOSE col_names;
LEAVE the_loop;
END IF;
FETCH col_names
INTO col_name;
//do stuff
SET i = i + 1;
END LOOP the_loop;
As I understand you want to Identify which columns have NULL values on all rows and dont want to type all columns, right?
If thats so, this is how I would do:
1) Build a function that takes the as an input parameter and does:
--FYI: this is a pseudo code. I dont have mysql here to get the correct syntax
select sum(
case when CAST(<column_name> as varchar(5200)) is not null then 1 else 0 end --5200 seems to be your longer column
)
from YOUR_TABLE
--the idea is to cast the column as anythig; if it is null, it gets a 0.
--If the sum across the rows is 0, it means that all the rows are null
2) Loop through the column names and call the function

MySQL - Result consisted of more than one row

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.

How to check if a particular value exists in a variable which stores multiple value in mysql?

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.

Stored procedure return SELECT only with rows

I just set an SQL Stored Procedure to return a specific row in a specific order (from more to less important):
-- 1st Level -> Query a more detailed object...
SELECT ... WHERE something
-- if a result is find, the SP is returning the correct row.
-- if rowcount = 0 then, the SP is returning an empty row
-- and continues with the next query (less specific than the 1st one).
IF ##ROWCOUNT = 0
BEGIN
SELECT .... WHERE something else...
-- Again, if a result exists, the SP returns the correct row, but also
-- the result of the 1st query is returned without rows...
IF ##ROWCOUNT = 0
BEGIN
SELECT .... WHERE something else again...
END
END
Is there any option to only return the SELECT statement that returns a non empty row? I don't want to return empty rows... and each time the row is an "sub-level" of the 1st query, I get empty results before the correct row.
I was thinking to create a table variable. Are there any better ways?
Since you are looking for the lack of rows why not use an if/else statement in your procedure. Something like:
If exists(/*firstQuery*/ SELECT ... WHERE something) begin
SELECT ... WHERE something
end else if exists (/*secondQuery*/ SELECT .... WHERE something else... ) begin
SELECT .... WHERE something else...
end else /*Third query*/ begin
SELECT .... WHERE something else again...
end
Just remember when checking is something exists you should select only one column (for example the id) as if you have calculated columns then this can slow down your procedure.

MySQL Stored Procedure with Dynamic Result LIMIT

I've got a stored procedure in my MySQL database, and need to figure out how to limit the return to create some pagination.
Some pseudocode:
CREATE PROCEDURE `my_procedure`(IN member_id INT, IN start INT, IN end INT)
BEGIN
SELECT * FROM member_activity WHERE `member_id` = member_id
<if start is not null>
LIMIT start, end
<endif>
END;
If I pass a null value, how do I simply unlimit the query?
Passing my_procedure(1,null,null) returns an error.
I know I can just wrap the entire query in an IF statement, but I'd rather not, because there's several other variables that would be annoying to keep in sync. Is it possible to accomplish this without writing the entire query twice?
Thanks
As mentioned in the manual:
To retrieve all rows from a certain offset up to the end of the result set, you can use some large number for the second parameter. This statement retrieves all rows from the 96th row to the last:
SELECT * FROM tbl LIMIT 95,18446744073709551615;
Since, as you point out, one cannot use the IFNULL() function within the LIMIT clause, prior to your SELECT command you could do:
SET `start` := IFNULL(`start`, 0);
SET `end` := IFNULL(`end` , 18446744073709551615);