Imploded PHP integer array for Mysql NOT IN clause - php

I've been trying to use a PHP integer array for a MySQL query that uses the NOT IN clause, but despite no errors it seems to always return the results I want filtered out.
Example:
$IDS = $_SESSION['Posts'];
$Select = 'SELECT *
FROM status
WHERE (W_ID = '.$ID.')
AND (ID NOT IN ("'.implode(',', $IDS).'"))
ORDER BY ID DESC
LIMIT '.$Begin.', '.$Number.'';
$Select = mysql_query($Select) OR DIE(mysql_error());
I'm pretty sure this is a logical syntax error.
What I've tested for:
I've made sure that $IDS is treated as an array. Also I have tested to see whether there are values stored within the array. I have also not quoted the integer array, but then I got a mysql syntax error for not having them.

The problem is the two ” in the beginning and the end of the IN block. They cause the entire implode array to become a comma-separated string.

Your actual query will look like this:
ID NOT IN ("1,2,3,4")
"1,2,3,4" is one string, not several values. Get rid of the " quotes.

You could try to use FIND_IN_SET rather than an IN clause.
$IDS = mysql_real_escape_string(implode(',', $IDS));
$Select = "SELECT * FROM status WHERE (W_ID=$ID)
AND (NOT FIND_IN_SET(ID, '$IDS'))
ORDER BY ID DESC LIMIT $Begin, $Number";
Anyway in SQL you are required to use single quotes for strings, not double quotes. That works with MySQL, but not for all configurations. Also gets more readable if you do it the other way round. (Single quotes in PHP for performance is retarded advise!)

Related

PHP SELECT returns empty using IN and implode

I have been at this for almost two hours and I'm pretty sure I'm just missing something simple. I have tried multiple iterations without success. SO searches have given insights but nothing exactly like this to see were I'm going wrong. Your input will be appreciated.
I have an array built [$prime_ids] made up of user IDs (individual email addresses). This is the look of the finished array:
["james.pruit#abcnet.com", "dan.smith#abcnet.com", "nathan.jones#abcnet.com", ...
Now I need to find matches in this list against matches in a database table. Note: there can be multiple matches with the information contained in the table (meaning a single user ID may show up multiple times in the list). That is being done for a specific reason.
My understanding is I need to use implode to make this work. Here is my query:
$sql_query = "SELECT * FROM worksheet4 WHERE worksheet4.user_id IN (" . implode(",", $prime_ids) . ");";
$result = $dbc->query($sql_query);
I then run a loop to build a second array ($kp_positions). Here is my code:
while($row = mysqli_fetch_assoc($result)) {
$kp_positions[] = $row;
}
This returns an empty array. While debugging I tried the same SELECT query using WHERE instead of IN and implode:
WHERE user_id = 'dan.smith#abcnet.com'";
... and it works perfectly (but only for this single-user). Thinking this might have something to do with single quotes (') in the implode statement I tried every possible combination that made sense without avail. Because this works perfectly with a single user ID, where my going wrong in my implode statement? Or, am I going about this the wrong way? Thank you.
if you print your query you will get something like this:
SELECT * FROM worksheet4 WHERE worksheet4.user_id IN (james.pruit#abcnet.com,dan.smith#abcnet.com,nathan.jones#abcnet.com);
Note that each member within the "in" should be wrapped in quotes
so try to run this line:
$sql_query = "SELECT * FROM worksheet4 WHERE worksheet4.user_id IN ('" . implode("','", $prime_ids) . "');";
and get
SELECT * FROM worksheet4 WHERE worksheet4.user_id IN ('james.pruit#abcnet.com','dan.smith#abcnet.com','nathan.jones#abcnet.com');
Another option, in my opinion better, is to use json_encode() to quote it.
$prime_ids = array_map('json_encode', $prime_ids)
https://3v4l.org/HPL2o
Then without quotes, which json_encode() adds for you:
$sql_query = "SELECT ... IN (" . implode(",", $prime_ids) . ")";
This will escape quotes that may exist, which is good.

How to force int as string in prepared statement

I'm working on syncing two PostgreSQL databases using a PHP script. I am not able to query the entire table so I have to use an id column to grab records in batches.
The id column is a string column, not numeric. However, there are numerical ids in the column. This is where I'm having an issue.
When I prepare the SQL statement in PHP, when I happen to get an id that is numeric, when I bind it to the statement, it doesn't put quotes around the value because it thinks its an int, not a string.
How do I force it to be a string and always put single quotes around the id??
If I put the quotes around the ? in the query it treats it as text and the parameter doesn't get bound to the statement.
As you can see in the code I also tried casting the $start variable as a string. $start contains the starting id.
Here is the code:
$sql = "select id from properties where id > ? order by id limit ?";
$params = [(string) $start, 50000];
$rows = $this->wolfnet->select($sql, $params);

Fat Free Framework PHP Sql statement with in expression

I'm trying to include a list of strings to be used in an "in" expression in a sql statement for example:
select * from poop where id in ('asd','sas','ser')
I want to pass the in parameter from a variable. The quoting is really screwing me up. Should I be passing this as a string which I have been trying to no avail by making a comma seperated string that looks like this:
282366381A,240506808A,244154247A,491404349A,242443808B,328409296A,239723812A,383423679M
or "282366381A","240506808A","244154247A","491404349A","242443808B","328409296A"
or
'282366381A','240506808A','244154247A','491404349A','242443808B','328409296A'
None of these work or is there a different way using an array of values?
This is the statement I'm using with the string:
$cernerResults = $this->cernerdb->exec( "select
pat as HICN,
from pat
where
HICN in ( ? )", $hicsString );
Edit:
I was able to get around this by constructing the entire query as a string like this:
$query = "select pat as HICN from pat where HICN in (".$hicsString.")";
$hicsString has single quotes around each item like so:
'282366381A','240506808A','244154247A','491404349A','242443808B','328409296A'
The problem is that providing the string to the exec would result in no results. When looking at the freetds log file the in expression values would be double quoted as a whole or each one would be double single quoted and if i used no quotes they would not be quoted at all.
All of these would make the statement return no results. I should also mention that this is a Sybase database.
I think your problem may come from the fact that PDO parser needs to have one value per question mark so it is able to validate it. So your "hack" with one question mark which is assigned to more than one value is where it fails IMHO.
This is how I handle case like that:
$values = ['asd','sas','ser'];
$count = count($values);
$results = $db->exec(
"select * from poop where id in ( ?".str_repeat(", ?", $count-1).")",
$values
);
In general I would advice you using data mappers instead of running the queries on a DB object. It is easier to iterate through them and it is more secure.

Double quotes in PHP

I don't know PHP at all, so I am struggling through this. I need to add an or section to a MySQL query, but the values I'm searching have double quotes. I need to figure out how to add them in PHP so they are passed in to MySQL. The current query looks like:
$query = 'SELECT * FROM ' .$tableName.' WHERE allowed_countries LIKE "%'.$regionId.'%" and skurules REGEXP "i:'.$secondlastdigit.';" and status = 1 ORDER BY id DESC LIMIT 1';
But I need to add an or statement to search for string values that looks like:
$query = 'SELECT * FROM ' .$tableName.' WHERE allowed_countries LIKE "%'.$regionId.'%" and skurules REGEXP "i:'.$secondlastdigit.';" or skurules REGEXP "s:1:'.$secondlastdigit.';" and status = 1 ORDER BY id DESC LIMIT 1';
with double quotes surrounding the second instance of '.$secondlastdigit.'; when passed into MySQL.
My JSON string I'm searching looks like this:
a:12:{i:1;s:2:"15";i:2;s:2:"10";i:3;s:2:"30";i:4;s:2:"50";i:5;s:3:"120";i:6;s:3:"240";i:7;s:3:"480";i:8;s:3:"960";i:9;s:4:"3786";s:1:"A";s:3:"100";s:1:"C";s:2:"60";s:1:"B";s:5:"18930";}
First of all: DON'T.
If you still want to, then...REALLY DO NOT.
Making SQL queries on serialized arrays is just hell. You should try to avoid it at all costs.
Either:
Convert the serialized column into a standard SQL table
or select the column into a PHP variable, unserialize it and search through it.
Example:
$properPhpArray = unserialize($sqlResult['column_name']);
Agreed, searching serialized string is not the best solution and what the developer did despite having a bottle_size table available. I needed a quick fix and no time/skill to rewrite a tax calculation magento extension so I used replace in the query to solve my problem for now.
Since "s:1:X" will always be just one alpha character after the 1 and will not match anything else. I change the query to:
$query = 'SELECT * FROM ' .$tableName.' WHERE allowed_countries LIKE "%'.$regionId.'%" and skurules REGEXP "i:'.$secondlastdigit.';" or replace(skurules,char(34),0) REGEXP "s:1:0'.$secondlastdigit.'0;" and status = 1 ORDER BY id DESC LIMIT 1';
Very hackish fix but gets me out of a bind for now..
Mark

php multiple AND Select Query

Hi There I'm trying to get some data with this SELECT statement and when I just select two items it gives me result but when I place third item it doesn't give any result.
$Query="SELECT * from tableName WHERE status='true' AND gid='".$gid."' AND section='".$cid."'";
Plz any solution.
this one works fine, but when I add third item status='true'. doesn't work.
$Query="SELECT * from tableName WHERE gid='".$gid."' AND section='".$cid."'";
First, let me say this: Double-quoted strings can parse your variables, so this line can work, too:
$Query="SELECT * from tableName WHERE gid='$gid' AND SECTION='$cid'";
Try to learn PHP basics about using single ' and double " quotes here: What is the difference between single-quoted and double-quoted strings in PHP?
Related to the database query, is status field is present in your database table? If not, it should NOT be included within the database, or it will return FALSE boolean value. Instead, use IF if you want to be 'selectively' filtering the status of the table.
if('your conditions here'){
$query = "SELECT * FROM tableName WHERE gid='$gid' AND section='$cid'";
}
I think your mistake is the status='true'
probable the database control its field with 1 or 0 value.

Categories