Goal:
I'm trying to store the tables results of a query as a variable in a function.
I'd like to be able to do more things in this procedure referencing these tables.
I've got a scaffold function below:
DELIMITER $$
CREATE FUNCTION getRatio(treatmentA INT, treatmentB INT)
RETURNS FLOAT
BEGIN
DECLARE answer FLOAT;
DECLARE countA, countB, countABIntersection;
# Store patients of treatment A
SELECT DISTINCT patient
INTO **Variable**
FROM Treatment
WHERE TreatmentID = treatmentA;
# Store patients of treatment B
SELECT DISTINCT patient
INTO **Variable**
FROM Treatment
WHERE TreatmentID = treatmentB;
# Get Intersection of treatment B
Set answer = count(TreatmentA) * count(TreatmentB) * count(IntersectionTreatmentAB)
RETURN answer;
END $$
DELIMITER ;
If anyone can help, it would be greatly appreciated.
Thanks in advance.
You only can store or return a value from a function which MySQL have datatypes.
In short if you want to store a result set to variable you have to have a table datatype, unfortunately MySQL doesn't have such.
Solution: What you can do is, you can create temporary tables with respective columns for each result set to store(or may be in the same temp table in your case).
Do all operations on the temp table and store the result to a variable(FLOAT in you case), return the variable.
Let me know if that helps :)
-Thanks
Related
I'm a bit confused as I couldn't find the reason why my simple stored procedure isn't working as intended. Here is the stored procedure:
CREATE DEFINER=`root`#`localhost` PROCEDURE `sp_GetEntriesTest`(
in centerid int
)
BEGIN
SELECT *
FROM `Entries`
WHERE `CenterId` = centerid;
END
The SP is supposed to select rows from Entries table where the given centerid parameter matches the CenterId column, but it keeps returning all rows in the table, even where CenterId does not match centerid.
I tried without enclosing the table and column names without ``, but same result. I really couldn't find what I am doing wrong, if anybody could shed some light I would be much grateful!
It is working just fine. You think that one of those centerids magically refers to a column and the other to a parameter. Nope. They both refer to the column in the table.
So, give your variables distinctive names:
tended. Here is the stored procedure:
CREATE DEFINER=`root`#`localhost` PROCEDURE `sp_GetEntriesTest` (
in in_centerid int
)
BEGIN
SELECT *
FROM Entries e
WHERE e.CenterId = in_centerid;
END;
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.
So far I have tried many different ways of accessing the data on three tables using a stored procedure. First I tried a simple select statement :
create procedure reportCodes () begin
SELECT Numbers.serial_numb, numOwner.lName, numOwner.fName, numOwner.email,
location.long, location.lat, Numbers.dateValidated
FROM Numbers, Owner, location
WHERE Numbers.used = true AND Numbers.id=numOwner.Numbers_id AND
Numbers.id=location.Numbers_id;
end$$
(names changed to protect the guilty)
Running the stored procedure in phpmyadmin results in the first instance of the record (1 out of two ‘true’ in the test database). Running just:
SELECT Numbers.serial_numb, numOwner.lName, numOwner.fName, numOwner.email,
location.long, location.lat, Numbers.dateValidated
FROM Numbers, Owner, location
WHERE Numbers.used = true AND Numbers.id=numOwner.Numbers_id AND
Numbers.id=location.Numbers_id;
in the phpmyadmin SQL tab returns both records. Then I tried a temp table:
create procedure reportCodes () begin
CREATE TEMPORARY TABLE used_numbers AS (
SELECT Numbers.serial_numb, numOwner.lName, numOwner.fName, numOwner.email,
location.long, location.lat, Numbers.dateValidated
FROM Numbers, Owner, location
WHERE Numbers.used = true AND Numbers.id=numOwner.Numbers_id AND
Numbers.id=location.Numbers_id);
SELECT * FROM used_numbers; end$$
Returns 1 of 2 records as the procedure but both records in console. Finally I tried changing my table to a join:
CREATE PROCEDURE reportCodes()
begin
create temporary table used_numbers AS (
SELECT Numbers.serial_numb, numOwner.lName, numOwner.fName, numOwner.email,
location.long, location.lat, Numbers.dateValidated
FROM Numbers JOIN numOwner
ON Numbers.id=numOwner.Numbers_id
JOIN location ON
numOwner.Numbers_id=location.Numbers_id
WHERE Numbers.used = true
);
SELECT * FROM used_numbers; end$$
Same results as above. I’m at a loss as to why running just the SQL would show both test records but running the procedure with the exact same code only yields one.
Thanks
in your query, numOwners isn't a valid table being selected against, so something's wrong. Have you tried running your SQL in the Query window in phpMyAdmin to ensure that the EXACT same query is returning 2 rows?
I presume the "Owner" table is supposed to be "numOwner", so I've re-written the stored procedure call below. Also, I'm not sure what types of values you're storing in Numbers.used to evaluate to "TRUE". I will presume you're using a TINYINT(1), so I've altered that, as well. I hope this helps.
DELIMITER $$
USE `db`$$
DROP PROCEDURE IF EXISTS `reportCodes`$$
CREATE PROCEDURE `reportCodes`()
BEGIN
SELECT
n.serial_numb,
o.lName,
o.fName,
o.email,
l.long,
l.lat,
n.dateValidated
FROM Numbers n
INNER JOIN numOwner o ON n.id=o.Numbers_id
INNER JOIN location l ON n.id=l.Numbers_id;
WHERE n.used = 1
END$$
DELIMITER ;
Ok, First off, I am not a mysql guru. Second, I did search, but saw nothing relevant related to mysql, and since my DB knowledge is limited, guessing syntactical differences between two different Database types just isn't in the cards.
I am trying to determine if a particular value already exists in a table before inserting a row. I've decided to go about this using two Stored procedures. The first:
CREATE PROCEDURE `nExists` ( n VARCHAR(255) ) BEGIN
SELECT COUNT(*) FROM (SELECT * FROM Users WHERE username=n) as T;
END
And The Second:
CREATE PROCEDURE `createUser` ( n VARCHAR(255) ) BEGIN
IF (nExists(n) = 0) THEN
INSERT INTO Users...
END IF;
END
So, as you can see, I'm attempting to call nExists from createUser. I get the error that no Function exists with the name nExists...because it's a stored procedure. I'm not clear on what the difference is, or why such a difference would be necessary, but I'm a Java dev, so maybe I'm missing some grand DB-related concept here.
Could you guys help me out by any chance?
Thanks
I'm not sure how it helped you, but...
why SELECT COUNT(*) FROM (SELECT * FROM Users WHERE username=n) and not just SELECT COUNT(*) FROM Users WHERE username=n?
Just make the user name (or whatever the primary application index is) a UNIQUE index and then there is no need to test: Just try to insert a new record. If it already exists, handle the error. If it succeeds, all is well.
It can (and should) all be one stored procedure.
This may or may not be a simple question.
I am looking for a way to NOT select anything from a table, but return a set of table-like data.
Basically I have a procedure that loops through a table and stores data into a variable, then displays it by the line:
SELECT #args as parents;
Is there any better way to set up a table data structure and return that whole thing? Right now I am returning a single variable with multiple (parse-needed) data.
EDIT:
To try and explain better:
What I have to do is loop through and perform a series of select statements, is there a way to 'concat' this data into a big datatable structure and then return that table?
Use a temp table
DROP TABLE IF EXISTS tmp;
CREATE TABLE tmp( --fields-- );
WHILE ( --condition-- ) DO
INSERT INTO tmp VALUES ( --fields-- );
SELECT --Statement--
END WHILE;
--do stuff--
and clean up
DROP TABLE tmp
I'm not positive for mySQL, but you should be able to use a function to return a table. I found the following on another question, which might be helpful:
CREATE FUNCTION getdepartments()
RETURNS #departments TABLE(
DNAME VARCHAR(25),
DEPTID VARCHAR(10),
DBONUS DECIMAL(7,2))
AS
BEGIN
INSERT #departments SELECT * FROM DEPARTMENT;
RETURN
END
I've done this in SQL Server, and you can do fun things like recursive functions that keep adding records to your output table, etc.
Maybe you could return a recordset like described here http://forums.mysql.com/read.php?102,50520,50626#msg-50626. Hope that this will help.