How to fix this error on PDO statements: Invalid parameter number? - php

I am trying to a PDO using the following code:
<?php
include('connection.php');
# cartexe.php will perform all actions on cart.php
// add Item to Cart
if(isset($_POST['addItemToCart']))
{
// initialize index.php variables
$productName = $_POST['productName'];
$price = $_POST['price'];
$description = $_POST['description'];
// check the cart table to see if the product has been previously added
$smtp = $conn->prepare('SELECT Quantity FROM cart WHERE Product Name = :product'); // prepare a statement to fetch the quantity for a particular product... the statement is not executed but merely prepared to do so.
$smtp->bindParam(':product', $productName, PDO::PARAM_STR); //bind the productName with whatever data supplied hence the statement after : above will be replaced with the actually data.. In additional the statement is set as string hence PDO::PRAM_STR
$smtp->execute();//finally run the statment
$result = $smtp->fetch(PDO::FETCH_NUM);
if($result > 0)
{
echo " DATA FOUND";
}
else
{
echo ' No data founded';
}
}
?>
But I keep getting the error below. I have tried several different methods but none of them worked.
Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[HY093]: Invalid parameter number: parameter was not defined'

Wrap your column name in backticks since it contains a space
WHERE `Product Name`
having used $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); right after the connection is opened, would have signaled an error.
Another option is to use an underscore between the words while renaming/altering your column to Product_Name
WHERE Product_Name ...
An insight:
Also make sure your form element is indeed named.
I.e.:
<input type="text" name="productName">
Using error reporting and placed at the top of your file(s):
error_reporting(E_ALL);
ini_set('display_errors', 1);
would signal (other) possible errors also, should it be the case.

Related

SQL query to update item quantity using PHP PDO

Good morning everyone
I am trying to update the table with the new quantity selected, when I run the following function, however, I get this error:
Fatal error: Uncaught PDOException: SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens in C:\xampp\htdocs\php_Assessments\shoppingList\model\functions_products.php:11 Stack trace: #0 C:\xampp\htdocs\php_Assessments\shoppingList\model\functions_products.php(11): PDOStatement->execute() #1 C:\xampp\htdocs\php_Assessments\shoppingList\controller\product_update_process.php(21): update_item('57', '3', '1') #2 {main} thrown in C:\xampp\htdocs\php_Assessments\shoppingList\model\functions_products.ph
Function to update the quantity, function_products.php:
<?php
function update_item($soldID, $orderedQuantity, $itemQuantity)
{
global $conn;
$sql = "UPDATE shopping_items.sold SET orderedQuantity = :itemQuantity WHERE soldID = :soldID";
$statement = $conn->prepare($sql);
$statement->bindValue(':soldID', $soldID);
$statement->bindValue(':orderedQuantity', $orderedQuantity);
$statement->bindValue(':itemQuantity', $itemQuantity);
$result = $statement->execute();
$statement->closeCursor();
return $result;
}
?>
product_update_process.php
<?php
// Require database connection
require('connection.php');
// Require function
require_once("../model/functions_products.php");
// Fetch the data required
$soldID = $_GET['soldID'];
$itemQuantity = $_POST['itemQuantity'];
$orderedQuantity = $_POST['orderedQuantity'];
if(empty($itemQuantity)) {
echo '<script type="text/javascript">alert("The quantity is required.")</script>' ;
// Redirect the browser window back to the add customer page
echo "<script>setTimeout(\"location.href = '../index.php';\",2000);</script>";
} else {
//call the update_item() function
$result = update_item($soldID, $itemQuantity, $orderedQuantity);
// Redirect the browser window back to the admin page
header("location: ../index.php");
}
?>
What could be the issue here?
Thanks for your assistance.
To add to #TangentiallyPerpendicular's comment, why are you binding to :orderedQuantity? This variable is not being used in your SQL statement, even though you have told the SQL engine to expect the variable. The column doesn't need to be a variable in order pass a variable to it.

PHP Unexplainable Error, Invalid parameter number: number of bound variables does not match number of tokens

I can't find a mistake in my code, and I always get the following error:
exception 'PDOException' with message 'SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens' "
when trying to submit some inputs from a form.
if (isset($_GET['createNewBox'])) {
if (!empty($_POST['tableName']) and !empty($_POST['commentFullAddress'])) {
try{
$sql = 'CREATE TABLE :tableName (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
customerid INT,
item TEXT,
pin INT(11) NOT NULL,
position VARCHAR(5),
storedate DATE NOT NULL,
storetime TIME NOT NULL
) DEFAULT CHARACTER SET utf8 ENGINE=INNODB COMMENT=":commentFullAddress"';
$statement = $pdo -> prepare($sql);
$statement -> bindValue(':tableName', $_POST['tableName']);
$statement -> bindValue(':commentFullAddress', $_POST['commentFullAddress']);
if ($statement -> execute()) {
session_start();
$_SESSION['messageSucceed'] = "A new database has been created for the box.";
header('Location: /?managebox');
exit();
}
} catch (PDOException $e) {
$error_output = "Error on creating new box database: " . $e;
include '../error.html.php';
exit();
}
} else {
session_start();
$_SESSION['message'] = "Please do not submit empty data.";
header("Location: /?managebox");
}
}
There are 2 things wrong with your code.
Firstly, this:
CREATE TABLE :tableName
You can't bind a table in PDO, so you need to either use a variable or from a safelist.
Then you're using quotes around the values for the binds COMMENT=":commentFullAddress"'; and those need to be removed.
Sidenote: TBH, I don't know why you're using a prepared statement for the COMMENT, I've never seen that before.
References:
When to use single quotes, double quotes, and backticks in MySQL
Can PHP PDO Statements accept the table or column name as parameter?
http://php.net/pdo.prepared-statements
Plus, make sure those POST arrays contain values.
Add error reporting to the top of your file(s) which will help find errors.
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
// Then the rest of your code
Sidenote: Displaying errors should only be done in staging, and never production.
You also may have to change bindValue to bindParam, I said "may".
Footnotes:
I don't understand why you're using this code to create a table, yet alone coming from user input. That's your decision but I don't see the reason for it, unless you're trying to create some form of database hosting service.

Syntax error MySql and PHP near '#dfaf.fa''

I create a simple site for findID when I write the email.
HTML CODE
<form action="test.php" method="post">
<input type="text" name="user_id_test" id="user_id_test">
<br>
<br>
<input type="submit" value="Find ID">
</form>
PHP CODE
<?php
//include database
include 'include/db.inc';
$emailUser = $_POST['user_id_test'];
$findNewID = mysqli_query($connessione,"SELECT user_id FROM user_tmplt WHERE user_mail = $emailUser");
if ($findNewID != "") {
var_dump($findNewID);
echo "$findNewID";
} else {
echo "Errore: " . $findNewID . "<br>" . mysqli_error($connessione) ."<br>";
}
mysqli_error($connessione);
?>
I try to find ID for email: dfaf#dfaf.fa (it is in my database with ID 13) and I've this error 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 '#dfaf.fa' at line 1
You should use prepared statements to avoid this kind of errors and to avoid SQL Inyection:
$stmt = mysqli_prepare($connessione,"SELECT user_id FROM user_tmplt WHERE user_mail = ?");
if ( !$stmt ) { someErrorHandlingHere(); }
mysqli_stmt_bind_param($stmt, "s", $emailUser);
// same here: mysqli_stmt_bind_param may fail -> returns false
mysqli_stmt_execute($stmt);
// same here: mysqli_stmt_execute may fail -> returns false
mysqli_stmt_bind_result($stmt, $userId);
// and so on and on: error handling
mysqli_stmt_fetch($stmt);
echo "The user id es: {$userId}";
It is about passing email as integer, pass it as string..
mysqli_query($connessione,"SELECT user_id FROM user_tmplt WHERE user_mail = $emailUser");
to
mysqli_query($connessione,"SELECT user_id FROM user_tmplt WHERE user_mail = '".$emailUser."' ");
This would work but it is not safe to pass parameters within the queries directly, make the sql injection safe first...
Your immediate problem (as has already been answered) is/was that you didn't mark the string parameter (the email-address) as a string literal within the SQL query. The MySQL server therefore interpreted it as an identifier (like a database/table/field name). And since # is an invalid character within an identifier the server reported the error you've posted, see http://dev.mysql.com/doc/refman/5.0/en/identifier-qualifiers.html.
To mark a string literal within a query you put it (by default) in single-quotes:
SELECT x FROM table WHERE y=z // compares the value of the field y with the value of the field z in each record
SELECT x FROM table WHERE y='z' // compares the value of the field y with the string literal 'z' <- that's what you want
Anyway, here's an example (that addresses some other issues) using PDO instead of mysqli_*:
<?php
define('POST_FIELD_MAIL', 'user_id_test');
if ( !isset($_POST[POST_FIELD_MAIL]) ) { // maybe the resource (...script) has been requested without that parameter?
trigger_error('missing parameter '.POST_FIELD_MAIL, E_USER_ERROR);
}
else {
/** that's you part you probably want in inc/db.php */
$pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8', 'localonly', 'localonly');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // that's why there's not error handling code after each and every call to a pdo function/method
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
/* ***** */
try {
$stmt = $pdo->prepare('SELECT user_id FROM user_tmplt WHERE user_mail=?'); // avoiding sql injections
$stmt->execute( array($_POST[POST_FIELD_MAIL]) );
$row = $stmt->fetch();
if (!$row) {
echo '<div>no such record</div>';
}
else {
echo '<div>user_id=', htmlspecialchars($row['user_id']), '</div>';
}
}
catch(PDOException $pex) {
yourErrorHandler();
}
}
This query is exposed to sql injections. Always sanitize or escape special characters in a string before using in a where clause. In this case wrap $email with quotes.
ie. change
$email to '".$emailUser."'
In the where clause.

PHP PDO MySQL query prints blank

Going through a PHP MySQL tutorial and switching the PHP out for PDO; at any rate, my query is coming up blank.
$get_cat = $that->dbh->query("SELECT `cat_name`, `cat_desc` FROM `categories`");
if(isset($get_cat))
{
while($row = $get_cat->fetch(PDO::FETCH_ASSOC))
{
printf("
<tr>
<td>".$row['cat_name']." : ".$row['cat_desc']."</td>
</tr>
");
}
}
else
{
echo '<tr><td>return is false</td></tr>';
}
$That refers to:
include('db.php');
$that = new lib();
OLD:
So, why is my query blank? Before putting the die in it would return Boolean and give in an error in the loop with the die in it just comes up blank. The categories table has data in it and the page is refreshed on submission for new entries.
NEW:
Fatal error: Call to a member function fetch() on a non-object in C:\wamp\www\forum\create_category.php on line 36
Line 36 is the while loop line.
mysql_fetch_array is not PDO. You would need something like:
while($row = $get_cat->fetch(PDO::FETCH_ASSOC))
To get your rows.
Nor can you use mysql_error() to get the error. You could use for example $that->dbh->errorInfo() but you should look into exceptions for a more robust way to catch all errors.
Edit: You should check what the error is. Using isset is pointless as you have just assigned a value to it, so it will always be set.
You need to tell PDO to throw errors.
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$res = $that->dbh->query("SELECT cat_name, cat_desc FROM categories");
while($row = $res->fetch())
{
echo "<tr><td>$row[cat_name] : $row[cat_desc]</td></tr>\n";
}
run your code, read the error message and take appropriate action
Don't forget to add the first line into your db.php file, to make the setting permanent
Your query is incorrect -- is this what you're trying to do?
SELECT `categories`.`cat_name`, `categories`.`cat_desc` FROM `categories`
Hard to know without seeing you table structure.

PDO Prepared Statement over ODBC Sybase "PARAM datastream" error

I am trying to convert some old PHP ODBC queries over to PDO Prepared statements and am getting an error I cannot find too much information on.
The Error is:
"[DataDirect][ODBC Sybase Wire Protocol driver][SQL Server]There is no host variable corresponding to the one specified by the PARAM datastream. This means that this variable '' was not used in the preceding DECLARE CURSOR or SQL command. (SQLExecute[3801] at ext\pdo_odbc\odbc_stmt.c:254)"
I am searching for a single row in the database using a 6 digit ID that is stored in the database as a VARCHAR but is usually a 6 digit number.
The database connection is reporting successful.
The ID passed by the query string is validated.
The prepared statement results in the above error.
The backup straight ODBC_EXEC statement in the else clause returns the data I am looking for.
//PDO Driver Connect to Sybase
try {
$pdo = new PDO("odbc:Driver={Sybase ASE ODBC Driver};NA=server,5000;Uid=username;Pwd=password;");
$pdo_status = "Sybase Connected";
} catch(PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
if((isset($_GET['id'])) AND ($_GET['id'] != "")) {
//Validate ID String
if(!preg_match("/^[A-Za-z0-9]{5,7}/",$_GET['id'])) {
$query1_id = FALSE;
echo "Invalid ID";
exit;
} else {
$query1_id = $_GET['id'];
}
$query1 = $pdo->prepare("SELECT * FROM People WHERE PersonId= ?");
$query1->execute(array($query1_id));
if($query1->errorCode() != 0) {
$person_data = $query1->fetch(PDO::FETCH_ASSOC);
echo "Person Data from PDO: ";
print_r($person_data);
} else {
$errors = $query1->errorInfo();
echo $errors[2];
//Try the old way to confirm data is there.
$odbc_query1 = "SELECT * FROM People WHERE PersonId='$query1_id' ";
$person_result = odbc_exec($conn,$odbc_query1) or die("Error getting Data, Query 1");
$person_data = odbc_fetch_array($person_result);
echo "Person Data from ODBC_EXEC: ";
print_r($person_data);
}
It also fails if I use:
$query1 = $pdo->prepare("SELECT * FROM People WHERE PersonId= :id ");
$query1->execute(array(":id"=>$query1_id));
Does anyone have experience with this error?
Edit: Sybase Manual says this about the error...
Error 3801: There is no host variable corresponding to the one specified by the PARAM datastream. This means that this variable `%.*s' was not used in the preceding DECLARE CURSOR or SQL command.
Explanation:
Adaptive Server could not perform the requested action. Check your command for missing or incorrect database objects, variable names, and/or input data.
Which is odd because my error (quoted at the top) doesn't tell me which variable has no host.
Also fails if I use...
$query1 = $pdo->prepare("SELECT * FROM People WHERE PersonId= :id ");
$query1->bindParam(':id',$query1_id,PDO::PARAM_STR); //Or PARAM_INT
$query1->execute();
The query works if I place the variable in the query like this...
$query1 = $pdo->prepare("SELECT * FROM People WHERE PersonId= '$query1_id'");
So I think it has something to do with the parameter not being bound to the placeholder but I can't figure out why.
If I can't work this out I'll have to revert to building my query as a string and hoping my input validation is bullet proof.
Your problem seems to be with the default data type PHP assigns to variables in the placeholders. The SQL Statement is looking for a number but PHP is interpreting it as something else. You can prevent this using quotes around the placeholder variable. Notice that in the statements that work you have apostrophes ('') around the value that PHP sees:
$query1 = $pdo->prepare("SELECT * FROM People WHERE PersonId= '$query1_id'");
Try this when using the placeholder it should be the same:
$query1 = $pdo->prepare("SELECT * FROM People WHERE PersonId= ':id'");

Categories