I am into situation where i dont know which fields would be set to update , i can get the columns and respected values which need to updated, but how can i get the type of each field for binding parameters using mysqli ?
UPDATE City SET Name = ?,CountryCode = ?,District = ? WHERE 1
Lets say this is the query i got as for now .. and I would something like this to update ..
$stmt = $conn->stmt_init();
if($stmt->prepare($query)) {
$stmt->bind_param('sss', $name, $countrycode, $district);
$stmt->execute();
}
but what if i dont know 'sss' ( in dynamic context ) ?
You can use string for everything. MySQL will convert strings to numbers when necessary. Just as you can do something like:
SET id = '123'
when writing a regular query.
Related
I'm building sql UPDATE query to append string value using only NAMED PLACEHOLDERS to the already existing value in db. please suggest necessary changes in below code to work or suggest how to use named placedholders in concat update syntax
$name="Lastname";
$stmt = $conn->prepare("UPDATE users SET name= name + :name WHERE id=:id");
$stmt->bindParam(':name', $name);
$stmt->bindParam(':id', $id);
$stmt->execute();
Expected Output:
Before: Table has 'name' column-value "Firstname"
After code execution: 'name' column-value "FirstnameLastname"
+ is not the normal way to concatenate strings in SQL. The standard operator is || and the function concat() is usually available:
UPDATE users
SET name = CONCAT(name, :name)
WHERE id = :id;
I'm trying to check to see if a column exists.. If it does, then I want to update the value, and if it doesn't, I want to alter the table and add the column with the a value. I'm pretty new to PDO, but I'm pretty sure my query is fine, I just don't know how to handle the output from the execute() command I guess. Thanks for the help in advance!
$sth = $pdo->prepare(' SELECT ? FROM `?` WHERE column_name=? ');
$sth->bindParam(1, $column, PDO::PARAM_STR);
$sth->bindParam(2, $livetable, PDO::PARAM_STR);
$sth->bindParam(3, $column, PDO::PARAM_STR);
$sth->execute();
if ($sth) {
//Row Exist - Update Value
echo 'Row Exist';
}else{
//Row Doesn't Exist - Create column & update with value
echo 'row does not';
}
You cannot pass a table name as a bind parameter like this, you would need to use dynamic SQL to achieve this. But if you just want to check if a column exist in a table, don’t query the table directly (what if it contains millions of records ?) ; instead, query Postgres information schema, as follows :
SELECT column_name
FROM information_schema.columns
WHERE
table_name = ?
AND column_name = ?;
I have a web program which allows the administrator to update a user's information... With that being said, I only want columns updated which have indeed been 'updated'...
I have done quite a bit of researching on this and it seems that all methods use outdated querys, which do not make use of the prepare statement to escape input...
Can someone please help me with the statement?
Essentially in psuedocode:
Update FIRSTNAME if $editedUserdata['firstname'] != FIRSTNAME, LASTNAME if $editedUserData['lastname'] != LASTNAME ...etc...
Here is what I have for the post code...
$password = sha1($password);
$editedUserData = array(
'firstname' => $firstname,
'lastname' => $lastname,
'username' => $username,
'password' => $password,
'cellphone' => $cellphone,
'security_level' => $seclvl,
'email' => $email,
'direct_phone' => $direct,
'ext_num' => $extension,
'is_active' => $userflag
);
Then it should be something like
$query = $this->db->prepare('UPDATE FIRSTNAME if(?) IS NOT FIRSTNAME, LASTNAME if(?) IS NOT LASTNAME, USERNAME if (?) IS NOT USERNAME.... VALUES (:firstname, :lastname, :username).....'
if ($query -> execute($editedUserData)) {
more code....
According to MySQL documentation -
Ref: (http://dev.mysql.com/doc/refman/5.0/en/update.html)
"If you set a column to the value it currently has,
MySQL notices this and does not update it."
Maybe I'm not understanding the problem which you're trying to solve but you don't have to test if field value did change.
If field value is "A" and you put there an "A" it will remain the same otherwise, if you put there a "B" it will be updated as expected
The prepared statement would be something like
$stmt = $dbh->prepare("
UPDATE table_name
SET
field1 = :value1,
field2 = :value2
WHERE
field0 = :key
");
$stmt->bindParam(':value1', $value1, PDO::PARAM_STR);
$stmt->bindParam(':value2', $value2, PDO::PARAM_STR);
$stmt->bindParam(':key', $key, PDO::PARAM_INT);
$stmt->execute()
Run a single statement to update the row.
Firstly, what's the unique identifier for a row in the users table, is there a unique userid or username? You'll want a WHERE clause on the UPDATE statement so that only that row will be updated.
The normative pattern for an UPDATE statement to update several columns in a single row is like this:
UPDATE users
SET col2 = 'value'
, col3 = 'another value'
, col4 = 'fi'
WHERE idcol = idvalue ;
To use a prepared statement with PDO, the SQL text could look something like this, if you use named placeholders:
UPDATE users
SET col2 = :col2_value
, col3 = :col3_value
, col4 = :col4_value
WHERE idcol = :id_value
Or this, if you use positional notation for the placeholders:
UPDATE users
SET col2 = ?
, col3 = ?
, col4 = ?
WHERE idcol = ?
(My personal preference is to use the named placeholders, rather than positional, but either will work.)
This is how I'd do it, run the prepare, then the bind_param, and then the execute.
$sql = "UPDATE users
SET col2 = :col2_value
, col3 = :col3_value
, col4 = :col4_value
WHERE idcol = :id_value ";
$stmt = $dbh->prepare($sql);
$stmt->bindParam(':col2_value', $col2_val, PDO::PARAM_STR);
$stmt->bindParam(':col3_value', $col3_val, PDO::PARAM_STR);
$stmt->bindParam(':col4_value', $col4_val, PDO::PARAM_STR);
$stmt->bindParam(':id_value' , $id_val, PDO::PARAM_STR);
$stmt->execute();
To do something different, to dynamically create the SQL text, and adjust the bindParam calls, that would add unnecessary complexity to the code. There's no performance advantage to doing that; when that UPDATE statement runs, MySQL has to lock the row, store a new copy of the row. It doesn't really save anything (aside from a few bytes of data transfer) to avoid sending a column value that hasn't changed.
If you realy want to use cases, read this.
There is no reason to do it in your case, as stated from #spencer7593 in the comments:
That's WAY more overhead... roundtrips to the database, parsing the
statement, developing an execution plan, executing the statement,
obtaining locks, returning a status, client checking the status, etc.
That's just seems an all-around inefficient approach.
I assume that any RDBMS is smart enough, to notice, that Caches etc should not be recalculated (if nothing changes), if that is the problem.
I have a query that looks like this:
UPDATE table SET column = UNIX_TIMESTAMP()
WHERE id IN (:idString)
Where idString is a string of comma separated ids and is passed to execute() in an array. To my surprise, when this query is executed, only the row with the first id in idString is updated.
After banging my head against the wall for a while, I finally decided to try it like this:
UPDATE table SET column = UNIX_TIMESTAMP()
WHERE id IN (' . $idString . ')
The second query works as expected.
Why won't the query work when I bind the string of ids using PDO?
In SQL, the string
'1,2,3,5,12'
Is a single value, and casting it in a numeric context, it will just have the value of the leading digits, so just the value 1.
This is much different from the set of multiple values:
'1', '2', '3', '5', '12'
Any time you use bound parameters, whatever you pass as the parameter value becomes just one single value, even if you pass a string of comma-separated values.
If you want to pass a set of multiple values to parameters in your SQL query, you must have multiple parameter placeholders:
UPDATE table SET column = UNIX_TIMESTAMP()
WHERE id IN (:id1, :id2, :id3, :id4, :id5)
Then explode your string of values and pass them as an array:
$idlist = array('id1' => 1, 'id2' => 2, 'id3' => 3, 'id4' => 5, 'id5' => 12);
$pdoStmt->execute($idlist);
For cases like this, I would recommend using positional parameters instead of named parameters, because you can pass a simple array instead of an associative array:
$pdoStmt = $pdo->prepare("UPDATE table SET column = UNIX_TIMESTAMP()
WHERE id IN (?, ?, ?, ?, ?)");
$idlist = explode(",", "1,2,3,5,12");
$pdoStmt->execute($idlist);
#mario adds a comment that you can use FIND_IN_SET(). That query would look allow you to pass one string formatted as a comma-separated string of values:
$pdoStmt = $pdo->prepare("UPDATE table SET column = UNIX_TIMESTAMP()
WHERE FIND_IN_SET(id, :idString)");
$pdoStmt->execute(["idString" => "1,2,3,5,12"]);
However, I usually don't recommend that function because it spoils any chance of using an index to narrow down the search. It will literally have to examine every row in the table, and during an UPDATE that means it has to lock every row in the table.
Your working solution is not good as it's subject to SQL INJECTION.
The reason it's not working is because you are allocating an array, instead of plain comma separated values.
You have to use implode to separate the values of the array, and then assign the comma separated values to a variable wich can be used by pdo.
Otherwise you can use instead of : $idString, ? in the select statement, and executing the prepared statement from and array which holds the $idString.
$query=$db->prepare("Select a From table where b =? order by 1;");
$query->execute(array($idString));
You are trying to pass a string as a set to a prepared statement. MySQL is trying to execute the query
-- assuming idString is "1,2,3,4,5"
UPDATE table SET column = UNIX_TIMESTAMP() WHERE id IN ("1,2,3,4,5");
instead of
UPDATE table SET column = UNIX_TIMESTAMP() WHERE id IN (1,2,3,4,5);
you'll have to either use the statement
UPDATE table SET column = UNIX_TIMESTAMP() WHERE id == ?
and execute it for however many id's you have or prepare the statement by injecting id string into the query
When binding, PDO expects a single value. Something like this will work, given your $idString above (though if you have the source array, even better!):
$ids = explode(',', $idString);
$placeholders = implode(', id', array_keys($ids));
if($placeholders) {
$placeholders = 'id' . $placeholders;
$sql = "UPDATE table SET column = UNIX_TIMESTAMP()
WHERE id IN ({$placeholders})";
// prepare your statement, yielding "$st", a \PDOStatement
$st = $pdo->prepare($sql);
// bind every placeholder
foreach($ids as $key => $id) {
$st->bindValue("id{$key}", $id);
}
// execute
$st->execute();
}
So I am trying to change the status of something when values are met using WHERE
Code:
$insertstatus = $DBH->prepare("INSERT INTO
csvdata (status) VALUES ('$status') WHERE username = '".$username."'");
$insertstatus->execute();
Not working. If you could give me a hand.
Thank you for your time!
If you want to use the where clause, you need to use update. From the looks of it, you are trying to update anyhow as you are only using one column from your table.
$insertstatus = $DBH->prepare("update
csvdata set status= '$status' WHERE username = '".$username."'");
$insertstatus->execute();
As PeeHaa correctly points out though, using a prepared statement with parameters would be a slight change in your code, and a better option for you. You can do it like this:
$sql="update csvdata set status=:status where username=:username";
$sth=$DBH->prepare($sql);
$sth->execute(array(':status' => $status, ':username' => $username));
This way you are preparing the statement so the database knows what will happen. You then pass the variables to the database via the execute() function in an array.