I need a mechanism that inserts the data from a newly registered user to a database. I use PDO to do this, and this is my current code:
$dbc = new PDO('mysql:host=localhost;dbname=*****', *****, *****);
$insert_query = $dbc->prepare('INSERT INTO members(name, gender, email, pass)
VALUES(:name, :gender, :email, :pass) WHERE email = :email LIMIT 1');
$insert_query->execute(array(':name' => $name, ':gender' =>
$gender, ':email' => $email, ':pass' => $pass));
However, nothing happens when a user submits the register form. I tried to echo $gender, $name, $email and $pass, and they all showed correct values. I am new to PDO, and I'm not sure what the problem could be at all. Is it a syntax error of some sort, or is it something else?
I don't receive any error messages.
I don't believe it is valid to include a LIMIT clause in an INSERT statement. LIMIT is not among the optional clauses in the MySQL INSERT syntax reference.
You also have a WHERE clause, which is also invalid in an INSERT statement.
I suspect you don't have error reporting turned on, since this ought to have been a fatal error or thrown an exception if the statement failed to prepare() due to syntax errors. You would have gotten an error similar to
ERROR 1064 (42000): 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 'LIMIT 1'
$insert_query = $dbc->prepare('INSERT INTO members(name, gender, email, pass)
VALUES(:name, :gender, :email, :pass) WHERE email = :email LIMIT 1');
//------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^
By definition, an INSERT statement inserts exactly as many rows as you have () groups* for in your VALUES (), so there's no need for a LIMIT anyway. You could use a LIMIT in an INSERT INTO...SELECT... statement, but in that case, the LIMIT is a clause of the SELECT component rather than the INSERT.
* Ignoring potential key violations or other insert problems, obviously
The fact that you have conflated multiple components (WHERE,LIMIT) from UPDATE statements makes me wonder if you actually intended this to be an UPDATE rather than an INSERT statement to begin with. INSERT is only for new rows. UPDATE is for changing existing rows, and both WHERE and LIMIT are valid in UPDATE.
That would look like:
$upd_query = $dbc->prepare('UPDATE members SET name = :name, gender = :gender, email = :email, pass = :pass) WHERE email = :email LIMIT 1');
As "Michael" said, you can't use LIMIT n in an INSERT query.
After all, You cannot use a named parameter marker of the same name twice in a prepared statement.
Try swtching to UPDATE query syntax. Looks to be what you need.
Related
I've been using Yii's active record pattern for a while. Now, my project needs to access a different database for one small transaction. I thought the Yii's DAO would be good for this. However, I'm getting a cryptic error.
CDbCommand failed to execute the SQL statement: SQLSTATE[HY093]: Invalid parameter number: parameter was not defined
Here is my code:
public function actionConfirmation
{
$model_person = new TempPerson();
$model = $model_person->find('alias=:alias',array(':alias'=>$_GET['alias']));
$connection=Yii::app()->db2;
$sql = "INSERT INTO users (username, password, ssn, surname
, firstname, email, city, country)
VALUES(:alias, :password, :ssn, :surname
, :firstname, :email, :city, :country)";
$command=$connection->createCommand($sql);
$command->bindValue(":username", $model->alias);
$command->bindValue(":password", substr($model->ssn, -4,4));
$command->bindValue(":ssn", $model->ssn);
$command->bindValue(":surname", $model->lastName);
$command->bindValue(":firstname", $model->firstName);
$command->bindValue(":email", $model->email);
$command->bindValue(":city", $model->placeOfBirth);
$command->bindValue(":country", $model->placeOfBirth);
$command->execute();
$this->render('confirmation',array('model'=>$model));
}
This constructs the following query (as seen on the application log):
INSERT INTO users (username, password, ssn, surname, firstname, email
, city, country)
VALUES(:alias, :password, :ssn, :surname, :firstname, :email, :city, :country);
FYI $model->placeOfBirth is supposed to be in both city and county values. That's not a typo (just a silly thing I have to do).
Just to provide an answer - because this error is pretty common - here are a few causes:
The :parameter name does not match the bind by mistake (typo?). This is what happened here. They have :alias in the SQL statement, but bound :username. So when the param binding was attempted, Yii/PDO could not find :username in the sql statement, meaning it was "one parameter short" and threw an error.
Completely forgetting to add the bindValue() for a parameter. This is easier to do in Yii other constructs like $critera, where you have an array or params ($criteria->params = array(':bind1'=>'test', ':bind2'=>'test)).
another possible reason is invalid character in the placeholder name
Weird conflicts with CDataProvider Pagination and/or Sorting when using together and joins. There is no specific, easy way to characterize this, but when using complex queries in CDataProviders I have had weird issues with parameters getting dropped and this error occurring.
One very helpful way to troubleshoot these issues in Yii is to enable parameter logging in your config file. Add this to your db array in your config file:
'enableParamLogging'=>true,
And make sure the CWebLogRoute route is set up in your log section. This will print out the query that gave and error, and all of the parameters it was attempting to bind. Super helpful!
May be you are trying to bind a param within single quotes instead of letting it does the work for you.
Compare:
Model::model()->findAll("t.description ilike '%:filter%'", array(':filter' => $filter));
With:
Model::model()->findAll("t.description ilike :filter", array(':filter' => '%' . $filter . '%'));
A cause of this error for me not covered above is when you're dealing with a dynamic array of parameters if you unset any params, you need to reindex before passing them in. The brutal part of this is that your error log doesn't show indexes so it looks like everything is right. Eg:
SELECT id WHERE x = ?, y = ?, z = ?
Might produce the Log: Invalid parameter number: parameter was not defined with params ("x","y","z")
This looks like it shouldn't be throwing an error, but if the indexes are something like:
0 => x, 1 => y, 4 => z
It considers the last parameter undefined because it's looking for key 2.
I got this error when trying to do something like:
$stmt = $pdo->prepare("select name from mytable where id = :id");
$stmt->execute([
'id' => $id,
'unusedvar' => $foo, // This row causes the error.
]);
Basically, you can't have unused parameters in the array passed to execute(). Every value in the array passed to execute() must be used in your prepared statement.
This is also specified in the docs:
Binding more values than specified is not possible; if more keys exist in input_parameters than in the SQL specified in the PDO::prepare(), then the statement will fail and an error is emitted.
I've been using Yii's active record pattern for a while. Now, my project needs to access a different database for one small transaction. I thought the Yii's DAO would be good for this. However, I'm getting a cryptic error.
CDbCommand failed to execute the SQL statement: SQLSTATE[HY093]: Invalid parameter number: parameter was not defined
Here is my code:
public function actionConfirmation
{
$model_person = new TempPerson();
$model = $model_person->find('alias=:alias',array(':alias'=>$_GET['alias']));
$connection=Yii::app()->db2;
$sql = "INSERT INTO users (username, password, ssn, surname
, firstname, email, city, country)
VALUES(:alias, :password, :ssn, :surname
, :firstname, :email, :city, :country)";
$command=$connection->createCommand($sql);
$command->bindValue(":username", $model->alias);
$command->bindValue(":password", substr($model->ssn, -4,4));
$command->bindValue(":ssn", $model->ssn);
$command->bindValue(":surname", $model->lastName);
$command->bindValue(":firstname", $model->firstName);
$command->bindValue(":email", $model->email);
$command->bindValue(":city", $model->placeOfBirth);
$command->bindValue(":country", $model->placeOfBirth);
$command->execute();
$this->render('confirmation',array('model'=>$model));
}
This constructs the following query (as seen on the application log):
INSERT INTO users (username, password, ssn, surname, firstname, email
, city, country)
VALUES(:alias, :password, :ssn, :surname, :firstname, :email, :city, :country);
FYI $model->placeOfBirth is supposed to be in both city and county values. That's not a typo (just a silly thing I have to do).
Just to provide an answer - because this error is pretty common - here are a few causes:
The :parameter name does not match the bind by mistake (typo?). This is what happened here. They have :alias in the SQL statement, but bound :username. So when the param binding was attempted, Yii/PDO could not find :username in the sql statement, meaning it was "one parameter short" and threw an error.
Completely forgetting to add the bindValue() for a parameter. This is easier to do in Yii other constructs like $critera, where you have an array or params ($criteria->params = array(':bind1'=>'test', ':bind2'=>'test)).
another possible reason is invalid character in the placeholder name
Weird conflicts with CDataProvider Pagination and/or Sorting when using together and joins. There is no specific, easy way to characterize this, but when using complex queries in CDataProviders I have had weird issues with parameters getting dropped and this error occurring.
One very helpful way to troubleshoot these issues in Yii is to enable parameter logging in your config file. Add this to your db array in your config file:
'enableParamLogging'=>true,
And make sure the CWebLogRoute route is set up in your log section. This will print out the query that gave and error, and all of the parameters it was attempting to bind. Super helpful!
May be you are trying to bind a param within single quotes instead of letting it does the work for you.
Compare:
Model::model()->findAll("t.description ilike '%:filter%'", array(':filter' => $filter));
With:
Model::model()->findAll("t.description ilike :filter", array(':filter' => '%' . $filter . '%'));
A cause of this error for me not covered above is when you're dealing with a dynamic array of parameters if you unset any params, you need to reindex before passing them in. The brutal part of this is that your error log doesn't show indexes so it looks like everything is right. Eg:
SELECT id WHERE x = ?, y = ?, z = ?
Might produce the Log: Invalid parameter number: parameter was not defined with params ("x","y","z")
This looks like it shouldn't be throwing an error, but if the indexes are something like:
0 => x, 1 => y, 4 => z
It considers the last parameter undefined because it's looking for key 2.
I got this error when trying to do something like:
$stmt = $pdo->prepare("select name from mytable where id = :id");
$stmt->execute([
'id' => $id,
'unusedvar' => $foo, // This row causes the error.
]);
Basically, you can't have unused parameters in the array passed to execute(). Every value in the array passed to execute() must be used in your prepared statement.
This is also specified in the docs:
Binding more values than specified is not possible; if more keys exist in input_parameters than in the SQL specified in the PDO::prepare(), then the statement will fail and an error is emitted.
I've been using Yii's active record pattern for a while. Now, my project needs to access a different database for one small transaction. I thought the Yii's DAO would be good for this. However, I'm getting a cryptic error.
CDbCommand failed to execute the SQL statement: SQLSTATE[HY093]: Invalid parameter number: parameter was not defined
Here is my code:
public function actionConfirmation
{
$model_person = new TempPerson();
$model = $model_person->find('alias=:alias',array(':alias'=>$_GET['alias']));
$connection=Yii::app()->db2;
$sql = "INSERT INTO users (username, password, ssn, surname
, firstname, email, city, country)
VALUES(:alias, :password, :ssn, :surname
, :firstname, :email, :city, :country)";
$command=$connection->createCommand($sql);
$command->bindValue(":username", $model->alias);
$command->bindValue(":password", substr($model->ssn, -4,4));
$command->bindValue(":ssn", $model->ssn);
$command->bindValue(":surname", $model->lastName);
$command->bindValue(":firstname", $model->firstName);
$command->bindValue(":email", $model->email);
$command->bindValue(":city", $model->placeOfBirth);
$command->bindValue(":country", $model->placeOfBirth);
$command->execute();
$this->render('confirmation',array('model'=>$model));
}
This constructs the following query (as seen on the application log):
INSERT INTO users (username, password, ssn, surname, firstname, email
, city, country)
VALUES(:alias, :password, :ssn, :surname, :firstname, :email, :city, :country);
FYI $model->placeOfBirth is supposed to be in both city and county values. That's not a typo (just a silly thing I have to do).
Just to provide an answer - because this error is pretty common - here are a few causes:
The :parameter name does not match the bind by mistake (typo?). This is what happened here. They have :alias in the SQL statement, but bound :username. So when the param binding was attempted, Yii/PDO could not find :username in the sql statement, meaning it was "one parameter short" and threw an error.
Completely forgetting to add the bindValue() for a parameter. This is easier to do in Yii other constructs like $critera, where you have an array or params ($criteria->params = array(':bind1'=>'test', ':bind2'=>'test)).
another possible reason is invalid character in the placeholder name
Weird conflicts with CDataProvider Pagination and/or Sorting when using together and joins. There is no specific, easy way to characterize this, but when using complex queries in CDataProviders I have had weird issues with parameters getting dropped and this error occurring.
One very helpful way to troubleshoot these issues in Yii is to enable parameter logging in your config file. Add this to your db array in your config file:
'enableParamLogging'=>true,
And make sure the CWebLogRoute route is set up in your log section. This will print out the query that gave and error, and all of the parameters it was attempting to bind. Super helpful!
May be you are trying to bind a param within single quotes instead of letting it does the work for you.
Compare:
Model::model()->findAll("t.description ilike '%:filter%'", array(':filter' => $filter));
With:
Model::model()->findAll("t.description ilike :filter", array(':filter' => '%' . $filter . '%'));
A cause of this error for me not covered above is when you're dealing with a dynamic array of parameters if you unset any params, you need to reindex before passing them in. The brutal part of this is that your error log doesn't show indexes so it looks like everything is right. Eg:
SELECT id WHERE x = ?, y = ?, z = ?
Might produce the Log: Invalid parameter number: parameter was not defined with params ("x","y","z")
This looks like it shouldn't be throwing an error, but if the indexes are something like:
0 => x, 1 => y, 4 => z
It considers the last parameter undefined because it's looking for key 2.
I got this error when trying to do something like:
$stmt = $pdo->prepare("select name from mytable where id = :id");
$stmt->execute([
'id' => $id,
'unusedvar' => $foo, // This row causes the error.
]);
Basically, you can't have unused parameters in the array passed to execute(). Every value in the array passed to execute() must be used in your prepared statement.
This is also specified in the docs:
Binding more values than specified is not possible; if more keys exist in input_parameters than in the SQL specified in the PDO::prepare(), then the statement will fail and an error is emitted.
I've been using Yii's active record pattern for a while. Now, my project needs to access a different database for one small transaction. I thought the Yii's DAO would be good for this. However, I'm getting a cryptic error.
CDbCommand failed to execute the SQL statement: SQLSTATE[HY093]: Invalid parameter number: parameter was not defined
Here is my code:
public function actionConfirmation
{
$model_person = new TempPerson();
$model = $model_person->find('alias=:alias',array(':alias'=>$_GET['alias']));
$connection=Yii::app()->db2;
$sql = "INSERT INTO users (username, password, ssn, surname
, firstname, email, city, country)
VALUES(:alias, :password, :ssn, :surname
, :firstname, :email, :city, :country)";
$command=$connection->createCommand($sql);
$command->bindValue(":username", $model->alias);
$command->bindValue(":password", substr($model->ssn, -4,4));
$command->bindValue(":ssn", $model->ssn);
$command->bindValue(":surname", $model->lastName);
$command->bindValue(":firstname", $model->firstName);
$command->bindValue(":email", $model->email);
$command->bindValue(":city", $model->placeOfBirth);
$command->bindValue(":country", $model->placeOfBirth);
$command->execute();
$this->render('confirmation',array('model'=>$model));
}
This constructs the following query (as seen on the application log):
INSERT INTO users (username, password, ssn, surname, firstname, email
, city, country)
VALUES(:alias, :password, :ssn, :surname, :firstname, :email, :city, :country);
FYI $model->placeOfBirth is supposed to be in both city and county values. That's not a typo (just a silly thing I have to do).
Just to provide an answer - because this error is pretty common - here are a few causes:
The :parameter name does not match the bind by mistake (typo?). This is what happened here. They have :alias in the SQL statement, but bound :username. So when the param binding was attempted, Yii/PDO could not find :username in the sql statement, meaning it was "one parameter short" and threw an error.
Completely forgetting to add the bindValue() for a parameter. This is easier to do in Yii other constructs like $critera, where you have an array or params ($criteria->params = array(':bind1'=>'test', ':bind2'=>'test)).
another possible reason is invalid character in the placeholder name
Weird conflicts with CDataProvider Pagination and/or Sorting when using together and joins. There is no specific, easy way to characterize this, but when using complex queries in CDataProviders I have had weird issues with parameters getting dropped and this error occurring.
One very helpful way to troubleshoot these issues in Yii is to enable parameter logging in your config file. Add this to your db array in your config file:
'enableParamLogging'=>true,
And make sure the CWebLogRoute route is set up in your log section. This will print out the query that gave and error, and all of the parameters it was attempting to bind. Super helpful!
May be you are trying to bind a param within single quotes instead of letting it does the work for you.
Compare:
Model::model()->findAll("t.description ilike '%:filter%'", array(':filter' => $filter));
With:
Model::model()->findAll("t.description ilike :filter", array(':filter' => '%' . $filter . '%'));
A cause of this error for me not covered above is when you're dealing with a dynamic array of parameters if you unset any params, you need to reindex before passing them in. The brutal part of this is that your error log doesn't show indexes so it looks like everything is right. Eg:
SELECT id WHERE x = ?, y = ?, z = ?
Might produce the Log: Invalid parameter number: parameter was not defined with params ("x","y","z")
This looks like it shouldn't be throwing an error, but if the indexes are something like:
0 => x, 1 => y, 4 => z
It considers the last parameter undefined because it's looking for key 2.
I got this error when trying to do something like:
$stmt = $pdo->prepare("select name from mytable where id = :id");
$stmt->execute([
'id' => $id,
'unusedvar' => $foo, // This row causes the error.
]);
Basically, you can't have unused parameters in the array passed to execute(). Every value in the array passed to execute() must be used in your prepared statement.
This is also specified in the docs:
Binding more values than specified is not possible; if more keys exist in input_parameters than in the SQL specified in the PDO::prepare(), then the statement will fail and an error is emitted.
Can't believe there are no questions like this... Must be something really simple, but I spend 2 days trying to figure this one out.
I have a table and one of the coloumns has values in a JSON format. In PHP my syntax is like this (it's in a class function):
$sql = "INSERT INTO users.users (username, class, settings, email, password) VALUES ($this->username, $this->class, ".json_encode($this->settings).", $this->email, $this->hashpwd);";
$STH = $DBH->prepare($sql);
$STH->execute();
However this one of course breaks because JSON format contains commas and these commas are also separating the Insert values, so it breaks the query. And escape functions (like PDO->quote or mysqli_real_escape_string) don't escape commas either.
Error I am getting is of course:
...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
'"usersetting1":"value","usersetting2":"value"}, email#interwebz.net, 712985cc'...
So is there any way to do this or do I have to use some kind of alt syntax for the query?
Try this:
$sql = "INSERT INTO users.users (username, class, settings, email, password) VALUES (:username, :class, :json, :email, :password);";
$STH = $DBH->prepare($sql);
$STH->bindParam(':username', $this->username);
$STH->bindParam(':class', $this->class);
$STH->bindParam(':json', json_encode($this->settings));
$STH->bindParam(':email', $this->email);
$STH->bindParam(':password', $this->hashpwd);
$STH->execute();