pdo query not executing when passing a variable as the query - php

I have a pdo command like this $sql = $pdoObj->execute($query) but it does not work, 0 result returning. I echo'ed out the $query variable just before calling execute() and then pasted it inside the execute() and the code ran successfully. I can't understand what is the problem here as I have done this in other parts of my code without problems.
Here are some examples of the queries:
SELECT s.id, s.marca, s.colore, s.prezzo, i.id_scarpa, i.taglia FROM scarpe AS s INNER JOIN info_scarpe AS i ON i.id_scarpa = s.id WHERE 1 = 1 AND taglia IN ('40','41','42') AND colore IN ('rosso', 'nero')
SELECT * FROM scarpe WHERE 1=1
SELECT * FROM scarpe WHERE 1=1 AND marca IN ('adidas','nike')
They are all dynamic generated queries based on the $_GET variable.
EDIT:
Sure
if ( isset($_GET) ) {
if ( isset($_GET['taglia']) ) {
$query = "
SELECT
s.id, s.marca, s.colore, s.prezzo, i.id_scarpa, i.taglia
FROM
scarpe AS s
INNER JOIN
info_scarpe AS i
ON i.id_scarpa = s.id
WHERE
1 = 1
";
foreach ( $_GET as $index => $val ) {
$a = explode(',', $val);
$in = "'" . implode("','", $a) . "'";
$query .= ' AND '.$index.' IN ('.$in.')';
}
} else {
$query = " SELECT * FROM scarpe WHERE 1=1";
foreach ( $_GET as $index => $val ) {
$a = explode(',', $val);
$in = "'" . implode("','", $a) . "'";
$query .= ' AND '.$index.' IN ('.$in.')';
}
}
echo 'data loaded';
} else {
$query = " SELECT * FROM scarpe ORDER BY id DESC ";
}
EDIT2:
I use query() and not execute() but still does not work

The arguments for execute should be an array with query parameters. You mean to use either
$result = $pdoObj->query($query);
OR
$stmt = $pdoObj->prepare($query);
$stmt->execute();

Related

SQL Statement: Getting results based on 2 values

I've got a pretty complex SQL statement and want to add a WHERE clause that only selects results WHERE the hidden column IS NOT '1', however it needs to relate to a specific user.
i.e If in table 1 hidden is 1 and userid is 1 I don't want to get this results. However as there is no record for user 2 in that table I want them to see it.
This is what I have managed to get working so far:
$where .= " AND uh.hidden IS NULL ";
However if I login as User 2 then I see the same results as user 1.
How do I make it so results are shown based on the user too?
SQL query:
$pdo = new PDO('mysql:host=localhost;dbname=myDB', 'root', 'root');
$select = 'SELECT tl.id,
tl.name,
tl.locale,
ROUND(AVG(pr.rating),0) AS rating ';
$from = ' FROM theList AS tl ';
$join = ' LEFT JOIN post_rating AS pr ON tl.id = pr.postid ';
$join2 = ' LEFT JOIN user_hidden_list AS uh ON uh.est_id = tl.id ';
$opts = isset($_POST['filterOpts']) ? $_POST['filterOpts'] : [''];
$where = ' WHERE 1 = 1 ';
if (in_array("pub", $opts)) {
$where .= " AND pub = 1";
}
if (in_array("bar", $opts)) {
$where .= " AND bar = 1";
}
$where = ' WHERE uh.hidden IS NULL ';
$group = ' GROUP BY tl.id, tl.name ';
$sql = $select . $from . $join . $join2 . $where . $group;
$statement = $pdo->prepare($sql);
$statement->execute();
$results = $statement->fetchAll(PDO::FETCH_ASSOC);
$json = json_encode($results);
echo($json);

PHP MySQL $_POST

I am trying to create a PHP form using MySQL database.
I have created a dropdown list with the names of samples (like Al, Au...) and a textbox for the values.
My problem that the units are in my database sometimes in ppm, sometimes in pph.
How can I set if the values are in pph, use the $value=$_POST["value"]/10000;
if the values are in ppm, use $value=$_POST["value"]?
Any idea?
My code:
<?php
if (isset($_POST["sample"]))
{
$sample = $_POST["sample"];
$unit = mysql_query("SELECT unit FROM analysis where sample='" . $sample . "'");
if ($unit == 'pph')
{
$value = $_POST["value"] / 10000;
$sql = "SELECT
a.sample,
concat (a.modif, (IF (unit='pph',10000*value,value))),
a.method,
a.mkey,
b.name,
b.from,
b.to,
b.type
FROM
anlysis a,
sample b
WHERE
a.mkey=b.mkey AND sample = '$sample' AND value > '$value'";
$result = mysql_query($sql);
}
else
{
$value = $_POST["value"];
$sql = "SELECT
a.sample,
concat ( a.modif, ( IF (unit = 'pph', 10000 * value, value) ) ),
a.method,
a.mkey,
b.name,
b.from,
b.to,
b.type
FROM
anlysis a,
sample b
WHERE
a.mkey = b.mkey AND sample = '$sample' AND value > '$value'";
$result = mysql_query($sql);
}
}
Thank you!
Here's what I'd suggest:
<?php
if (isset($_POST["sample"])) {
$sample = htmlspecialchars(trim($_POST["sample"])); //A little clean-up wont hurt...
$unit = mysql_query("SELECT unit FROM analysis where sample='" . $sample . "'");
if ($unit == 'pph'){
$postVal= htmlspecialchars(trim($_POST["value"]));
$value = $postVal / 10000;
$sql = "SELECT a.sample,
concat (a.modif, (IF (unit='pph',10000*value, value))),
a.method,
a.mkey,
b.name,
b.from,
b.to,
b.type
FROM
analysis AS a
LEFT JOIN sample AS b
ON a.mkey=b.mkey
WHERE
a.sample='" . $sample . "' AND a.value > '" . $value ."'";
$result = mysql_query($sql);
}
else
{
$postVal= htmlspecialchars(trim($_POST["value"]));
$value = $postVal;
$sql = "SELECT
a.sample,
concat ( a.modif, ( IF (unit = 'pph', 10000 * value, value) ) ),
a.method,
a.mkey,
b.name,
b.from,
b.to,
b.type
FROM
analysis AS a
LEFT JOIN sample AS b
ON a.mkey=b.mkey
WHERE
a.mkey = b.mkey AND sample = '" . $sample . "' AND value > '" . $value . "'";
$result = mysql_query($sql);
}
first
$analysis = mysql_fetch_object($query);
then you can access the value
if ($analysis->unit == 'pph')

PHP MySQL check if items in array exist in Table, THEN SHOW

PHP 5.4 with MySQL
Building off of this:
<?php
$arr = ...
$sql = 'SELECT COUNT(*) FROM table WHERE field IN ( ' . implode( ',', $arr ) . ' );';
$result = $db->query( $sql );
?>
How would I display which items of the array ARE NOT in the table?
Instead of returning the count, return the field itself:
$sql = 'SELECT field WHERE field IN ' . implode( ',', $arr ) . ' );';
$result = $db->query($sql);
$found = array();
while ($row = $result->fetch_assoc()) {
$found[] = $row['field'];
}
Then you can compare the two arrays:
$not_found = array_diff($arr, $found);
If your $arr variable is sanitized and safe to build a query with, you can use union operators to build a table containing all the words in the array, then you can left join that table to table.field and only keep array items where there was no match.
$arr = array('one','two');
$sql = "select item from (
select '" . implode("' item union select '",$arr). "' item
) t1 left join table t2 on t2.field = t1.item
where t2.field is null";
this will produce the following sql
select item from (select 'one' item union select 'two' item) t1
left join table t2 on t2.field = t1.item
where t2.field is null
Just to give an idea (this probably won't work)
$arr = ...
$sql = 'SELECT field FROM table WHERE field IN ( ' . implode( ',', $arr ) . ' );';
$result = $db->query( $sql );
while($r = $result->fetch())
$arr2[] = $r['field'];
print_r(array_diff($arr,$arr2));
after you've done imloud, array ceases to be an array, this is a string, so you do not have to select count(*). You need to select id after do the while and compare arrays
Just use "NOT IN", if your items is up to 10 elements:
<?php
$arr = array('one','two');
$filterExisting = "'" . implode("', '", $arr ) . "'";
$sql = "SELECT COUNT(*) FROM table WHERE field NOT IN (". $filterExisting .")";
$result = $db->query($sql);
?>

how can I avoid to many OR statements in a mysql query?

I am writing a code, where I have to produce a query with many OR statements, and I think there is a more comfortable way to this than:
foreach ($plz as &$value) {
if (empty($i)) {
$query = "WHERE plz='$value'";
} else {
$query = "$query OR plz='$value'";
}
$i++;
}
$sql = mysql_query("SELECT * FROM table $query");
while ($data = mysql_fetch_array($sql)) {
//do something
}
If you have multiple values a column may take, just connect them using the IN operator:
Instead of writing
... WHERE col=1 OR col=2 OR col=3
just write
... WHERE col IN (1,2,3)
To collect all entries in PHP, use an array and implode() later on:
// collecting values
$vals = array();
$vals[] = 1;
$vals[] = 2;
// ...
// add them to your query
$query .= ' WHERE col IN ( ' . implode( ',', $vals ) . ')';
// execute the query ...
In case your values are not integer, but need to be enclosed in apostrophes within the query, insert them that way into the array in the first place:
$vals[] = "'my string value'";
You're looking for ;
SELECT * FROM table WHERE plz in ('value1', 'value2', 'value3')
Be aware of SQL injections...
If the column plz is INT type, and all $plz are also integers, then:
$query = 'WHERE plz IN( ' . implode(',', $plz) . ')';
would work. Otherwise, trying this might work(not tested):
$query = 'WHERE plz IN( \'' . implode("','", $plz) . '\')';

Can't get spaces in my SQL statement

I have two variables in my WHERE statement. I cant seem to separate them with a space so i end up getting a syntax error. Thanks for the help.
(I am using codeigniter)
btw i have tried setting a $space variable, and putting spaces before the and, after setting both variables, and in the sql.
ERROR
Error Number: 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 'source_adusers.ad_account="Wolfs, Marc" GROUP BY rollout_systems.eam_user LIMIT ' at line 2
SELECT *, COUNT(rollout_systems.EAM_USER) as systems FROM rollout_systems LEFT JOIN source_adusers ON rollout_systems.EAM_User = source_adusers.ad_account WHERE rollout_systems.scope_ID = 3AND source_adusers.ad_account="Wolfs, Marc" GROUP BY rollout_systems.eam_user LIMIT 0,50
Line Number: 330
PHP
if ($this->session->userdata('scopeId') != NULL) {
$where1 = 'WHERE rollout_systems.scope_ID = '. $this->session->userdata('scopeId') . '';
} else {
redirect('/headquarters/home');;
}
if ($search) {
$where2 = ' AND rollout_systems.sys_name ="'.$search.'"';
} else {
$where2 = '';
}
$query = $this->db->query('SELECT * FROM rollout_systems LEFT JOIN source_adusers
ON rollout_systems.eam_user = source_adusers.ad_account '. $where1 .''. $where2 .' GROUP BY rollout_systems.sys_name LIMIT '.$limit.',50');
what if you keep the spaces and the AND in the $query, instead of building them into your where variables? Then your $where 2 just needs to work without affecting the query - thus 0=0.
if ($this->session->userdata('scopeId') != NULL) {
$where1 = 'WHERE rollout_systems.scope_ID = '. $this->session->userdata('scopeId') . '';
} else {
redirect('/headquarters/home');;
}
if ($search) {
$where2 = 'rollout_systems.sys_name ="'.$search.'"';
} else {
$where2 = '0=0';
}
$query = $this->db->query('SELECT * FROM rollout_systems LEFT JOIN source_adusers
ON rollout_systems.eam_user = source_adusers.ad_account '. $where1 .' and '. $where2 .' GROUP BY rollout_systems.sys_name LIMIT '.$limit.',50');
Just add a space between the two vars - '. $where1 .' '. $where2 .'
As pointed out by others you really should be escaping your user input using mysql_real_escape_string() or intval() if you are expecting an integer value. If you are using PDO or mysqli use prepared statements.
If $this->db is a PDO instance you could use -
$params = array();
if ($this->session->userdata('scopeId') != NULL) {
$where = 'WHERE rollout_systems.scope_ID = ?';
$params[] = $this->session->userdata('scopeId');
} else {
redirect('/headquarters/home');;
}
if ($search) {
$where .= ' AND rollout_systems.sys_name = ?';
$params[] = $search;
}
$sql = "SELECT * FROM rollout_systems
LEFT JOIN source_adusers ON rollout_systems.eam_user = source_adusers.ad_account
$where
GROUP BY rollout_systems.sys_name
LIMIT ?, 50";
$params[] = $limit;
$query = $this->db->prepare($sql);
$query->execute($params);
$where = array();
if ($this->session->userdata('scopeId') != NULL) {
// better to escape your parameter here unless you trust it totally
// judging by its name, it's user-provided data, so I wouldn't trust it
$where[] = 'rollout_systems.scope_ID = '. $this->session->userdata('scopeId');
} else {
redirect('/headquarters/home');
// you may need to exit here after redirection, depends on your implementation
}
if ($search) {
// once again don't forget to escape $search in real application
$where[] = "rollout_systems.sys_name = '" . $search . "'";
}
$query = $this->db->query("
SELECT
*
FROM
`rollout_systems`
LEFT JOIN
`source_adusers`
ON rollout_systems.eam_user = source_adusers.ad_account
WHERE
" . implode (' AND ', $where) . "
GROUP BY
rollout_systems.sys_name
LIMIT " . $limit /* escape it! */ . ",50"
);
You also have the option to use the PHP syntax
$sql = " blah blah {$my_var} {$my_other_var} ";

Categories