MySQL - Build a query string - php

I've tried aLL of the below yet I can't seem to get it working
$sql="UPDATE filename SET weekday = {$_GET[wkd]} WHERE id = 2";
$sql="UPDATE filename SET weekday = '$_GET[wkd]' WHERE id = 2";
$sql="UPDATE filename SET weekday = '"{$_GET[wkd]}"' WHERE id = 2";
$sql="UPDATE filename SET weekday = '."{$_GET[wkd]}".' WHERE id = 2";
What is the correct way?
Thanks

The proper way? Assuming $link is your mysqli_connect
$wkd = mysqli_real_escape_string($link, $_GET['wkd']);
$sql = "UPDATE filename SET weekday = '" . $wkd . "' WHERE id = 2";
http://de1.php.net/manual/en/mysqli.real-escape-string.php

This:
$sql="UPDATE filename SET weekday = '" . $_GET['wkd'] . "' WHERE id = 2";
FYI, this is very bad coding practice, you should validate $_GET before add to sql.

Alright. If weekday accepts string values, then the value needs to be surrounded with quotes, ie:
$sql="UPDATE filename SET weekday = '" . $_GET['wkd'] . "' WHERE id = 2";
This is also equivalent to:
$sql="UPDATE filename SET weekday = '{$_GET['wkd']}' WHERE id = 2";
The first concatenates the string together, the second simply inserts the variable directly into the string.
For $_GET['wkd'] = "tuesday";, bot of those queries output this:
UPDATE filename SET weekday = 'tuesday' WHERE id = 2
If weekday only accepts numeric values, then there is no need to surround the value with quotes (but you still can):
$sql="UPDATE filename SET weekday = " . $_GET['wkd'] . " WHERE id = 2";
Which like the first, is equivalent to:
$sql="UPDATE filename SET weekday = {$_GET['wkd']} WHERE id = 2";
Which for $_GET['wkd'] = 1, will have both queries output:
UPDATE filename SET weekday = 1 WHERE id = 2
Point is - there is no one correct syntax, they'd all work.
However, what you really want to be doing is using pdo or mysqli with prepared statements and parameter binding, like so:
$pdo = new PDO('... connection string ... ');
$stmt = $pdo->prepare("UPDATE filename SET weekday = ? WHERE id = ?");
$stmt->execute(array($_GET['wkd'], 2));
This will bind the value of $_GET['wkd'] to the first ? in the prepared statement, and the literal 2 to the value of the second `?'. If you find yourself using lots of question marks, or losing track of the order, you can also use named placeholders like this:
$pdo = new PDO('... connection string ... ');
$stmt = $pdo->prepare("UPDATE filename SET weekday = :weekday WHERE id = :id");
$stmt->execute(array(
'weekday' => $_GET['wkd'],
'id' => 2
));
In that example i've named the placeholders the same as the fields - this isn't necessary but it is obviously more readable than naming the placeholders :asdfasdf and :lmnop (in which case the array being passed to the execute function would be ('asdfasdf' => $_GET['wkd'], 'id' => 2)
Why use the parameter binding? Its your best defense against SQL Injection

Related

Update SQL database in rows where variable is not empty

I want to create a simple SQL UPDATE query which can check via an IF statement that the passed POST variable is empty or not. If empty then won't modify the original value, if not then update. I just can't figure out how I did it before.
It should be something like that, but not working:
$sql = "UPDATE Clients SET Name = IF(" . $_POST['edit_client_name'] .
" = '', Name, " .
mysqli_real_escape_string( $this -> link, $_POST['edit_client_name'] ) .
" WHERE Id=" . $_GET['selected_client'] . "";
You need to check this in application not query. Like
if(isset($_POST['edit_client_name'])){
$name = mysqli_real_escape_string( $this -> link, $_POST['edit_client_name'] );
$id = mysqli_real_escape_string( $this -> link, $_GET['selected_client'] );
mysqli_query("UPDATE Clients SET Name = '".$name."' WHERE Id=".$id."');
}
You can tweak through the SQL instead of doing checks in the DB.
I skipped the SQL Injection prevention part.
<?php
if(empty($_POST['edited_client_name'])){
$namequery = '';
}
else{
$namequery = "Name = '".$_POST['edited_client_name']."'";
}
$sql = "UPDATE Clients SET ".$namequery." WHERE ID = ".$_GET['selected_client'];
echo $sql;
?>
returns:
UPDATE Clients SET Name = 'foo' WHERE ID = 1
when edited_client_name is provided,
else returns:
UPDATE Clients SET WHERE ID = 1
Hope this will give you an idea what to do with your code.

sql add one to field value

I'm having problems with an INT field. The thing is when I print the value on screen is OK but when I update the database register adds one more.
$today = date('Y-m-d H:i:s');
$query = "SELECT id_ad, ad_printed FROM ads WHERE (ad_type = \"990x90\" OR (ad_type = \"728x90\" OR ad_type = \"250x90\")) AND ad_date_start <= \"$today\" AND ad_date_finish >= \"$today\"";
$result = mysqli_query($link, $query);
while ($row = mysqli_fetch_array($result)) {
$new_value = $row['ad_printed'] + 1;
$curr_id = $row['id_ad'];
$query_upd = "UPDATE ads SET ad_printed = '".$new_value."' WHERE id_ad = '".$curr_id."' LIMIT 1;";
$upd = mysqli_query($link, $query_upd);
}
Does anybody know what could be happened?
I.E. If the original value is 26, the new value must be 27. The $new_value is 27 but it registers as 28... :(
if you like to increase a value in sql don't wrap the column value into quotes, otherwise sql handle the column value as a string. please make sure your column type is correct like integer and not varchar
UPDATE ads SET ad_printed = (ad_printed + 1) WHERE id_ad = '".$curr_id."' LIMIT 1;
//edit
if you pass variables directly into sql please look at the mysqli_real_escape_string function to prevent sql injections.
http://de2.php.net/manual/de/mysqli.real-escape-string.php

How do I update a certain column when a value from the same row equals a variable?

I have been trying to do this for hours now, and I can't quite get my head round it. I have a table called "requests" that has the columns "deletekey" and "deleted". "deletekey" is a random unique number (data-type text), and "deleted" is by default set to 0 (data-type boolean), and when the user inputs the deletekey, it changes "deleted" to 1.
But I can't get it to work.
Here is the code I have, and I have no idea what I'm doing wrong:
$key = $_GET["delkey"];
$link = mysqli_connect("localhost","username","password","dbname");
$query = 'UPDATE requests SET deleted = True WHERE deletekey = "$key"';
$result = $link->query($query);
This should help, and will also provide protection against SQL injection:
$link = mysqli_connect("localhost","username","password","dbname");
$key = $link->real_escape_string($_GET["delkey"]);
$query = sprintf("UPDATE requests SET deleted = 1 WHERE deletekey = '%s'", $key);
$result = $link->query($query);
Shouldn't it be WHERE deletekey = '$key', then? The deleted field could NEVER equal whatever's in $key, since deleted is a simple boolean, and $key is probably an int/char/varchar-type thing.
Note that you are vulnerable to SQL injection attacks. Stop working on this sort of code until you've learned about the problem and how to avoid it.
Its deletedkey = "$key" right ? and not deleted = "$key" :
$key = $_GET["delkey"];
$link = mysqli_connect("localhost","username","password","dbname");
$query = 'UPDATE requests SET deleted = true WHERE deletedkey = "$key"';
$result = $link->query($query);
Try this?
$link = mysqli_connect("localhost","username","password","dbname");
$key = $link->real_escape_string($_GET["delkey"]);
$query = "UPDATE `requests` SET `deleted` = true WHERE `deletedkey` = $key";
$result = $link->query($query);
$query = 'UPDATE requests SET deleted = 1 WHERE deletekey = "$key"';
the query is a string. And to add a variable to a string you need to type
$query = 'UPDATE requests SET deleted = True WHERE deleted = '".$key."';
the difference is how to make a variable put into the string. You have to do like this in php.
$query = "randomtext ". $randomvar ." ";
where the important point is to ". $var ." inside the string. This i similar to javas "+ var +"

MySql Fetch Array manipulation

Ok..I know how to get a data record from a MySql table...and I want to change data in that record and update the table.
My question is...can you actually manipulate that data from the result row, and subsequently use those in the update statement?
For example.
Let's say the table rows have 2 fields: Name, YearlyEarn.
And once a month I want to add that month's income to the YearlyEarn field for each person.
Assume we already did the Select statement for someone who's name is in $CurrentName.
And we then get their record.
$DataRow = mysql_fetch_array($result):
Can you do this:
$DataRow["YearlyEarn"] = $DataRow["YearlyEarn"] + $MonthEarn;
$query = "UPDATE EarnTable SET YearlyEarn = '$DataRow["YearlyEarn"]'
`WHERE Name = '$CurrentName'" ;
$UpdResult = mysql_query($query) or die(mysql_error());
OR.....should I put the data into intermediate fields, manipulate it..and then use those fields in the update statement?
You should use prepared statements, like PDO. The mysql_* is outdated. But if not doing so, you should consider changing your query from:
$query = "UPDATE EarnTable SET YearlyEarn = '$DataRow["YearlyEarn"]'`WHERE Name = '$CurrentName'" ;
to:
$query = "UPDATE EarnTable SET YearlyEarn = `" . $DataRow['YearlyEarn'] . "` WHERE Name = `$CurrentName`" ;
Yes, you can:
UPDATE EarnTable
SET YearlyEarn = YearlyEarn + 123
WHERE Name = 'abc'
You can use:
$query = "UPDATE EarnTable SET YearlyEarn = '$DataRow[YearlyEarn]' WHERE Name = '$CurrentName'" ;
When you're interpolating an array reference, the key is automatically quoted.
or:
$query = "UPDATE EarnTable SET YearlyEarn = '{$DataRow["YearlyEarn"]}' WHERE Name = '$CurrentName'" ;
Inside {...}, you can put any variable expression and it will be evaluated and interpolated.

MySQL update query, how to skip empty values?

I've got such query:
$sql = "UPDATE test_accs SET
acc_owner = '$owner_id',
acc_policy_version = '$version',
acc_policy_last_update = '$approved',
acc_policy_next_update = '$renewed'
WHERE acc_id = '1'";
Now, all of these values on the web folmular are optional, one can set one of these values, two, or so. Now, after I submit the form, it goes in the query like that:
UPDATE test_accs SET acc_owner = '2', acc_policy_version = '1.2', acc_policy_last_update = '2012-12-19', acc_policy_next_update = '2012-12-18' WHERE acc_id = '1'
It works only when I submit all values from the form. Can you please show me how could it work even if not all the values has been sent, just for example one of them?
When I set one value (f.ex. policy version), it looks like that:
UPDATE test_accs SET acc_owner = '', acc_policy_version = '1.2', acc_policy_last_update = '', acc_policy_next_update = '' WHERE acc_id = '1'
and it isn't working.
It might be possible cause of the acc_owner table values?
#1366 - Incorrect integer value: '' for column 'acc_owner' at row 1
Thanks in advice.
Form:
echo '<td>Change owner: <select name="owner_id" onchange="showUser(this.value)" style="font-size:9px"><option value="">Select a person:</option>';
while($owners = mysql_fetch_array($owners_query)) { echo '<option value="'.$owners['id'].'">'.$owners['surname'].' '.$owners['name'].'</option></h2>'; } echo '</select></td>';
echo "<td><input name='version' style='width:50px;text-align:center' placeholder='0.0' /></td>";
echo "<td><input name='approved' class='datepicker_all' readonly='readonly' style='text-align:center' placeholder='1999-01-01' /></td>";
echo "<td><input name='renewed' class='datepicker_all' readonly='readonly' style='text-align:center' placeholder='1999-01-01' /></td>";
One way to accomplish this is to use an expression in the SQL statement that tests whether the supplied value is an empty string. If the supplied value is an empty string, then use the current value of the column as the value to assign to the column. Otherwise, assign the supplied value to the column.
In the example below, the each of the supplied values have to be include TWICE in the statement: once in the conditional test, and then again, as a possible result of the conditional test.
This statement:
UPDATE test_accs
SET acc_owner = IF('2'='',acc_owner,'2')
, acc_policy_version = IF('1.2'='',acc_policy_version,'1.2')
, acc_policy_last_update = IF('2012-12-19'='',acc_policy_last_update,'2012-12-19')
, acc_policy_next_update = IF('2012-12-18'='',acc_policy_next_update,'2012-12-18')
WHERE acc_id = '1'
is equivalent to the first UPDATE statement in the question, in that it sets the value of all four columns to the new specified value.
This statement:
UPDATE test_accs
SET acc_owner = IF(''='',acc_owner,'')
, acc_policy_version = IF('1.2'='',acc_policy_version,'1.2')
, acc_policy_last_update = IF(''='',acc_policy_last_update,'')
, acc_policy_next_update = IF(''='',acc_policy_next_update,'')
WHERE acc_id = '1'
changes ONLY the value of the acc_policy_version column, the values of the other three columns will remain unchanged.
This is not necessarily the best approach, but it is workable for some scenarios.
It's also possible to create an expression that requires each supplied value be specified in the statement one time, although I think these expressions are a little less intuitive:
SET acc_owner = COALESCE(NULLIF( '' ,''),acc_owner )
, acc_policy_version = COALESCE(NULLIF( '1.2' ,''),acc_policy_version)
That's essentially doing the same thing as the examples above.
If the supplied value is equal to '' (like it is for acc_owner in the example above), then the NULLIF expression will return a NULL. The COALESCE function essentially causes that NULL value to be skipped, and the current value of the column will remain unchanged (the current value of the column is assigned to the column.)
If the supplied value is not equal to '' (like it is for acc_policy_version in the example above), then the NULLIF expression will return the supplied value. The COALESCE function will pick up that value, and assign it to the column.
Check if acc_owner is empty and set it to zero is one option, you can't insert empty space if column is supposed to hold integer - or just don't do update unless you have int value
1:
if(strlen($acc_owner)==0){
$acc_owner=0;
}
2:
if(is_int($acc_owner)){
//update it
}
Is the value for the Integer field required? If not, then check for the GET/POST value being set, and if its empty, don't include that in your update statement.
if(isset($_GET['acc_id'])) {
$acc_id = $_GET['acc_id'];
$sql = "UPDATE test_accs SET ";
if(isset($_GET['version'])) {
$version = $_GET['version'];
$sql = $sql . "acc_policy_version = " . $version . ",";
}
if(isset($_GET['owner_id'])) {
$owner_id = $_GET['owner_id'];
$sql = $sql . "acc_owner = " . $owner_id . ",";
}
$sql = $sql .
"acc_policy_last_update = '$approved',
acc_policy_next_update = '$renewed'
WHERE acc_id = " . $acc_id;
//Execute SQL
echo "successfully updated " . $acc_id;
} else {
echo "invalid acc_id";
}
1 - Convert your $owner_id to type int
$owner_id = (int)$owner_id;
2 - Use a condition to update this field only if a value > 0
$sql = "UPDATE test_accs SET " .
($owner_id > 0 ? "acc_owner = '$owner_id', " : "") .
"acc_policy_version = '$version', " .
"acc_policy_last_update = '$approved', " .
"acc_policy_next_update = '$renewed' " .
"WHERE acc_id = '1'";
Note : Be carrefull, your variables seems not correctly securised and you have risks of mysql injections. See http://php.net/manual/fr/mysqli.real-escape-string.php.
And, maybe you should think about use the PDO php extension (http://fr2.php.net/manual/en/intro.pdo.php) for you mysql developpement or any orm ?
You should verify all values that came from a html form. Than, if you mysql field can be NULL, just set NULL to php var:
if (strlen($owner_id) == 0) {
$owner_id = NULL;
// OR
$owner_id = 0;
} else {
$owner_id = addslashes($owner_id);
}
$sql = "UPDATE test_accs SET
acc_owner = '$owner_id',
acc_policy_version = '$version',
acc_policy_last_update = '$approved',
acc_policy_next_update = '$renewed'
WHERE acc_id = '1'";
You can initialize variables holding values for optional fields with default values according to their respective data types.
Please refer the code snippet mentioned below.
$owner_id=0;
$version=0;
$approved='';
$renewed='';
if($_SERVER['REQUEST_METHOD']=='POST')
{
extract($_POST);
}
$sql = "UPDATE test_accs SET
acc_owner = '$owner_id',
acc_policy_version = '$version',
acc_policy_last_update = '$approved',
acc_policy_next_update = '$renewed'
WHERE acc_id = '1'";

Categories