php mysql statement not working - php

I have the following php mysql statment that is working fine:
if (isset($_GET['name'])) {
$data = "%".$_GET['name']."%";
$sql = 'SELECT * FROM tbl_clients WHERE fname like ?';
$stmt = $conn->prepare($sql);
$results = $stmt->execute(array($data));
$rows = $stmt->fetchAll();
$error = $stmt->errorInfo();
}
But i want to add the following so it can check to columns for the name variable:
$sql = 'SELECT * FROM tbl_clients WHERE fname like ? or lname like ?';
If i modify this statement to the above it errors out with the following:
Warning: PDOStatement::execute(): SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens in /var/www/www.test.com/search.php on line 38

It's pretty obvious, you have two ? and only one item in the array you are passing to $stmt->execute
$sql = 'SELECT * FROM tbl_clients WHERE fname like :something or lname like :something';
$data = array(':something'=>'SOME VALUE');
$results = $stmt->execute($data);

In the updated query, you have two parameters, but you're only passing one value to execute. Just fix the latter problem, and it will work:
$results = $stmt->execute(array($data, $data));

Related

Left join using PDO

I am using the following PDO query:
<?php
$cadena = $_SESSION[Region];
// We Will prepare SQL Query
$STM = $dbh->prepare("SELECT `id_mesero`, `nombre_mesero`,`alias_mesero`, `rest_mesero` FROM tbmeseros WHERE cadena_mesero='$cadena'");
// For Executing prepared statement we will use below function
$STM->execute();
// we will fetch records like this and use foreach loop to show multiple Results
$STMrecords = $STM->fetchAll();
foreach($STMrecords as $row)
{
The value from the 'rest_mesero' field is the index from the table 'tbrestaurantes'.
I would need to join some fields values from 'tbrestaurantes' to the PDO query, but I don't know how to do it using PDO.
Any help is welcome.
UPDATED QUESTION TEXT
This is my proposal for the query :
$dbh->prepare("SELECT * FROM tbmeseros LEFT JOIN tbrestaurantes ON tbmeseros.rest_mesero = tbrestaurantes.id_restaurante WHERE tbmeseros.cad_mesero = ?");
But is show an error:
Warning: PDOStatement::execute() [pdostatement.execute]: SQLSTATE[HY093]: Invalid parameter number: no parameters were bound in /.../AdminMeseros.php on line 80
Line 80 is
$STM->execute();
This is my updated query:
<?php
$cadena = $_SESSION[Region];
$STM =$dbh->prepare("SELECT * FROM tbmeseros LEFT JOIN tbrestaurantes ON tbmeseros.rest_mesero = tbrestaurantes.id_restaurante WHERE tbmeseros.cad_mesero = ?");
$STM->bindParam(1, $cadena);
// For Executing prepared statement we will use below function
$STM->execute(array($cadena));
// we will fetch records like this and use foreach loop to show multiple Results
$STMrecords = $STM->fetchAll();
foreach($STMrecords as $row)
{
And here table's screenshots:
For tbmeseros:
For tbrestaurantes:
The value of $cadena is 'HQ3'.
When you put a parameter in the SQL, you need to supply the value for the parameter. There are two ways to do that:
1) Call bindParam():
$STM->bindParam(1, $cadana);
2) Provide the values when calling execute():
$STM->execute(array($cadana));
You need to fill the ? in the query:
$q = $dbh->prepare("SELECT * FROM tbmeseros LEFT JOIN tbrestaurantes ON tbmeseros.rest_mesero = tbrestaurantes.id_restaurante WHERE tbmeseros.cad_mesero = ?");
$q->bindValue( 1, 'x' );
$q->execute();
print_r( $q->fetchAll( PDO::FETCH_ASSOC );
In prepare you can use '?' and then bindValue to attach an escaped value to the query. Your query doesn't appear to have this and that is the cause of the error.

Unable to concatenate sql in pdo statement [duplicate]

This question already has answers here:
How to include a PHP variable inside a MySQL statement
(5 answers)
Closed 2 years ago.
I currently have a Get varible
$name = $_GET['user'];
and I am trying to add it to my sql statement like so:
$sql = "SELECT * FROM uc_users WHERE user_name = ". $name;
and run
$result = $pdo -> query($sql);
I get an invalid column name. But that doesn't make sense because if I manually put the request like so
$sql = "SELECT * FROM uc_users WHERE user_name = 'jeff'";
I get the column data, just not when I enter it as a get variable. What am I doing wrong. I am relatively new to pdo.
Update:
Now I have the following:
$name = $_GET['user'];
and
$sql = "SELECT * FROM uc_users WHERE user_name = :name";
//run the query and save the data to the $bio variable
$result = $pdo -> query($sql);
$result->bindParam( ":name", $name, PDO::PARAM_STR );
$result->execute();
but I am getting
> SQLSTATE[42000]: Syntax error or access violation: 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 ':name' at line
> 1
For your query with the variable to work like the one without the variable, you need to put quotes around the variable, so change your query to this:
$sql = "SELECT * FROM uc_users WHERE user_name = '$name'";
However, this is vulnerable to SQL injection, so what you really want is to use a placeholder, like this:
$sql = "SELECT * FROM uc_users WHERE user_name = :name";
And then prepare it as you have:
$result = $pdo->prepare( $sql );
Next, bind the parameter:
$result->bindParam( ":name", $name, PDO::PARAM_STR );
And lastly, execute it:
$result->execute();
I find this best for my taste while preventing SQL injection:
Edit: As pointed out by #YourCommonSense you should use a safe connection as per these guidelines
// $conn = mysqli_connect(DB_HOST, DB_USER, DB_PASS, DB_NAME);
$sql = 'SELECT * FROM uc_users WHERE user_name = ?';
$stmt = $conn->prepare($sql);
$stmt->bind_param('s', $name);
$stmt->execute();
$result = $stmt->get_result();
$stmt->close();
// perhaps you'll need these as well
$count = $result->num_rows;
$row = $result->fetch_assoc();
/* you can also use it for multiple rows results like this
while ($row = $result->fetch_assoc()) {
// code here...
} */
BTW, if you had more parameters e.g.
$sql = 'SELECT * FROM table WHERE id_user = ? AND date = ? AND location = ?'
where first ? is integer and second ? and third ? are string/date/... you would bind them with
$stmt->bind_param('iss', $id_user, $date, $location);
/*
* i - corresponding variable has type integer
* d - corresponding variable has type double
* s - corresponding variable has type string
* b - corresponding variable is a blob and will be sent in packets
*/
Source: php.net
EDIT:
Beware! You cannot concatenate $variables inside bind_param
Instead you concatenate before:
$full_name = $family_name . ' ' . $given_name;
$stmt->bind_param('s', $full_name);
Try this .You didn't put sigle quote against variable.
$sql = "SELECT * FROM uc_users WHERE user_name = '". $name."'";
Note: Try to use Binding method.This is not valid way of fetching data.
$sql = "SELECT * FROM 'uc_users' WHERE user_name = '". $name."' ";

Convert sql to mysqli_prepare with variable variables

I'm having trouble to convert my code from sql to mysqli. $XX can be 1 or 0. When $XX=1 I want to search for it. When $XX=0, there must be no search for $XX. Same for $YY.
Old code
$sql = "SELECT name FROM tabel WHERE 1=1";
if (!empty($XX)) {$sql .= " AND XX = 1 ";}
if (!empty($YY)) {$sql .= " AND YY = 1 ";}
When $XX=1 and $YY=1, the code will look like:
$sql = "SELECT name FROM tabel WHERE 1=1 AND XX = 1 AND YY = 1";
When $XX=0 and $YY=1, the code will look like:
$sql = "SELECT name FROM tabel WHERE 1=1 AND YY = 1";
When $XX=0 and $YY=0, the code will look like:
$sql = "SELECT name FROM tabel WHERE 1=1";
The 'problem' is that I do not want to search for XX=0 because that excludes all XX=1 answers. When XX=0, it should not search for XX.
New code
$stmt = mysqli_prepare($link, "SELECT name FROM tabel WHERE XX=? and YY=?");
mysqli_stmt_bind_param($stmt, "ii", $XX, $YY);
Who knows how the mysqli code must look like? Thanks!
EDIT
Okay, from what I get now, it should be simple. If the only possible value for XX and YY in the query is 1, you don't need bind_param.
$qry = 'SELECT name FROM table WHERE 1=1';
$qry .= (!empty($XX)) ? ' AND XX=1';
$qry .= (!empty($YY)) ? ' AND YY=1';
$stmt = mysqli_prepare($link, $qry);
And then just execute your query.
You can rewrite the query in the following way
SELECT * FROM table1 WHERE (xx = ? OR ? = 0) AND (yy = ? OR ? = 0)
Here is SQLFiddle demo
$sql = "SELECT * FROM table1 WHERE (xx = ? OR ? = 0) AND (yy = ? OR ? = 0)";
$db = new mysqli(...);
$stmt = $db->prepare($sql)) {
$stmt->bind_param('iiii', $xx, $xx, $yy, $yy);
$stmt->execute();
$stmt->bind_result(...);
another alternate if you can pass the field name as parameter
$stmt = mysqli_prepare($link, "SELECT name FROM tabel WHERE XX=? and YY=?");
mysqli_stmt_bind_param($stmt, "ii", $XX, $YY);
if you want to avoid filtering XX pass $XX as 'XX'(i.e field name) insted of 0
In such a special case when no variable is actually going into query, you can stick to your current setup. Just change prepare and bind to mysqli_query().
However, in case you need to add a variable into query, you either can use peterm's dirty solution or create the conditional query with placeholders and then call bind_param() with variable number of parameters using call_user_func_array()

implement LIKE query in PDO

I am running problems in implementing LIKE in PDO
I have this query:
$query = "SELECT * FROM tbl WHERE address LIKE '%?%' OR address LIKE '%?%'";
$params = array($var1, $var2);
$stmt = $handle->prepare($query);
$stmt->execute($params);
I checked the $var1 and $var2 they contain both the words I want to search, my PDO is working fine since some of my queries SELECT INSERT they work, it's just that I am not familiar in LIKE here in PDO.
The result is none returned. Do my $query is syntactically correct?
You have to include the % signs in the $params, not in the query:
$query = "SELECT * FROM tbl WHERE address LIKE ? OR address LIKE ?";
$params = array("%$var1%", "%$var2%");
$stmt = $handle->prepare($query);
$stmt->execute($params);
If you'd look at the generated query in your previous code, you'd see something like SELECT * FROM tbl WHERE address LIKE '%"foo"%' OR address LIKE '%"bar"%', because the prepared statement is quoting your values inside of an already quoted string.
Simply use the following:
$query = "SELECT * FROM tbl WHERE address LIKE CONCAT('%', :var1, '%')
OR address LIKE CONCAT('%', :var2, '%')";
$ar_val = array(':var1'=>$var1, ':var2'=>$var2);
if($sqlprep->execute($ar_val)) { ... }
No, you don't need to quote prepare placeholders. Also, include the % marks inside of your variables.
LIKE ?
And in the variable: %string%
$query = "SELECT * FROM tbl WHERE address LIKE ? OR address LIKE ?";
$params = array("%$var1%", "%$var2%");
$stmt = $handle->prepare($query);
$stmt->execute($params);
You can see below example
$title = 'PHP%';
$author = 'Bobi%';
// query
$sql = "SELECT * FROM books WHERE title like ? AND author like ? ";
$q = $conn->prepare($sql);
$q->execute(array($title,$author));
Hope it will work.

Not able to update rows using PDO

When I run the following code:
// Loop through each store and update shopping mall ID
protected function associateShmallToStore($stores, $shmall_id) {
foreach($stores as $store_id) {
$sql .= 'UPDATE my_table SET fk_shmallID = :shmall_id WHERE id = :store_id';
$stmt = $this->db->prepare($sql);
$stmt->bindParam(':shmall_id', $shmall_id);
$stmt->bindParam(':store_id', $store_id);
$stmt->execute();
}
}
I get the following message:
Warning: PDOStatement::execute() [pdostatement.execute]: SQLSTATE[HY093]: Invalid parameter number: mixed named and positional parameters
I've also tried the following without success (without $stmt->bindParam):
$stmt->execute( array($shmall_id, $store_id));
I don't understand what I'm doing wrong.
UPDATE
I've updated my code to reflect what I actually got in my source code. There should not be any typos here.
UPDATE 2
I tried this, but I still get the same error message.
protected function associateShmallToStore($stores, $shmall_id) {
$i = 0;
$sql .= "UPDATE sl_store ";
foreach($stores as $store_id) {
$i++;
$sql .= 'SET fk_shmallID = :shmall_id, lastUpdated = NOW() WHERE id = :store_id_'.$i.',';
}
$sql = removeLastChar($sql);
$stmt = $this->db->prepare($sql);
$stmt->bindParam(':shmall_id_'.$i, $shmall_id);
$i = 0;
foreach($stores as $store_id) {
$i++;
$stmt->bindParam(':store_id_'.$i, $store_id);
}
$stmt->execute();
}
This is the output of the SQL query:
UPDATE sl_store
SET fk_shmallID = :shmall_id, lastUpdated = NOW() WHERE id = :store_id_1,
SET fk_shmallID = :shmall_id, lastUpdated = NOW() WHERE id = :store_id_2
UPDATE 3
The code I endet up using was this:
foreach($stores as $store_id) {
$sql = "UPDATE sl_store SET fk_shmallID = :shmall_id WHERE id = :store_id";
$stmt = $this->db->prepare($sql);
$stmt->bindParam(':shmall_id', $shmall_id);
$stmt->bindParam(':store_id', $store_id);
$res = $stmt->execute();
}
It's just as the error says, you have mixed named and positional parameters:
:name (named)
:person_id (named)
? (positional)
More than that, you have the named parameter :person_id, but you're binding to :id.
These are your parameters, I'll call them P1, P2 and P3:
UPDATE my_table SET name = :name WHERE id = :person_id ?
^ P1 ^ P2 ^ P3
And this is where you bind them:
$stmt->bindParam(':name', $name); // bound to P1 (:name)
$stmt->bindParam(':id', $person_id); // bound to nothing (no such param :id)
You probably want to bind the second parameter to :person_id, not to :id, and remove the last positional parameter (the question mark at the end of the query).
Also, each iteration through the foreach loop appends more to the query, because you're using the concatenation operator instead of the assignment operator:
$sql .= 'UPDATE my_table SET name = :name WHERE id = :person_id ?';
You probably want to remove that . before =.
For more about this, take a look at the Prepared statements and stored procedures page in the PDO manual. You will find out how to bind parameters and what the difference is between named and positional parameters.
So, to sum it up:
Replace the SQL line with:
$sql = 'UPDATE my_table SET name = :name WHERE id = :person_id';
Replace the second bindParam() call with:
$stmt->bindParam(':person_id', $person_id);
Try:
$sql = 'UPDATE my_table SET name = :name WHERE id = :id';

Categories