Error in PDO Update Function - php

$table="menu_permission";
$field = array('permission'=>$mnuprmis);
$ob->update($table,$field,'staff_id',$stfid);
public function update($table, $fields, $wherefield, $wherefieldvalues)
{
$sql = "update $table set";
foreach ( $fields as $fieldname => $sfieldvalue )
$sql .= $fieldname."= '".$sfieldvalue."',";
$sql = substr($fldquery,0,strlen($fldquery)-1);
$sql .=" where $wherefield = '$wherefieldvalues'";
$q = $this->conn->prepare($sql);
$q->execute();
return true;
}
The error
Fatal error: Uncaught exception 'PDOException' with message '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 'where staff_id = '1'' at line 1'
in G:\xampp\htdocs\live\Billing Suryas\model\DBConfig.php:171
Stack trace: #0 G:\xampp\htdocs\live\Billing Suryas\model\DBConfig.php(171): PDOStatement->execute()
#1 G:\xampp\htdocs\live\Billing Suryas\pages\permission_pages.php(257): Connection->update('menu_permission', Array, 'staff_id', '1')
#2 {main} thrown in G:\xampp\htdocs\live\Billing Suryas\model\DBConfig.php on line 171

There is no such freaking thing as an $fldquery
$sql = substr($fldquery,0,strlen($fldquery)-1);
^^^ ^^^
Hence your query is only
$sql .=" where $wherefield = '$wherefieldvalues'";
Which results in
where staff_id = '1' // This is your COMPLETE query
That is just one of the problems and it will be fixed when you fix the typo and put in correct variable name there. However a bigger problem will be evident if you read this
How can I prevent SQL injection in PHP?

It might have had to do with the fact that you put single quotes around numeric values, which isn't necessary and might break your query since your DB might regard it as a string instead of a number.
$table="menu_permission";
$field = array('permission'=>$mnuprmis);
$ob->update($table,$field,'staff_id',$stfid);
public function update($table, $fields, $wherefield, $wherefieldvalues)
{
//
// COMPILE QUERY
$sql = "update $table set ";
$col_values_array = array();
foreach ( $fields as $fieldname => $sfieldvalue ) {
$value = is_numeric($sfieldvalue) ? $sfieldvalue : "'$sfieldvalue'";
$col_values_array[] = "$fieldname = $value";
}
$sql .= implode("," , $col_values_array);
$sql .= " where $wherefield = '$wherefieldvalues'";
//
// EXECUTE QUERY
//$q = $this->conn->prepare($sql); --> not required when not using parametrised queries
//$q->execute(); --> not required when not using parametrised queries
$this->conn->query($sql);
return true;
}
Also consider using prepared statements to be safe against SQL injection.

Related

Mistake in SQL syntax.. (bindValue?)

I am trying to create an update query and I am looping in some set stuff to a var called $str and I cant seem to get it to work.
if (is_numeric($id)) {
if (!empty($values) && !empty($table_name)) {
$str = '';
$sql = "UPDATE `$table_name` SET :update_values WHERE `$column_name` = :id";
// Its one because we dont use ID like that
$i = 1;
foreach ($values as $key => $value) {
if ($key != $column_name) {
// Exclude the last one from having a comma at the end
if ($i == count($values) - 1) {
$str .= "$key='" . $value . "'";
} else {
$str .= "$key='" . $value . "', ";
$i++;
}
}
}
$query = $this->dbh->prepare($sql);
$query->bindValue('update_values', $str, PDO::PARAM_STR);
$query->bindValue(':id', $id, PDO::PARAM_INT);
$query->execute();
return true;
} else {
return false;
}
} else{
return false;
}
}
Output:
Fatal error: Uncaught PDOException: SQLSTATE[42000]: Syntax error or
access violation: 1064 You have an error in your SQL syntax; check the
manual that corresponds to your MariaDB server version for the right
syntax to use near ''note_name=\'yeet\', note_date=\'2020-02-20\',
note_desc=\'asdasdasdasdadsasdads' at line 1
Am I making any obvious mistakes?
Also for the life of me I don't know what the backslashes in front of the values mean.
In MySQL, identifiers cannot be provided as values.
References to columns must appear in the text of the SQL statement, they cannot be provided through bind parameters. This holds true for table names, column names, function names.
There is no workaround; this is a by-design restriction. There's several reasons for this. One of the most straightforward reasons is understanding how a SQL statement gets prepared, the information that is needed to come up with an execution plan, the tables and columns have to be known at prepare time (for the semantic check and privilege check. The actual values can be deferred to execution time.
Bind placeholders are for providing values, not identifiers.
With the code given, what MySQL is seeing something along the lines of
UPDATE `mytable` SET 'a string value' WHERE `id_col` = 42
And MySQL is balking at the 'a string value'.
We can (and should) use bind parameters for values.
We could dynamically generate SQL text that looks like this:
UPDATE `mytable`
SET `col_one` = :val1
, `col_two` = :val2
WHERE `id_col` = :id
and after the SQL text is prepared into statement, we can bind values:
$sth->bindValue(':val1', $value_one , PDO::PARAM_STR );
$sth->bindValue(':val2', $value_two , PDO::PARAM_STR );
$sth->bindValue(':id' , $id , PDO::PARAM_INT );
and then execute

Using prepared statements but quotes not being escaped or removed

I am having an issue getting some things to insert into my database. If I put quotes single or double into my text fields it will break the query and will not escape them. I just got done reading that using prepared statements eliminates the need to call mysql_real_escape_string. Can someone tell me if I am executing my query wrong. $companyInfo is an array that contains about 8 rows to be inserted.
function InsertCompanyInfo($companyInfo, $conn) {
foreach($companyInfo as $key => $table) {
$keys = array_keys($table);
$values = null;
$x = 1;
foreach($table as $row => $value) {
$values .= "'$value'";
if($x < count($keys)) {
$values .= ', ';
}
$x++;
}
$sql = $conn->prepare("INSERT INTO {$key} (`" . implode('`, `', $keys) . "`) VALUES ({$values});");
$sql->execute();
$CompanyID = $conn->lastInsertId('CompanyID');
}
return $CompanyID;
}
This is the error I get when I insert qoutes:
Fatal error: Uncaught exception 'PDOException' with message '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 '1',
''''"'"''"';;''';';')' at line 1' in /var/www/Survey/InsertFunctions.php:20 Stack trace: #0
/var/www/Survey/InsertFunctions.php(20): PDOStatement->execute() #1
/var/www/Survey/testProcess.php(8): InsertCompanyInfo(Array, Object(PDO)) #2 {main} thrown
in /var/www/Survey/InsertFunctions.php on line 20
Prepared statements work by separating the query structure and the values in code like so:
$stmt = $pdo->prepare('INSERT INTO foo (bar) VALUES (?)');
This is the query structure, which the database is given first to understand. Then you give it the values separately:
$stmt->execute(array('baz'));
What you're doing instead is you call prepare on a completely formed query which includes crudely interpolated values. There's nothing prepare can do here. The entire problem of escaping values is that the database cannot figure out what a value was and what your part of the query was after the fact. If you're giving the query fully formed and incorrectly escaped to the database, it can't magically recognise what was supposed to be what. You need to add placeholders to the query and provide the corresponding values in a separate step.

Changing php script to PDO causing Syntax error during MySQL update query

I have a php script to update details in a MySQL table. It all worked fine but now I have changed the db connection method to PDO:
$pdo = new PDO('mysql:host=localhost;dbname=****', '****', '*****');
I made various changes to the script to accommodate this so it continues to work, The only place that fails is right at the end after the mysql table has been updated. I get this error:
Fatal error: Uncaught exception 'PDOException' with message '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 'and park_id=31' at line 1' in /home3/danville/public_html/test2/index.php:29 Stack trace: #0 /home3/danville/public_html/test2/index.php(29): PDO->query('update tpf_ride...') #1 {main} thrown in /home3/danville/public_html/test2/index.php on line 29
This is the piece of code causing the error:
$query = "update tpf_rides set name='$name',type='$type'";
if($topride!=""){$query .= ",top_ride=$topride";}
if($info!=""){$query .= ",info='$info'";}
if($height!=""){$query .= ",height=$height";}
if($length!=""){$query .= ",length=$length";}
if($speed!=""){$query .= ",speed=$speed";}
if($inversions!=""){$query .= ",inversions=$inversions";}
$query .= " where ride_id=".$ride_id." and park_id=".$park_id;
$pdo->query($query);
}
line 29 is this on Notepad++ $pdo->query($query); although the error message seems to reference the line above that $query .= " where ride_id=".$ride_id." and park_id=".$park_id;
Any ideas what I ned to change to stop the error? Additional details - I connect to the db with a require_once include. The updates do take effect despite the error.
If you're going to switch to PDO, you might as well take advantage of prepared statements and parameter binding. It actually makes your queries much safer from SQL injection and also makes your code more readable. Your query builder approach does complicate things a little but it's still possible. I'd also highly recommend enabling error reporting during development. For example
error_reporting(E_ALL);
ini_set('display_errors', 'On');
$upd = array('name = :name', 'type = :type');
$values = array(
'name' => $name,
'type' => $type,
'ride_id' => $ride_id,
'park_id' => $park_id
);
if (!empty($topride)) {
$upd[] = 'top_ride = :topride'; // :topride is the named parameter placeholder
$values['topride'] = $topride; // the array key matches the named placeholder above
}
if (!empty($info)) {
$upd[] = 'info = :info';
$values['info'] = $info;
}
// and so on
$query = sprintf('UPDATE tpf_rides SET %s WHERE ride_id = :ride_id AND park_id = :park_id',
implode(', ', $upd));
$stmt = $pdo->prepare($query);
$stmt->execute($values);

Why is this MySQL INSERT not working in CI?

For some reason this SQL statement is not working. Can anyone tell me why? (This is a Codeigniter site, if that matters)
Here is my Model (where my error is pointing me to)
public function edit_profile($ID, $field, $new_info)
{
$sql = "UPDATE users SET ?=? WHERE id=?";
$query = $this->db->query($sql, array($field, $new_info, $ID)); // <<<< LINE 42
return $query;
}
And this is the error I'm getting
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 ''first_name'='oooo' WHERE id='151'' at line 1
UPDATE users SET 'first_name'='oooo' WHERE id='151'
Filename: /Applications/MAMP/htdocs/MY_SITE/models/member_model.php
Line Number: 42
My table is called 'users', and I have a 'first_name' and 'id' column.
Ideas?
EDIT
Just because it seems to come up a bit I want to clarify that the variables I am passing in here have NO QUOTES OR BACKTICKS. They are being added somewhere (and it seems like the ->query method, but I cant imagine that's true? .. dunno though, cause it's my first CI project)
Here is the controller that is passing to the model...
public function profileEdit()
{
$ID = $this->the_user->id;
$field = $this->input->post('edit_field')
$field = strstr($field,'_edit', true);
$new_info = $this->input->post('new_info');
$this->load->model('Member_model');
if( $this->Member_model->edit_profile( $ID, $field, $new_info )){
echo 'success';
}
else
{
echo 'error';
}
}
i suggest use like this :
public function edit_profile($ID, $field, $new_info)
{
$sql = "UPDATE users SET $field =? WHERE id=?"; # UPDATED (remove $this->db->escape())
$query = $this->db->query($sql, array($new_info, $ID)); // <<<< LINE 42
return $query;
}
if $field is not secured you can use escape functions .
EDIT :
$this->db->escape() will add quotes around variable so you will get an error again .

sprintf() Versus mysql_query()

Having trouble formatting my code to execute without error using sprintf() When I run the code I get this error: Parse error: syntax error, unexpected T_VARIABLE in /location on line 16
$query = sprintf('UPDATE `%s` SET `stock` = :amount WHERE `itemname` = '$q'', $tablename);
Above is line 16 in my code. I'm assuming it is syntax related.
I am now receiving the following error:
Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[42000]: Syntax error or access violation: 1065 Query was empty' in /home/content/63/6563663/html/inventory/pg.php:19 Stack trace: #0 /home/content/63/6563663/html/inventory/pg.php(19): PDOStatement->execute() #1 {main} thrown in /home/content/63/6563663/html/inventory/pg.php on line 19
This is my entire code block:
<?php
$u=$_GET["u"];
if ((isset($_POST["MM_update"])) && ($_POST["MM_update"] == "form2")) {
$amount = isset($_POST['amount']) ? $_POST['amount'] : null;
if (null != $amount) {
$user = 'username';
$pass = 'password';
$pdo = new PDO('mysql:localhost', $user, $pass);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
session_start();
$tablename = $_SESSION['MM_Username'];
$query = sprintf('UPDATE %s SET stock= :amount WHERE itemname= '.$u, $tablename);
$stmt = $pdo->prepare($UpdateQuery);
$stmt->bindParam('amount', $amount);
$stmt->execute();
}
}
?>
Thank you, seems my error is dealing with the PDO execution, not the query itself. If anyone has any ideas on that it would be great. Alan, I used your method for the quotes and also am running the query through mysql_real_escape_string().
Please do not build SQL queries out of variables. Use bind variables.
See http://bobby-tables.com/php.html
Try this:
$query = sprintf('UPDATE%sSETstock= :amount WHEREitemname= '.$q, $tablename);
You need to put a concatenation operator between strings and variables to combine them together. You also can get rid of the '' after $q because it is not changing the string at all.
Edit:
I believe I misread what you are trying to do. Try this instead:
$query = sprintf("UPDATE%sSETstock= :amount WHEREitemname= '$q'", $tablename);
By changing your PHP string to be within double quotes, you do not need to escape your single quotes, and $q will be expanded to its value.
Also, be sure that you run $q and $tablename through mysql_real_escape_string() to prevent SQL injection.
Like so:
$query = sprintf('UPDATE `%s` SET `stock` = :amount WHERE `itemname` = \'$q\'', $tablename);
or
$query = sprintf("UPDATE `%s` SET `stock` = :amount WHERE `itemname` = \'$q\'", $tablename);
You can't have unescaped 's in strings delimited by '. Either unescaped "s in strings delimited by ". To escape the string delimiter you need to prepend a \ character.

Categories