number of bound variables does not match number of tokens - pdo

I am facing "number of bound variables does not match number of tokens" exception while trying to use multiple condition in where clause using PDO.
code:
$servername = "localhost";
$username = "xxxx";
$password = "xxxxx";
$dbname = "yyyy";
$searchParam = $_POST['typeahead'];
$conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $conn->prepare("SELECT * FROM trucks WHERE plate_number LIKE :plateNumber OR company_name LIKE: companyName");
$stmt->bindValue(':plateNumber', '%'.$searchParam.'%', PDO::PARAM_INT);
$stmt->bindValue(':companyName', '%'.$searchParam.'%', PDO::PARAM_INT);
I am trying to search depending on either plate_number or company_name. For the same reason I am binding the two place holders(variables). the code works while I use only 1 variable but not two. how to bind two variables?

You can use
$stmt->bindValue(array(':plateNumber', '%'.$searchParam.'%', PDO::PARAM_INT,':companyName', '%'.$searchParam.'%', PDO::PARAM_INT));

Related

Powershell insert into MS Access with WHERE clause

Trying to insert values into MS Access DB based on values entered into a powershell form with a WHERE clause. I'm receiving a simple error but struggling to resolve ("Missing Semicolon (;) at end of SQL Statement")
Here is my base code;
$query = "INSERT INTO SignIns ([DateTimeOUT], [SignedOut]) VALUES ('$($info.F1)','$($info.F2)') FROM $Info WHERE SignIns.Surname = '$($Info.F3)'"
$cmd = $conn.CreateCommand()
$cmd.CommandText = $query
$result = $cmd.ExecuteNonQuery()
$conn.Close()
I've amended to add a semicolon in all places I thought could resolve, but no luck, still returns the same error (Missing Semi Colon at end of SQL statement);
$query = "INSERT INTO SignIns ([DateTimeOUT], [SignedOut]) VALUES ('$($info.F1)','$($info.F2)') FROM $Info WHERE SignIns.Surname = '$($Info.F3);';";
$cmd = $conn.CreateCommand()
$cmd.CommandText = $query;
$result = $cmd.ExecuteNonQuery();
$conn.Close()
(for reference, I've added a semi-colon at the end of my WHERE clause, at the end of the $Query variable and tried to append onto the end of $query when executing in the $cmd.commandtext variable, and also on the end of the $result variable.
I expect the statement to execute as normal and update with the given values. Testing within Access DB itself is difficult as I am unable to reference my PS form from within the DB. Any help greatly appreciated,
Thanks.
Update: Ameding query to UPDATE now lets me 'insert' values with WHERE statement following a simple logic.
$conn.Open()
$query = "UPDATE SignIns SET DateTimeOUT = '$($info.F1)' WHERE SignIns.Surname = '$($Info.F3)'";
$cmd = $conn.CreateCommand()
$cmd.CommandText = $query;
$result = $cmd.ExecuteNonQuery();
$query = "UPDATE SignIns SET SignedOut = '$($info.F2)' WHERE SignIns.Surname = '$($Info.F3)'";
$cmd = $conn.CreateCommand()
$cmd.CommandText = $query;
$result = $cmd.ExecuteNonQuery();
$conn.Close()
It is not a method I'm normally use to when inputting new values into a table, but same result so.. I don't think there's any implications. It probably takes the update as 'Update from NULL to VALUE' as opposed to INSERT FROM source to DESINTATION (where)

How to return the value of a row, without column name in a query?

I am writing a Powershell script that extracts data via the SQLPS module, executing a query directly to the SQL Server. If I do a plain
Select <column A> from <table B>
I get the column listed as well, as stated like this:
Column A
--------
Value C
Here I wish to only retrieve the Value C, for storing it as a variable.
If you are not bound to use this SQLPS module then this might be a easier way to do it:
$connection = new-object System.Data.SqlClient.SqlConnection("Data Source=.;Initial Catalog=TestDB;Integrated Security=True");
$connection.Open()
$query = "SELECT [A] FROM [dbo].[Tablename]"
$cmd = new-object "System.Data.SqlClient.SqlCommand" ($query, $connection)
$cmd.CommandTimeout = 0
$executeReader = $cmd.ExecuteReader()
while ($executeReader.Read()) {
$Name = $executeReader.GetValue(0)
//Do what you desire with the resultset.
$Name + "`r`n" >> D:\PathToResultFolder\result.txt
}
$executeReader.Close()
$connection.Close()
Also I read and think that this should be handled outside of the Query as it is not normal for a Query to not show column-names.

My first attempt at PDO statements - Is this code actually correct and doing what it should?

I'm brand new to PDO statements, and this is my very first attempt.
I'm not completely sure if the code I have produced is achieving anything?
Am I protected from coding-genius-hackers?
<?php
$host = "localhost";
$db = "test";
$user = "root";
$pass = "admin";
$who = '65';
$conn = new PDO("mysql:host=$host;dbname=$db",$user,$pass);
$sql = "SELECT
tbl_tracking.id as trackID,
tbl_tracking.from_user as trackFROM,
tbl_tracking.viewed as trackVIEWED,
tbl_tracking.date as trackDATE,
tbl_users.id as usrID,
tbl_users.name as usrNAME,
tbl_photos.profile as photosPROFILE,
tbl_photos.photo_link as photoLINK,
tbl_photos.default_photo as photoDEFAULT
FROM tbl_tracking
LEFT JOIN tbl_users ON tbl_tracking.from_user = tbl_users.id
LEFT JOIN tbl_photos ON tbl_photos.profile = tbl_users.id
WHERE tbl_tracking.viewed = '$who' AND tbl_photos.default_photo IS NULL OR tbl_photos.default_photo = '1'
GROUP BY tbl_tracking.from_user
ORDER BY tbl_tracking.id DESC
LIMIT 9
";
$q = $conn->query($sql) or die("failed!");
while($r = $q->fetch(PDO::FETCH_ASSOC)){
echo '<img src="../assets/uploads/thumbnail_' . $r['photoLINK'] . '" class="suggestUser" />';
}
?>
To be protected against sql injection, you must use PDO's new of verifying values: binding parameters. This needs that your prepare statements instead of running them directly:
$q = $conn->prepare($sql); // the default way of PDO to manage errors is quite the same as `or die()` so no need for that
Change your where clause:
WHERE tbl_tracking.viewed = :who AND tbl_photos.default_photo IS NULL OR tbl_photos.default_photo = '1'
then bind the value to your statement and execute it:
$q->bindValue(':who',$who,PDO::PARAM_INT);
$q->execute();
or you can execute it directly with an array of values:
$q->execute(array(':who' => $who));
otherwise, I'm not very sure what your code should be doing, so I can't really tell if it will, but if your sql worked before using PDO, it should work now too.
For your code to be prone to sql injection, one of the values in your query must have a way to come from user-input, and it must be passed as-is to PDO's prepare(). Since we use a parameter :who instead of $who, there's no way your sql will be prepared with dangerous values.

bindParam or binValue will not work

Hi It seems that both bindParam or bindValue methods will not work.
Please advise. I tried to bind the $dbname to dbtest. It does not seem to work!
bindParam
$dbname = "test1";
$stmt=$dbh->prepare('use :dbtest');
$stmt->bindParam(':dbtest', $dbname, PDO::PARAM_STR);
$firephp->fb($stmt);
try
{ $stmt->execute();
$stmt=$dbh->prepare('select database()');
$stmt->execute();
$count = $stmt->fetch(PDO::FETCH_ASSOC);
$firephp->warn("Attempting to use selected database is successful.");
}
bindValue
$dbname = "test1";
$stmt=$dbh->prepare('use :dbtest');
$stmt->bindValue(':dbtest', $dbname, PDO::PARAM_STR);
$firephp->fb($stmt);
try
{ $stmt->execute();
$stmt=$dbh->prepare('select database()');
$stmt->execute();
$count = $stmt->fetch(PDO::FETCH_ASSOC);
$firephp->warn("Attempting to use selected database is successful.");
$firephp->fb($count);
}
What could be the problem?
First, native prepared statements won't work for identifiers
Second, there is no point in having dynamically bound databases. They are supposed to be constant.
So, select your database in DSN and then use bindValue to bind values in the query.

PDO SQL - Update query issue

I am new to pdo and do not get why the following insert query does not work. If I remove the line that executes the query, there will be of course no insertion, but there will be no error. If I leave that line, the script is not executed. Of course I checked and rechecked the table name and field name. Hope someone can hep me understand. Note that before executing the query, the ber_mBacth_date field of my table is set to NULL. Cheers. Marc
<?php
$db_host = 'localhost';
$db_user = 'user';
$db_password = 'user';
$db_database = 'myconsole';
$mBatchDate = date('Y-m-d H:i:s');
$connexion = new PDO("mysql:host=$db_host;dbname=$db_database", $db_user, $db_password);
$qry = $connexion->execute('UPDATE batcherrors SET ber_mBatch_date = "'.$mBatchDate.'"');
$connexion = NULL;
?>
Can you try instead of:
$connexion = new PDO("mysql:host=$db_host;dbname=$db_database", $db_user, $db_password);
$qry = $connexion->execute('UPDATE batcherrors SET ber_mBatch_date = "'.$mBatchDate.'"');
do:
$statement = $connexion->prepare("UPDATE batcherrors SET ber_mBatch_date = :mBatchDate");
$statement->bindValue(':mBatchDate', $mBatchDate, PDO::PARAM_STR);
$statement->execute();
Binding is recommended way to set parameters values (over concatenation).