Mysql type hidden type casting - php

I am trying to improve an old system (written ages ago) where every mysql queries are glued from string. So example of that query looks like
"SELECT * FROM User WHERE id > '3'"
Id column is of course bigint and PK.
What does mysql do with '3' in query where id should be a int value? I assume it is treated as a string (due to '') so this value is casted into int during analyze/optimize process by mysql. Am I right?
//UPDATE
I probably asked wrong way. There are two way to handle it.
(Fast) Mysql automatically detects that id should be int and rewrite/cast a query to
SELECT * FROM User WHERE id > 3
before send it to DB engine
(Unbelievable) Mysql does
SELECT * FROM
then in loop apply condition WHERE id > '3' and cast it for EVERY row
I just want to be sure that second option is impossible.

MySQL will always cast the string to a number for comparing, which in this case this is the right thing to do (it will use the index on the column to find the values).
If your column is a string and you compare it to an integer constant MySQL will cast the column to an integer and not use the index.

MySQL will automatically cast it into the correct column type. If it cannot for some reason, it will throw an error.
Make sure to use prepared statements with PDO or MySQLi in any case where the parameter may come from an unsafe source (the user, an external API).

Related

How to make MySQL strict on types

Here's the scenario, we are building a web application in Laravel, and assigned a route as follows:
Route::get('/sample/{client}', 'SampleController#SampleMethod')->name('SampleNaming');
The method SampleMethod, reads from the client variable and displays data about the client in the page.
if we go to http://localhost/appurl/sample/1 for example, it displays data about client id 1. The trick is that if we go to http://localhost/appurl/sample/1abc , it will still display the data for client id 1.
Tried the query in MySQL,
select * from clients where ID = '1abc'
The ID column is an integer and the primary key of the clients table.
The above query gave me the result for Client ID 1, turns out that MySQL checks the provided string and searches for the integer part in it and fetches the rows accordingly.
Surely, we can escape this in PHP / Laravel however my question is, is there a way to make MySQL strict on such scenarios?
Pure Laravel solution is to use Regular Expression Constraints.
Route::get('/sample/{client}', 'SampleController#SampleMethod')
->name('SampleNaming')
->where(['client' => '[0-9]+']);
you probably need to change sql_mode setting for your server. you need to use strict mode.
enter link description here
preventing type casting is not configurable in mysql. mysql implicit type casting rules
you can use the cast function to solve the issue at the sql level
select * from t where cast(id as char) = "1abcd"

Sql returns empty row on combinning primary key with another value in where clause

I am getting empty row on following sql
SELECT * FROM flyers WHERE fId='6' AND 'userId'='400'
MySQL returned an empty result set
(i.e. zero rows). (Query took 0.0004 sec)
But when i use
SELECT * FROM flyers WHERE fId='6'
Showing rows
0 - 0 (1 total, Query took 0.0005 sec).
As i got my result and that is correct using only primary key.
But i does not know why mysql returns empty row on using AND with primary key.
Note:- fId is flyer table primary key.
Try this:
Use back ticks for the column name not single quotes
If userid is int data type it means you have to remove single quotes userid=400
If fid is string it means fID='6'
SELECT * FROM flyers WHEREfId=6 ANDuserId=400
In your query you have only one mistake, which is that you used single quotes around userId. Use back-ticks instead or nothing:
SELECT * FROM flyers WHERE fId='6' AND userId='400'
SELECT * FROM flyers WHERE fId=6 AND userId=400// safe not to use quotes
But I suggest not to use quotes around numbers for below reason.
The real issue comes down to type casting. When you put numbers inside quotes, it is treated as a string and MySQL must convert it to a number before it can execute the query. While this may take a small amount of time, the real problems start to occur when MySQL doesn't do a good job of converting your string.
For example, MySQL will convert basic strings like '123' to the integer 123, but will convert some larger numbers, like '18015376320243459', to floating point. Since floating point can be rounded, your queries may return inconsistent results.

Retrieving one integer value from database using php

How do I fetch an integer value from the database?
$query = mysql_query('select number from table_name where UNIQUE_ID =SOME_UNIQUE_ID');
I am unable to access the integer value using the query above.
As many have commented, it's unclear what is the problem your are facing.
The $query variable you are obtaining is NOT the integer you want but a "query object" (or False if the query failed). You have to extract at least a row using (e.g.) $t=mysql_fetch_array($query). The wanted value will be in $t[0].
Keep in mind, anyway, that the result of a query is tipically a string, so you have to extract its integer value using intval($t[0]).

How to check if a column value is in a string SQL

I have a database with 150,000 records and I need to match its FULL column value or records, with some parts of the string.
**
As i want to check if the STRING contains the COLUMN records and NOT!
if the COLUMN contains the string
**
(Example below)
For testing purposes
Lets say the database has a TABLE , 1 COLUMN and 1 record as the records are similar to this:
come to me
and i need to match it with this #STRING
She wants to come to me now
I want to execute something similar to :(but this doesn't work of course)
SELECT * from TABLE where #STRING like '%'+COLUMN+'%'
I can't seem to solve this with SQL the usage of PHP is possible but prefer if the solution is with SQL but if the solution with PHP is available please propose it and note that the database has over 150,000 records
SELECT * from TABLE where LOCATE(COLUMN, #STRING)>0;
LOCATE(a,b) returns a number giving the character location of a in b, or returns 0.
See Mysql LOCATE()
The docs discuss that LOCATE() is only case sensitive when one of the strings is a 'binary string'. That probably doesn't affect your use case, though if it became an issue you could CONVERT() the binary strings to a locale and use LOWER() to get lower case.
MySQL String Functions
The dynamic like syntax for mysql is
SELECT * from TABLE where #STRING like CONCAT('%',COLUMN,'%')

Wrong result from query

I have this simple query
SELECT *
FROM `book`
WHERE `BookID` = '7u'
LIMIT 1
i expect empty result
But i see one result with book id =7.
BookID is auto increment.
Why query ignore 'u' character?
Because 7u is not numeric, so apparently mysql is ignoring the u.
Maybe you are thinking of some high level programming languages which use suffixes to qualify the type of number? In C-derived languages, 7u would be an unsigned integer with value 7.
Just because of two reasons:
There may be only one record.
you were using LIMIT 1. That display only one record from the output. so use LIMIT 5 OR 2.
the mysql takes the string as 7u so when you try to do this stuff it coverts in a string but mysql is not in strict mode so it coverts string into integer because your id is intenger and its rounding of 7u becomes 7 thats why its display the one record try without quote 7u instead of '7u' then it gives error

Categories