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.
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 a Stored Procedure in mySQL that takes a subset of data from a table and performs some analysis on that subset within a temp table. Here is my code:
CREATE PROCEDURE GetPortfolioStats
(
InIdx_i INT,
InStart_i INT,
InEnd_i INT
)
BEGIN
DECLARE myLimit INT;
DECLARE myOffset INT;
SET myLimit = InEnd_i - InStart_i + 1;
SET myOffset = InStart_i - 1;
CREATE TEMPORARY TABLE IF NOT EXISTS myTmpTable AS (SELECT * FROM Leases WHERE Portfolio_i = InIdx_i ORDER BY Index_i LIMIT myLimit OFFSET myOffset);
SET #Additive_i := (SELECT COUNT(Index_i) FROM myTmpTable WHERE ReviewType_vc = 'Additive');
DROP TABLE myTmpTable;
SELECT #Additive_i;
END; GO
This works fine. However, the problem I have is that this is a multi-threaded application and when multiple threads are calling this stored proc, they start sharing the same temp table, which messes up the Stats I'm trying to compile.
Is there a way to either apply a unique table name to each call of the stored proc or limit the scope of the temp table to just that instance of the stored proc?
To answer the specific question: the easiest solution would be to use a different database connection per thread because temporary tables are session (connection) specific:
You can use the TEMPORARY keyword when creating a table. A TEMPORARY table is visible only to the current session, and is dropped automatically when the session is closed. This means that two different sessions can use the same temporary table name without conflicting with each other or with an existing non-TEMPORARY table of the same name.
However, after checking out the actual code, I would suggest not to use a temporary table at all, use a single query with a subquery:
SELECT COUNT(Index_i)
FROM
(SELECT Index_i, ReviewType_vc
FROM Leases
WHERE Portfolio_i = InIdx_i
ORDER BY Index_i
LIMIT myLimit OFFSET myOffset) t
WHERE ReviewType_vc = 'Additive'
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.
In MySql
UPDATE `inventoryentry` SET `Status` = 1 WHERE `InventoryID`=92 AND `ItemID`=28;
It successfully update only one row , where inventoryID = 92 and itemID=28 , the following message displayed.
1 row(s) affected
when I put this on stored procedure, as follow
CREATE DEFINER=`root`#`localhost` PROCEDURE `Sample`(IN itemId INT, IN itemQnty
DOUBLE, IN invID INT)
BEGIN
DECLARE crntQnty DOUBLE;
DECLARE nwQnty DOUBLE;
SET crntQnty=(SELECT `QuantityOnHand` FROM `item` WHERE id=itemId);
SET nwQnty=itemQnty+crntQnty;
UPDATE `item` SET `QuantityOnHand`=nwQnty WHERE `Id`=itemId;
UPDATE `inventoryentry` SET `Status` = 1 WHERE `InventoryID`=invID AND
`ItemID`=itemId;
END$$
calling stored procedures
CALL Sample(28,10,92)
It update all the status = 1 in inventoryentry against InventoryID (i.e. 92) ignoring ItemID, instead of updating only one row. The following message displayed!
5 row(s) affected
Why Stored procedure ignoring itemID in update statement ? or Why Stored procedure updating more than one time? But without Stored procedure it working fine.
You need to use different variable names apart from your field name, also use the table name with the columns for better understanding like i used in following:
CREATE DEFINER=`root`#`localhost` PROCEDURE `Sample`(IN itemID INT, IN itemQnty
DOUBLE, IN invID INT)
BEGIN
DECLARE crntQnty DOUBLE;
DECLARE nwQnty DOUBLE;
SET crntQnty=(SELECT `QuantityOnHand` FROM `item` WHERE id=itemID);
SET nwQnty=itemQnty+crntQnty;
UPDATE `item` SET `QuantityOnHand`=nwQnty WHERE `QuantityOnHand`.`Id`=itemID;
UPDATE `inventoryentry` SET `Status` = 1 WHERE `InventoryID`=invID AND
`inventoryentry`.`ItemID`=itemID;
END$$
because of
update inventoryentry ... WHERE ... AND `ItemID`=itemId
You are saying that column itemid should be the same as column itemid which is always true
Try renaming your parameter to a name that differs from your column name
Using same names for columns and variable names has some issues.
Semantics of Stored procedure code is not checked at CREATE time. At runtime, undeclared variables are detected, and an error message is generated for each reference to an undeclared variable. However, SP's seem to believe any reference denotes a column, even though the syntactic context excludes that. This leads to a very confusing error message in case the procedure.
Your column name ItemID matches with input variable name itemId, and hence is the issue.
Please look at my answer to a similar query here.
I noticed that a select statement inside my stored procedure is always returning the same value, no matter what parameter I'm calling my stored procedure with. Here's the code:
DELIMITER $$
CREATE PROCEDURE TEST(IN id INT)
BEGIN
DECLARE x INT DEFAULT 0;
select id;
SELECT paper_id
INTO x
FROM Paper
WHERE ID = id
limit 1;
select x;
END$$
x always returns the same value no matter what id I call test with. I noticed the value of x is always the value of paper_id in the first row of my Paper table.
However, if I run the same query outside of the stored procedure, I get the expected value.
What is going wrong inside the stored procedure which skews that value?
I'm not that familiar with MySQL's stored procedures, but could it be that the expression WHERE ID = id is evaluated as "all rows from Paper where the value in the column ID equals the value in the column ID" and simply ignores your parameter?
Try to rename your parameter to something that is different from the column name in your query.