MySQL: Searching number column with string parameter - mysql

Let's say we have a record in table 'orders' with id=1. This query:
SELECT * FROM 'orders' WHERE id = 'abc1'
won't return mentioned record. But this query:
SELECT * FROM 'orders' WHERE id = '1abc'
will return the record with id=1. This is because when MySQL converts string to number 'abc1' becomes 0, but '1abc' becomes 1. Is there a nice way to make MySQL search strictly for records with id from query, i.e. not return the record with id=1 in both mentioned cases?

What about using :
SELECT * FROM 'orders' WHERE id LIKE '1abc' COLLATE utf8_bin
or even
SELECT * FROM 'orders' WHERE STRCMP(id, '1abc') = 0;

I handled it with PHP before submitting the SQL query
$idTest = '1abc';
if (is_numeric($id){
$query = "SELECT * FROM 'orders' WHERE id = '$idTest'"
}
This will prevent submitting queries if the $idTest has a string

Related

Operator precedence and type conversion in MySQL (more than one comparison operators in WHERE clause)

I am new in pentest and have a question about MySQL's Operator Precedence and Type Conversion. (more than one comparison operators in WHERE clause)
The table structure is shown as follows (DVWA users table):
user_id int(6)
first_name varchar(15)
last_name varchar(15) .....
I tested the results of the following queries (in MySQL 5.7). (P.S.These queries are used for bypass or simply for fun)
SELECT * FROM users WHERE user_id = 1&1=1;
SELECT * FROM users WHERE user_id = 1&1=0;
SELECT * FROM users WHERE user_id = 0&1=0;
SELECT * FROM users WHERE user_id = 1&0=1;
The first one returns 1 record (user_id = 1), The second query returns all records except user_id =1 one. The third one returns all records and the last one returns no record.
The previous four queries have the same output with the following four queries as Bitwise AND (&) has the highest precedence:
SELECT * FROM users WHERE user_id = 1=1;
SELECT * FROM users WHERE user_id = 1=0;
SELECT * FROM users WHERE user_id = 0=0;
SELECT * FROM users WHERE user_id = 0=1;
My question is: What is the precedence of the two comparisons? (as boolean is tinyint(1) and there should be no conversion when comparing int(6) and tinyint(1), not like comparing string and int) Lastly, I also test SELECT * FROM users WHERE user_id = 0<1; and SELECT * FROM users WHERE user_id =0=1=0; which got the same results as the third one.
It really seems weird to me.
Thank you all for the help.

sub query returns more than 1 - issue with passing values into subquery

I am running the following query which keep stating that more then one row is given:
select filestorage.id
from `filestorage`
where (SELECT LEFT(filestorage_inst_data.value, length(filestorage_inst_data.value - 1)) as seconds
FROM filestorage_inst_data
WHERE filestorage_inst_data.parameter = "Time" AND filestorage_inst_data.filestorage_id = filestorage.id) <= 3600
For some reason, the only very first value is passed into the subquery. Also, if I do set a limit within the subquery than the data is fetched fine, it's just I don't see why query would fetch multiple results?
Try this:
SELECT filestorage.id
FROM filestorage f
WHERE EXISTS(SELECT 1 FROM filestorage_inst_data fid
WHERE fid.parameter = 'Time'
AND fid.filestorage_id = f.id
AND CAST(LEFT(fid.value, length(fid.value - 1)) AS UNSIGNED) <= 3600)
You have to pass a specific one row when giving a select statement on where clause. select clause that, the one you using on where clause must return one unique row. for example.
"SELECT * FROM user WHERE role_id=(SELECT role_id FROM user_role WHERE role_name='Admin');"

Insert into a different table for each result of a select query

If I have a setup such as:
set #idToIgnore = (select user_id from user_field_value where user_field_id = 82 and value = 'No';
Then I run a select query:
select id from users where account_id = 10 and id != #idToIgnore;
Which returns ~15 different ID values.
I then want to run a query such as:
insert into user_field_value(user_id, user_field_id, value) values (**user_id**, 82, 'Yes');
where user_id in the final insert query is each of the id's from the second query.
I assume there is an easy way to do this but I can't figure it out.
Why not just do that in one INSERT INTO ... SELECT ... query?
INSERT INTO user_field_value(user_id, user_field_id, value)
SELECT id, 82, 'Yes' FROM users
WHERE account_id = 10 and id != #idToIgnore;
You can also do the whole thing in one query using subquery instead of #idToIgnore, but be careful in the matter of performance.

Combine Update and Select Query

I got two MySQL working fine and i'm trying to find a way to combine them into one single query.
First, it selects ID of an employee.
SELECT 'ID' FROM `employee` ORDER BY ID DESC LIMIT 1;
Let's say it returns ID 100;
Then update data of employees whose ID is 100
UPDATE 'LOG' SET `TIME_EXIT`='2013/02/22' WHERE `ID`='100';
Can i do it all in a single query?
Just add them together:
UPDATE LOG SET TIME_EXIT = '2013/02/22'
WHERE ID = (
SELECT ID
FROM employee
ORDER BY ID DESC
LIMIT
);
But based on that code currently it'll only ever update the last employee, you will need to select the correct employee by using some other identifier to ensure you have the correct one.
UPDATE LOG SET TIME_EXIT = '2013/02/22'
WHERE ID = (
SELECT ID
FROM employee
WHERE NAME = 'JOHN SMITH'
ORDER BY ID DESC
LIMIT 1
);
It's now a few months old, but maybe helps you or others finding this via google…
If you want to UPDATE a field in the same selected table use this:
UPDATE LOG SET
TIME_EXIT = '2013/02/22'
WHERE ID = (
SELECT ID
FROM (
SELECT ID
FROM LOG
WHERE whatEverYouWantToCheck = whateverYouNeed
) AS innerResult
)
So, you SELECT id from a subselect. If you try to subselect it directly, mySQL quites with your error message You can't specify target table 'log' for update in FROM clause, but this way you hide your subsubquery in a subquery and that seems to be fine. Don't forget the AS innerResult to avoid getting the error message #1248 - Every derived table must have its own alias. Also match the subsubquery field name to the subquery field name in case you do something like SELECT COUNT(*) or SELECT CONCAT('#', ID)

How do you get the seed fieldname from a table programmatically?

Is there anyway to get the seed fieldname?
What I mean by seed is the field that's been created with something like this;
INT NOT NULL AUTO_INCREMENT PRIMARY KEY
I plan on using this ( getting the seed field name pro grammatically ) in coming up with the fastest SQL query to get the number of records in a table.
The function I plan on writing is something like this. Please fill in the blanks and provide the getSeed function inner mechanics.
function get_record_count ($dbh,$table,$where){
//get the seedfield name in the {table} programmatically
$seed = getSeed($dbh,$table);
$sql = "select count({$seed}) as `count` from {$table} " . $where;
//do the mysql query & get num rows to return it...
}
If you're not trying to count the number of non-NULL values in the column (COUNT(expr) doesn't count NULLs), then just use SELECT COUNT(*) and let MySQL use the same index that is used in the WHERE clause to answer COUNT(*).
$sql = "SELECT COUNT(*) AS `count` FROM {$table} " . $where;