How to cast string parameter to int in a "limit" - mysql

SELECT DISTINCT(id) vetid,
c.clinic_id,
c.clinic_name,
c.type,
c.city,
c.state,
c.country,
c.lat,
c.lng,
c.zip,
( 3959 * Acos( Cos( Radians(44.977498) ) * Cos( Radians( c.lat ) ) * Cos( Radians( c.lng ) - Radians(-93.406556) ) + Sin( Radians(44.977498) ) * Sin( Radians( c.lat ) ) ) ) AS distance
FROM biah_clinics c
WHERE opt_out != '1'
AND c.country = 'US'
HAVING distance < '10'
ORDER BY distance limit cast('20' AS int);
Using Drupal's db_query, all parameters passed to the query are passed as STRING. This is giving me an error. That is why in my query, I want to cast that parameter to INT.
So it should end up like this:
limit cast('20' AS int);
limit 20;
But this is giving me an error in MySQL:
"SQLSTATE[42000]: Syntax error or access violation: 1064 You have an
error in your SQL syntax; check the manual that corresponds to your
MySQL server version for the right syntax to use near 'CAST('25' AS
INT)' at line 15"

I ended up using drupal's db_query_range(), due to sql limit doesn't work but with integer literals.
https://api.drupal.org/api/drupal/includes%21database%21database.inc/function/db_query_range/7.x

Related

Query works when function is not used

I'm creating a query that get's the total number of customers within a certain distance of each one of our stores using the Haversine Formula.
This formula is fairly big and looks ugly when I use it in a query, so I decided to create a function out of it so that my queries would look cleaner.
The issue is that when I run the query using the function, I get this error: Error Code: 2013. Lost connection to MySQL server during query.
As soon as I use the actual formula instead of the function in my query it runs as expected. Anyone know why this is happening? Is this a time out issue because the query is taking to long to run?
Here is my user created Haversine function:
CREATE DEFINER=`MYADMIN`#`%` FUNCTION `Haversine`(lat1 DECIMAL(15,10), lng1 DECIMAL(15,10), lat2 DECIMAL(15,10), lng2 DECIMAL(15,10)) RETURNS decimal(11,2)
BEGIN
RETURN (3959 * acos( cos( radians(lat1) ) * cos( radians( lat2 ) ) * cos( radians( lng2 ) - radians(lng1) ) + sin( radians(lat1) ) * sin(radians(lat2)) ));
END
This query causes the lost connection error:
SELECT s.StoreID
, count(c.PBID) as customers
, sum(c.Status = 'null') as 'Not Active'
, sum(c.Status = 'Left Message') as 'Left Message'
from console.Stores s
cross
join console.Customers c
where console.Haversine(s.Latitude,s.Longitude,c.Lat,c.Lng) <= 5
and c.DNC = '0'
and c.Status != 'Do Not Call'
group
by s.StoreID;
This is the same query without the function which runs as expected:
SELECT s.StoreID, count(c.PBID) as customers, sum(c.Status = 'null') as 'Not Active', sum(c.Status = 'Left Message') as 'Left Message' from console.Stores s cross join console.Customers c where (3959 * acos( cos( radians(s.Latitude) ) * cos( radians( c.Lat ) ) * cos( radians( c.Lng ) - radians(s.Longitude) ) + sin( radians(s.Latitude) ) * sin(radians(c.Lat)) ) ) <= 5 and c.DNC = '0' and c.Status != 'Do Not Call' group by s.StoreID;

Error 1064 in SQL statement

I have tried to run a SQL command but I am receiving this error:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ')
The SQL statement is
SELECT * ,
Match(product.title) against (query) + match(product.description) against (query1) +match(product.keyword) against (query2)+match(product.url) against (query2) + (average(review.rating)/100*count(productid))+(100/price)+(site.domainauthority/25)+(10-
CASE
WHEN lcase(seller.city) = lcase(city) THEN TRUNCATE(( 6371 * acos( cos( radians( 23 ) ) * cos( radians( seller.latitude ) ) * cos( radians( seller.longitude ) - radians(24) ) + sin( radians( 24 ) ) * sin( radians( seller.latitude ) ) ) ),1))
ELSE + 0
END AS score
FROM product,
productimages,
review,
seller,
site
WHERE distance < 10
AND productimage.id=product.id
AND product.sellerid =seller.id
AND product.siteid-site.id
AND productmeta.id = product.id
AND review.productid = product.id
AND ((
seller.deliverabletype = "international")
OR (
seller.deliverabletype = "country"
AND seller.country = 'country')
OR (
seller.deliverabletype = "state"
AND seller.country = 'country')
OR
OR (
seller.deliverabletype = "city"
AND seller.country = 'city'))
GROUP BY product.id mysql sql-server
The query was not well formed. One of the closing parenthesis should be at the end.
try this.
TRUNCATE(
( 6371 * acos(
cos( radians( 23 ) ) * cos( radians( seller.latitude ) ) *
cos( radians( seller.longitude ) - radians(24) ) +
sin( radians( 24 ) ) * sin( radians( seller.latitude ) )
)
),1)
ELSE + 0
END) AS score

Why does query give different result once put into stored procedure?

I have read a few articles listed below to try and find an answer to my problem. They both seemed to have the same issue.
I saw this one but I read in the MySQL documentation that all procedures are by default non deterministic.
This one doesn't have anything to do with my problem because its SQL Server (not MySQL).
Here is the query I am using to create my procedure:
CREATE PROCEDURE getcusbyzip(zipcode VARCHAR(30),radius VARCHAR(30))
SELECT C.CustomerName, C.MenuId
FROM Customers C
INNER JOIN (
SELECT ZIPCODE, ( 3959 * ACOS( COS( RADIANS( (
SELECT Z.LAT
FROM ZipCodes Z
WHERE Z.ZIPCODE =zipcode
LIMIT 0 , 1
) ) ) * COS( RADIANS( LAT ) ) * COS( RADIANS( LNG ) - RADIANS( (
SELECT Z.LNG
FROM ZipCodes Z
WHERE Z.ZIPCODE =zipcode
LIMIT 0 , 1
) ) ) + SIN( RADIANS( (
SELECT Z.LAT
FROM ZipCodes Z
WHERE Z.ZIPCODE =zipcode
LIMIT 0 , 1
) ) ) * SIN( RADIANS( LAT ) ) ) ) AS distance
FROM ZipCodes
HAVING distance <radius
ORDER BY distance
LIMIT 0 , 20
) AS RelevantCodes ON ( C.ZIPCODE = RelevantCodes.ZIPCODE )
Now If I run this query after that one:
CALL getcusbyzip(08360,50)
I get zero rows returned. But if I run the exact same statement inside the procedure as just a query and put the params in like this:
SELECT C.CustomerName, C.MenuId
FROM Customers C
INNER JOIN (
SELECT ZIPCODE, ( 3959 * ACOS( COS( RADIANS( (
SELECT Z.LAT
FROM ZipCodes Z
WHERE Z.ZIPCODE =08360
LIMIT 0 , 1
) ) ) * COS( RADIANS( LAT ) ) * COS( RADIANS( LNG ) - RADIANS( (
SELECT Z.LNG
FROM ZipCodes Z
WHERE Z.ZIPCODE =08360
LIMIT 0 , 1
) ) ) + SIN( RADIANS( (
SELECT Z.LAT
FROM ZipCodes Z
WHERE Z.ZIPCODE =08360
LIMIT 0 , 1
) ) ) * SIN( RADIANS( LAT ) ) ) ) AS distance
FROM ZipCodes
HAVING distance <50
ORDER BY distance
LIMIT 0 , 20
) AS RelevantCodes ON ( C.ZIPCODE = RelevantCodes.ZIPCODE )
I get exactly what I wanted. The answer should only be one row but why is the result coming to me while not in a procedure but when I put it in one it will not give me the row.
I thought maybe it was because I did not have BEGIN and END but when I place that after the create line and END after the last line it fails to produce the procedure.
Your sample code and stored procedure code are too different from one another.
In order to identify your problem, you need to do the following
At the top of your sample code (not SP)
Declare a variable called zipcode of type varchar(30)
Declare a variable called radius of type varchar(30)
Then, modify the rest of the sample code to be exactly the same as the stored procedure.
You will be able to identify the exactly problem using this method.
As mentioned in the comments, it is likely due to the abuse of varchars being converted to numerics.
Summary
Declare and set variables at the top of your sample code so that the rest of the sample is EXACTLY the same as your stored procedure. Then you can start to identify the problem.

MySQL logic: different result for Stored Procedure vs Query with just body of Proceduce

Ok so my stored procedure is reading variables wrong in its MySQL query. The results I need are obtained fine when I just use the body of the proc. I would like to make this a stored procedure.
Here is the SP in SQLyog:
DELIMITER $$
USE `XXXXXXXXXXXXXXX`$$
DROP PROCEDURE IF EXISTS `getcusbyzip`$$
CREATE DEFINER=`XXXXXXXXXXXXXXX`#`%` PROCEDURE `getcusbyzip`(IN zipcode VARCHAR(30), IN radius VARCHAR(30))
BEGIN
SELECT C.CustomerName, C.MenuId
FROM Customers C
INNER JOIN (
SELECT ZIPCODE, ( 3959 * ACOS( COS( RADIANS( (
SELECT Z.LAT
FROM ZipCodes Z
WHERE Z.ZIPCODE =zipcode
LIMIT 0 , 1
) ) ) * COS( RADIANS( LAT ) ) * COS( RADIANS( LNG ) - RADIANS( (
SELECT Z.LNG
FROM ZipCodes Z
WHERE Z.ZIPCODE =zipcode
LIMIT 0 , 1
) ) ) + SIN( RADIANS( (
SELECT Z.LAT
FROM ZipCodes Z
WHERE Z.ZIPCODE =zipcode
LIMIT 0 , 1
) ) ) * SIN( RADIANS( LAT ) ) ) ) AS distance
FROM ZipCodes
HAVING distance <radius
ORDER BY distance
) AS RelevantCodes ON ( C.ZIPCODE = RelevantCodes.ZIPCODE );
END$$
DELIMITER ;
Now there is only 1 record that should be returned because I have only 1 customer added for now until I get this type issue resolved. Here is where I have a breakthrough (please don't laugh, I am new to SQL entirely :) ).
I have tried changing the TYPE as well for the parameters. The zipcode broke after I changed it to an INT and I used this:
CALL getcusbyzip(08361,50)
and my resulting rows were all the rows in which "8361" were in the zipcode. Basically that is my only personal explanation as to why I received so many rows back.
When I use this with both params set to VARCHAR type:
CALL getcusbyzip(08361,50)
or
CALL getcusbyzip('08361',50)
or
CALL getcusbyzip(08361,'50')
you get the point.
I get 0 rows back when I should be getting 1 row back.
So now I think Iknow what my problem is and I might actually ask it hopefully. What is causing my SP to read the input differently as a parameter than as if I just did a query and manually put the parameters into the query. Secondly how can I adjust my procedure so that the MySQL server reads my procedure just like my Query but with the parameters ofcoarse?
Below is the query that works perfectly fine:
SELECT C.CustomerName, C.MenuId
FROM Customers C
INNER JOIN (
SELECT ZIPCODE, ( 3959 * ACOS( COS( RADIANS( (
SELECT Z.LAT
FROM ZipCodes Z
WHERE Z.ZIPCODE =08360
LIMIT 0 , 1
) ) ) * COS( RADIANS( LAT ) ) * COS( RADIANS( LNG ) - RADIANS( (
SELECT Z.LNG
FROM ZipCodes Z
WHERE Z.ZIPCODE =08360
LIMIT 0 , 1
) ) ) + SIN( RADIANS( (
SELECT Z.LAT
FROM ZipCodes Z
WHERE Z.ZIPCODE =08360
LIMIT 0 , 1
) ) ) * SIN( RADIANS( LAT ) ) ) ) AS distance
FROM ZipCodes
HAVING distance <50
ORDER BY distance
) AS RelevantCodes ON ( C.ZIPCODE = RelevantCodes.ZIPCODE )
EDIT:
Another point to note is that when I change the variables to direct information in the SP(Stored Procedure) that does not fix it either so it has to be something I missing in MySQL procedure logic. I honestly do not understand why the results are different just because its in a stored procedure.

MySQL query returning errors

I'm trying to get coordinates and locations from a database, but my server is returning this error:
Error: You have an error in your SQL syntax; check the manual that corresponds to your
MySQL server version for the right syntax to use near
'long ) - radians(0) ) + sin( radians(0) ) * sin( radians( lat ) ) ) ) AS distanc'
at line 1
Query:
SELECT id,
address,
name,
(3959 * acos(cos(radians(0)) *
cos(radians(lat)) *
cos(radians(long) - radians(0)) +
sin(radians(0)) *
sin(radians(lat)))
) AS distance
FROM places
HAVING distance < 10
ORDER BY distance
LIMIT 0, 20;
Do I have to escape "lat" and "long" with `, or is that formula wrong altogether? Thanks.
Also, the coordinates I'm using are 0, 0 (just for test purposes).
LONG is a reserved word in mysql. Escape it using backticks when using it as a column name.
Replace the HAVING statement with "WHERE" statement. There is no "GROUP BY", then why are you using HAVING?
I think you have an extra ). Try this
SELECT id, address, name, ( 3959 * acos( cos( radians(0) ) * cos( radians( lat ) ) * cos( radians( long ) - radians(0) ) + sin( radians(0) ) * sin( radians( lat ) ) ) AS distance FROM places HAVING distance < 10 ORDER BY distance LIMIT 0 , 20;