compare single field in mysql for multiple values - php

I Have an array of different ids, I want to iterate this array and use these ids to be compared with a single field in DB Table
Example
classid{
0=>1,
1=>2
}
and I have table as
id name
1 myname
2 ur name
3 everyonename
Now how can i retrieve the values for both id=1 and id = 2 in just a Select query?

The query you want is:
SELECT * FROM table WHERE id IN (1,2)
To create this from PHP, you would use something like
$classid = array(1, 2);
$sql = sprintf('SELECT * FROM table WHERE id IN (%s)',
implode(',', $classid));
You should be ultra careful to prevent SQL injections if the values in $classid are coming from an external source! Normally this is achieved with prepared statements and bound parameters, but in this case (where you want to use IN) this is not possible AFAIK.
Therefore you should sanitize the values yourself, using something like
// This will convert all the values in the array to integers,
// which is more than enough to prevent SQL injections.
$classid = array_map('intval', $classid);
Read more about protecting yourself from SQL injection.

Related

Delete from all tables where ip equals that ip

I have a lot of tables in my SQL database, and I want to delete from all tables from it where the IP matches a certain IP in one statement/Query. Is there a way to do it quickly?
Something like:
DELETE FROM * tables where ip = '$ip';
Is there a way to do this?
Like this
$tables = ['table1','table2','table3'];
foreach($tables as $table){
//DELETE FROM `$table` tables where ip = :ip;
}
Just make absolutely certain you are using prepared statements, and "canned" table names. Never concatenate user input into your sql.
Imagine this $ip = "1' OR 1=1"; Now all your data has been deleted. AKA sql Injection.
Because your innocent query:
DELETE FROM table where ip = '$ip'
Becomes:
DELETE FROM table where ip = '1' OR 1=1
AND 1 is always equal to 1
If you can't see the data your putting in when you look at the query, use prepared statements. Because, you never know when you will re-purpose a piece of code and if it's not done right from the get go, your setting yourself up for a lot of headaches.
This may be a one time thing you are doing, but if you plan to leave the code around, I would still use prepared statements.
Can't you just separate them by a semicolon?
DELETE FROM table1 WHERE id = 1;
DELETE FROM table2 WHERE id = 1;
DELETE FROM table3 WHERE id = 1;
Looking into the details of the question that you have provided. You can do this with the help of Dynamic SQL.
Step 1) With the help of information_schema, prepare the dynamic SQL to delete the record from the table. You will get dynamic SQL like below
Delete from table1 where ColumnName = 'IPAddress';
Delete from table2 where ColumnName = 'IPAddress';
Step 2) With the help of Execute Statement. Run that dynamic SQL and this will delete all the records from those tables where the record has IP address in that column.

Do I need to run a prepared query in Wordpress when I'm just matching table columns?

Simple question - I do understand that if I want to run this type of query in Wordpress:
SELECT * FROM tableA WHERE variable1 = $var1
...then I need to use 'prepare', like so:
$my_query = $wpdb->get_results($wpdb->prepare("SELECT * FROM tableA
WHERE variable1 = %s", $var1) );
However, when I want to do this type of query instead:
join two tables on a column
and NOT use a variable
like this:
SELECT * FROM tableA, tableB WHERE tableA.some_col = tableB.some_other_col
...'should' I:
still use some form of 'prepare' statement to safeguard against SQL injection
or is it ok to do the following:
$my_query = $wpdb->get_results("SELECT * FROM tableA, tableB WHERE
tableB.some_col = tableB.some_other_col");
You dont need prepared statements there because there is no way that anyone could use this code for sql injection.
If you just select everything from two tables without giving any variable you can forget about prepared statements :)
I think you should stick with
$wpdb->prepare
even if you do not have any un-sanitized parameters to pass to the query.
There are few reasons why you should do that:
This is a best practice;
Consistency. If you will use the same approach for all your queries;
If you will need to pass a parameter to this query in future, it will be easier for you.
You find a discussion about this here Should I use wpdb prepare?

Select MySQL table with dynamic content

I have a bunch of tables that are like Client# and the # changes. Is there a way to create a query to query that table based on the client number you get from logging in as their use?
Example to give idea:
$q2 = "SELECT * FROM users WHERE username = '".$_SESSION['username']."'";
$result2 = mysql_query($q2,$conn);
$row = mysql_fetch_assoc($result2);
$_CLIENT_ID = $row['CLIENTID'];
$q2 = "SELECT * FROM client+".$_CLIENT_ID."";
Is there a better way to do this?
I'm trying to keep clients in their own tables so they do not get to massive.
I'm trying to keep clients in their own tables so they do not get to massive.
This is almost always the wrong strategy. The table size isn't as important as how you have indexed it for access, and it can be partitioned later, should that become necessary. The proper way to handle this is simply a column in one table which identifies the client id.
With a proper client-identifying column you can query as:
SELECT othertable.*
FROM
users
JOIN othertable ON users.CLIENTID = othertable.CLIENTID
WHERE users.username = '$_SESSION['username']'
Dealing with dynamic table names becomes troublesome not only because it is more difficult to query against. You cannot, for example, use a placeholder in place of a table name with many parameterized query APIs like PDO & MySQLi:
// Won't work with a PDO prepared statement. :clienttable place holder isn't allowed
SELECT * FROM :clienttable WHERE value=:someval

Filtering SQL Queries Using PHP

I have been searching for a while on a way to select certain columns (fields) in SQL.
What I am trying to do is this... Lets say I have a table with 200 columns of data. I want to select an entire row but only the last 197 columns of data. Leaving out the first 3 columns that have dates and ID's.
It would be very time consuming to type out the 197 field names I wanted the data from. There has to be some easier way of doing it.
Any help or suggestions to point me in the correct direction?
If you are using MySQL, try something like this:
<?php
$query = "
SHOW COLUMNS FROM `Table`
WHERE `Field` NOT LIKE 'rowtoignore1'
AND `Field` NOT LIKE 'rowtoignore2'
AND `Field` NOT LIKE 'rowtoignore3'
";
$r = mysql_query($query) or die(mysql_error());
$queryfields = "";
while($f = mysql_fetch_assoc($r)) {
$queryfields .= "`{$f['Field']}`,";
}
$queryfields = substr($queryfields,0,strlen($queryfields)-1);
$query = "SELECT {$queryfields} FROM `Table` WHERE xyz";
?>
If you're using MySQL you can query the schema to get a column name by index, so you could use an iterative PHP routine to build your query, but it would require 197 select statements before you could run the one you really want. Messy and inefficient.
It seems simpler to do a SELECT * and then ignore the first three columns. If you use mysql_fetch_assoc() you can get the columns you want easily. Take a look at:
http://php.net/manual/en/function.mysql-fetch-array.php
If i am doing this task, i won't exclude the first 3 columns . If the 3 columns contains lengthy text / blob , then you could avoid, else better fetch those 200 columns .
Using this function mysql_list_fields() fetch fields corresponding to a table , and customize the select query to include required fields

SQL injection even when the variable is escaped [duplicate]

This question already has answers here:
How can I prevent SQL injection in PHP?
(27 answers)
Closed 2 years ago.
The sql injection will work only when my query looks like below sample
SELECT * FROM login WHERE id = $my_id_va;
Assume if my query is
SELECT * FROM login WHERE id = $my_id_va ORDER BY id DESC
Than I will get following 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 'order by id desc' at line 1
So, this 1 or 1=1; SHOW TABLES will not work, correct?
My site was hacked successively many times.
I want one quick answer: When my query looks like the following one, what ways or which types of query can they use to hack my site?
SELECT * FROM login WHERE id = $my_id_va ORDER BY id DESC
What are the ways to execute the show table in the following query
SELECT * FROM login WHERE id = $my_id_va ORDER BY id DESC
I am also using escaping function to handle the query string values, like mysql_real_escape_string($my_id_va). Yes, obviously this for single related hack, but not sure.
Added some more
SELECT EventActuallyCharged, EventDate FROM tblevent WHERE EventDate between '2011-07-21 or 1=1; SHOW TABLES --' and '2011-07-31' ORDER BY EventDate DESC
but show table not worked
If you are using PHP5, use parametarized query, use PDO.
Int cast
If id is a number, you can int-cast your variable as well. Integers are safe to use:
$x = (int)$yourInputVar;
$s = "select * from Table where id = $x";
mysql_real_escape_string
If you want to pass a string, you can, and should, use mysql_real_escape_string, but this function escapes only those characters that are inside the string. You will still need to add quotes around the string, so:
$x = mysql_real_escape_string('hello');
$s = "select * from Table where id = $x";
.. will result in the query: select * from Table where id = hello. This is obiously not a valid query, since hello should be in quotes.
Change the query to:
$x = mysql_real_escape_string('hello');
$s = "select * from Table where id = '$x'";
.. and everything works fine. You add the quotes around, and mysql_real_escape_string takes care of special characters inside the string, if any.
Parameters
Another solution is to use parameterized queries. This can by done using MySQLi or PDO. The advantage is that you only tell your database where a variable should be inserted, and the database takes care of the escaping yourself.
It also may add a performance benefit, because these queries could be cached without their parameters, make a more efficient use of the query cache. This doesn't really work yet in current versions of MySQL, though.
You are right that 1 or 1=1; SHOW TABLES will give a syntax error but this will work:
1 or 1=1 --
The -- comments out the rest of the query.
In your case the value is an integer so instead of using mysql_real_escape_string you can use intval.
If you set $my_id_va to:
1 or 1=1; SHOW TABLES --
The -- will comment out the rest of the command, effectively terminating it.
I'm not sure what effect mysql_real_escape_string will have on the query. What you should be doing is parameterized queries.
1. First query somehow secured
$sql = sprintf('SELECT * FROM login WHERE id = %d ORDER BY id DESC', mysql_real_escape_string($my_id_va));
2. Second query somehow secured
$sql = sprintf("SELECT EventActuallyCharged, EventDate FROM tblevent WHERE EventDate BETWEEN '%s' AND '%s' ORDER BY EventDate DESC",
mysql_real_escape_string($start_date),
mysql_real_escape_string($end_date));
Read the docs about sprintf if you don't understand it.
However, as others have said, it would be very very secure if you would use parameterized queries with a class such as PDO or MySQLi.

Categories