MySQL SELECT Statement not working when executed from PHP - php

I have the following piece of code, executing a pretty simple MySQL query:
$netnestquery = 'SELECT (`nested`+1) AS `nest` FROM `ipspace6` WHERE `id`<='.$adaddr.' AND `subnet`<='.$postmask.' AND `type`="net" AND `addr` NOT IN(SELECT `id` FROM `ipspace6` WHERE `addr`<'.$adaddr.' AND `type`="broadcast") ORDER BY `id`,`subnet` DESC LIMIT 1';
$netnestresults = mysql_query($netnestquery);
$netnestrow = mysql_fetch_array($netnestresults);
$nestlvl = $netnestrow['nest'];
echo '<br> NESTQ: '.$netnestquery;
Now, when I execute this in PHP, I get no results; an empty query. However, when I copy and paste the query echoed by my code (for debug purposes) into the mysql command line, I get a valid result:
mysql> SELECT (`nested` + 1) AS `nest` FROM `ipspace6` WHERE `id`<=50552019054038629283648959286463168512 AND `subnet`<=36 AND `type`='net' AND `addr` NOT IN (SELECT `id` FROM `ipspace6` WHERE `addr`<50552019054038629283648959286463168512 AND `type`='broadcast') ORDER BY `id`,`subnet` DESC LIMIT 1;
+------+
| nest |
+------+
| 1 |
+------+
1 row in set (0.00 sec)
Can anybody tell me what I'm doing wrong? I can't put quotes around my variables, as then MySQL will try to evaluate the variable as a string, when it is, in fact, a very large decimal. I think I might just be making a stupid mistake somewhere, but I can't tell where.

Can you modify the line to say $netnestresults = mysql_query($netnestquery) or die(mysql_error());
It may be giving you an unknown error, such as a bad connection, missing DB, etc.

do an echo $netnestquery
before calling mysql_query
also add a die(mysql_error()) there.

WHERE `id`<=50552019054038629283648959286463168512
That's a pretty big number there.
PHP has issues with big numbers. The maximum size of an integer depends on how PHP was compiled, and if it's on a 64-bit system.
Have you checked that the variable containing that number hasn't been capped to a 32-bit or 64-bit integer? If it has been capped, you're going to need to take steps to make sure it's only being stored as a string in PHP. MySQL accepts strings that are entirely numeric as numbers without complaining.
(That being said, I'm not sure that MySQL can do anything with a number larger than 64-bits. The largest integer column is BIGINT, which is 64-bits. There's also NUMERIC, but it's treated as a floating point number, and that might not be what you want to do...)

Related

mySQL Workbench Error: Syntax Error, unexpected single quotes

I was trying to make a SQL statement in PHP, to convert a string into a time(6). But I have tried everything, for the last 12 hours, and have not made an inch of progress. I have tried these statements, all yield the same error.
UPDATE scheduling SET start='03:42PM' WHERE activityid=2;
UPDATE scheduling SET start=CONVERT(TIME(6),'03:42PM');
INSERT INTO scheduling(start) VALUES (start=CONVERT(TIME(6),'03:42PM'));
INSERT INTO scheduling(start) VALUES (start=CONVERT(TIME(6),'03:42PM'));
INSERT INTO scheduling(start) VALUES (start=CONVERT(TIME(6),'15:42'));
The error is
Syntax Error: unexpected '03:42PM'(single quoted text)"
I do not know how to fix this, the table exists, and i have sucesfully got other info using statements like SELECT activityid=2 FROM xxxxxx.scheudling
I guess I have two questions, either answer would work.
In my PHP document, how would I convert a string I get in from an Android Studio volley to a date. (I get the variable correctly, with $start=$_Post("start"), so that works, but I cant convert it into a time. I looked online, and tried everything that looked like it work work.
Conversion through SQL Code, I already tried CAST and CONVERT, neither works. My start column is type TIME(6).
I recommend testing expressions using a SELECT statement.
Firstly, the MySQL CONVERT function arguments are flipped around backwards.
The syntax is CONVERT(expr,type)
And type is supplied as a keyword, not a string literal. For example:
SELECT CONVERT('235',SIGNED)
To convert to a TIME datatype
SELECT CONVERT( '15:42' ,TIME(6)) // => 15:42:00.000000
The 'PM' part of the string literal will be ignored.
SELECT CONVERT( '03:42PM' ,TIME(6)) // => 03:42:00.000000
We can use the STR_TO_DATE function to return a TIME value from a string that contains the AM/PM indicator
SELECT STR_TO_DATE( '03:42PM' ,'%h:%i%p')
And there's no need to cast that to TIME(6), we can do this:
UPDATE scheduling
SET start = STR_TO_DATE( '03:42PM' ,'%h:%i%p')
WHERE activityid = 2
The STR_TO_DATE function is documented here:
https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_str-to-date
The format patterns for STR_TO_DATE are documented here, under DATE_FORMAT:
https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_date-format
FOLLOWUP
Demonstration:
setup
USE test;
CREATE TABLE scheduling (activityid INT PRIMARY KEY, start TIME(6));
-- 0 row(s) affected
INSERT INTO scheduling (activityid) VALUES (2);
-- 1 row(s) affected
execute the update statement in the answer above
UPDATE scheduling SET start = STR_TO_DATE( '03:42PM' ,'%h:%i%p') WHERE activityid = 2 ;
-- 1 row(s) affected
results
SELECT * FROM scheduling WHERE activityid = 2;
-- activityid start
-- ---------- ---------------
-- 2 15:42:00.000000
SECOND FOLLOWUP
Use same sql_mode setting reported by OP:
SET ##sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' ;
Test:
SELECT STR_TO_DATE( '03:42PM' ,'%h:%i%p')
returns
(NULL)
But this more complicated expression:
SELECT TIME(STR_TO_DATE(CONCAT(CURRENT_DATE(),' ', '03:42PM' ),'%Y-%m-%d %h:%i%p'))
returns
15:42:00
The more complicated expression is a workaround to avoid behavior imposed by the STRICT_TRANS_TABLES and NO_ZERO_DATE in the sql_mode.

PHP/MYSQL- Number operation stops at zero

I feel like there is a simple solution, but I cant find it anywhere.
I've got a while() loop and at the beginning of each loop, I subtract 1 from a number that I get from a MYSQL database. But for some reason, it stops at 0. I need the number to go negative if the value pulled from the database is 0 or a negative number.
//Get members
$select = mysql_query("SELECT * FROM members") or die(mysql_error());
//Start the loop
while($members= mysql_fetch_row($select)){
//Get limit
$limit = $members['limit'];
$newlimit = $limit - 1;
mysql_query("UPDATE `members` SET `limit` = '".$newlim."' WHERE `email`='".$members['email']."'");
}
Any advice? This code successfully works until the value gets to 0. But I need it to keep subtraction.
Thanks in advance!
Brandon
Edited: updated the code above. Had an error
My guess is that yout limit column is an UNSIGNED INT. Unsigned numbers can be twice as large as signed numbers, but they cannot have a negative value (hence unsigned).
You could use an ALTER TABLE statement to change the column to INT, but you need to be careful because if any of the values stored in the limit field are greater than 2147483647 (if you change it to a signed INT), these values will not be preserved.
remove the extra = symbol
$newlimit = $limit - 1;
and replace $newlim with $newlimit in your SQL statement
also please note that you could be doing the same thing in a single SQL statement without any loop or php involved:
UPDATE `members` SET `limit`=`limit`-1

How to Handle (Escape) a % sign in mysqlclient (C Library)

i am using mysqlclient,
in one of my query, as shown below
sprintf (query, "select user from pcloud_session where id = '%s'", sid);
here some time this sid is with % sign in it like the example
2Cq%yo4i-ZrizGGQGQ71eJQ0
but when there is this % this query always fail, i think i have to escape this %, but how ?
i tried with \ and %% , but both of this not working, please help me here
UPDATE:
When using session.hash_bits_per_character = 6, in php session ,the default charset contains a character (comma) that will always be urlencoded(here it is %2C). This results in cookie values having this %2C in it, but session db having a comma instead of it. any idea about fixing this problem ?.. sorry for the confusion
Thanks
There's no need to escape a literal '%' in MySQL query text.
When you say the query "always fail", is it the call to the mysql_query function that is returning an error? Does it return a SQL Exception code, or is it just not returning the resultset (row) you expect?
For debugging, I suggest you echo out the contents of the query string, after the call to sprintf. We'd expect the contents of the string to be:
select user from pcloud_session where id = '2Cq%yo4i-ZrizGGQGQ71eJQ0'
And I don't see anything wrong with that SQL construct (assuming the id column exists in pcloud_session and is of character datatype. Even if id was defined as an integer type, that statement wouldn't normally throw an exception, the string literal would just be interpreted as integer value of 2.)
There should be no problem including a '%' literal into the target format of an sprintf. And there should be no problem including a '%' literal within MySQL query text.
(I'm assuming, of course, that sid is populated by a call to mysql_real_escape_string function.)
Again, I suggest you echo out the contents of query, following the call to sprintf. I also suggest you ensure that no other code is mucking with the contents of that string, and that is the actual string being passed as an argument to mysql_query function. (If you are using the mysql_real_query function, then make sure you are passing the correct length.)
UPDATE
Oxi said: "It does not return a SQL Exception code, it just does not return the result[set] I expect. I did print the query, it prints with % in it."
#Oxi
Here's a whole bunch of questions that might help you track down the problem.
Have you run a test of that query text from the mysql command line client, and does that return the row(s) you expect?
Is that id column defined as VARCHAR (or CHAR) with a length of (at least) 24 characters? Is the collation on the column set as case insensitive, or is it case sensitive?
show create table pcloud_session ;
(I don't see any characters in there that would cause a problem with characterset translation, although that could be a source of a problem, if your application is not matching the database charactarset encoding.)
Have you tested queries using a LIKE predicate against that id column?
SELECT id, user FROM pcloud_session WHERE id LIKE '2Cq\%yo4i-%' ESCAPE '\\'
ORDER BY id LIMIT 10 ;
SELECT id, user FROM pcloud_session WHERE id LIKE '2Cq%'
ORDER BY id LIMIT 10 ;
Are you getting no rows returned when you expect one row? Are you getting too many rows returned, or are you getting a different row than the one you expect?
That is an oddball value for an id column. At first, it looks almost as if the value is represented in a base-64 encoding, but it's not any standard encoding, since it includes the '%' and the '-' characters.
If you're going to do this in C without an interface library, you must use mysql_real_escape_string to do proper SQL escaping.
There shouldn't be anything intrinsically wrong with using '%inside of a string, though, as the only context in which it has meaning is either directly inprintftype functions or as an argument toLIKE` inside of MySQL.
This proves to be really annoying, but it's absolutely necessary. It's going to make your code a lot more complicated which is why using low-level MySQL in C is usually a bad idea. The C++ wrapper will give you a lot more support.
You really shouldn't escape the string yourself. The safest option is to let the MySQL API handle it for you.
For a string of maximum length n, start by allocating a string of length 2*n+1:
int sidLength = strlen(sid);
// worst-case, we need to escape every character, plus a byte for the ASCIIZ
int maxSafeSidLength = sidLength * 2 + 1;
char *safeSid = malloc(maxSafeSidLength);
// copy "sid" to "safeSid", escaping as appropriate
mysql_real_escape_string(mysql, safeSid, sid, sidLength);
// build the query
// ...
free(safeSid);
There's a longer example at the mysql_real_escape_string page on dev.mysql.com, in which they build the entire query string, but the above approach should work for supplying safeSid to sprintf.

MySQL select from char column using int - leading zero causes unexpected result

I have the following data:
stockcode (CHAR) | description (VARCHAR)
----------------------------------------------
1234 | some product
01234 | some other product
I run the following code:
$sql = "SELECT * FROM stock WHERE stockcode = " . $db->quoteSmart($stockcode)
$res = $db->query($sql);
If I pass the stock code "01234" in, I get the second row as expected. If I pass in "1234" I get both rows, when I expect to only get the first.
By echoing out the sql statements, it seems to be because only the 01234 stockcode gets quotes around it, the 1234 one doesn't (presumably quoteSmart thinks as it is an integer it doesn't need quoting?).
Mysql is then comparing the int 1234 to the CHAR column, and deciding they both match (presumably it is doing the comparison as ints?)
There are a lot of places in the code which build queries like this, and 99% of the time, the stockcode variable will be alphanumeric, it's only occasionaly entirely numeric, and very rarely contains a leading zero, this is just a fluke occurrence I stumbled across today.
Can anyone recomend an easy solution?
Try explicitly casting your variables to strings:
$db->quoteSmart((string)$stockcode);
// instead of:
// $db->quoteSmart($stockcode);
Edit:
If this does not work, I imagine that quoteSmart() isn't really that smart (or it's trying to be too smart for it's own good), so you'll very likely need to stop using it and stick to bound parameters (which I suggest over this method anyway).
Add quotes so the char in the database don't get converted to numbers for the comparison
$sql = "SELECT * FROM stock
WHERE stockcode = '" . $db->quoteSmart($stockcode). "'"
2nd Version:
$stockcode_str = $db->quoteSmart($stockcode);
if (is_numeric($stockcode_str))
$stockcode_str = "'$stockcode_str'";
$sql = "SELECT * FROM stock
WHERE stockcode = $stockcode_str";

Why MySQL fetches record even if it doesn't match the ID?

I just discovered this, I use MySQL as my database.
When i do something like:
$query = $this->db->where('id', '6rubbish')->get('posts', 1);
it generates and executes this SQL:
SELECT *
FROM (`posts`)
WHERE `id` = '6rubbish'
LIMIT 1
The surprising thing is that it actually fetches the post with the ID 6.
I find this very vulnerable in same cases because i'm trying to exactly match the ID, not to do a LIKE query.
Any ideas?
Yes.
Read Type Conversion in Expression Evaluation
Use intval() PHP function to extract the integer part of the variable
Or use is_int to exclude any variable that is not a pure integer
But the origin of the problem is that your query generator library doesn't understand the variable types, PHP being a dynamic typed language doesn't help too.
I don't know what library you're using, maybe there is an option to tell that you're passing an int? It should protect you from SQL injection, I hope, try with:
$query = $this->db->where('id', "don't")->get('posts', 1);
and see if the generated SQL has the single quoted escaped (doubled or preceded by backslash).
That is because SELECT 6 = '6rubbish' will give you true, and your id is number type.
Your id field is, no doubt, a numeric data type.
When MySQL evaluates expressions, it converts operands to compatible types (see docs).
'6rubbish' (a string) gets converted to 6 (a number) and, hence, you get a match.

Categories