SQL PHP UPDATE query using an array - php

I am trying to update an MS Access table using an array here is my code
for($i = 1; $i<=$rows; $i++)
{
$seedsize[$i] = $_POST['packageType'.$i];
$RefNo[$i] = $_POST['field'.$i];
(int)$qtyOrder[$i] = $_POST['ordered'.$i];
(int)$qtyDel[$i] = $_POST['delivered'.$i];
$unitPrice[$i] = $_POST['unitPriceDtl'.$i];
$ref2[$i] = $_POST['grade'.$i];
//$date[$i] = $_POST['myDate'.$i];
}
$InvoiceID = $_SESSION['InvoiceID'];
$sql = "UPDATE
[Tbl_Invoice_Details]
SET
[Seed Size]=?,
[RefNo]=?,
[Quantity Ordered]=?,
[Quantity Delivered]=?, [Ref2]=?,
[PricePerUnit]=?
WHERE
[Invoice_ID]=?";
$data = $conn2->prepare($sql);
for($x = 1; $x <= 4; $x++)
{
$data->execute(array($seedsize[$x], $RefNo[$x], $qtyOrder[$x], $qtyDel[$x], $unitPrice[$x], $ref2[$x], $InvoiceID));
echo $RefNo[$x]."<br/>";
}
I am getting this error "Invalid character value for cast specification: -3030 [Microsoft][ODBC Microsoft Access Driver] Data type mismatch in criteria expression."
Thank you for your help!

Have you confirmed that there isn't any null values in the data? Null values might be causing the cast error.
I would suggest to cast all numeric values:
for($i = 1; $i<=$rows; $i++)
{
$seedsize[$i] = $_POST['packageType' . $i]; // Not sure about this one
$RefNo[$i] = (int)$_POST['field' . $i];
$qtyOrder[$i] = (int)$_POST['ordered' . $i];
$qtyDel[$i] = (int)$_POST['delivered' . $i];
$unitPrice[$i] = (float)$_POST['unitPriceDtl' . $i];
$ref2[$i] = $_POST['grade' . $i]; // Not sure about this one
//$date[$i] = $_POST['myDate' .$i];
}
Please note that the cast should be on the right side of the assignment operator.

Why is 4 hard coded in the 2nd for loop? Just curious.
What I think is the issue is(int)$qtyOrder[$i] or (int)$qtyDel[$i] or really anything else. The error is saying the data it expected to get is not what it got, so somewhere you sent ABC when it wanted only 123 (Numbers) for example. You should do any processing on the POST'ed information, maybe somting like:
$qtyOrder[$i] = intval($_POST['ordered'.$i]);
$qtyDel[$i] = intval($_POST['delivered'.$i]);
I've never done what your doing percisly but I think this will send you on the right track. Here is the PHP manual page I looked at.

Related

PHP Explode array using integer field

I searched, but I couldn't find an answer anywhere here. I have a multiselect box that will take each selection and explode it into individual data entries into a MySQL DB. Here is the code
$arr = explode(",",$values["account_id"]);
$j = count($arr);
for($i = 0; $i < $j ; $i++)
{
$strInsert = "update accounts_data set balance=balance+".$values["debit"]." where id='".$arr[$i]."'";
DB::Query($strInsert);
}
The field account_id is an integer field, but if I have more than 2 items selected, the code breaks. If account_id is set to a VARCHAR, I can select everything and it works just as I need it to updating every account balance with the new debit. I'm not quite sure why it works for a VARCHAR and not an INT, and I can't quite figure out how to make it work after a month of trial and error. I was wondering if anyone had an idea that is smarter than I am.
not sure I understood about your explanation about varchar and int.
Here is a way I would do it:
$values["account_id"] = "30,56,78";
$values["debit"] = 100;
foreach(explode(",", $values["account_id"]) as $account)
{
$strInsert = "update accounts_data set balance=balance+" . $values["debit"] ." where id=" . $account;
echo $strInsert . PHP_EOL;
// DB::Query($strInsert);
}
Hope this helps something.

How to += string with sql query using php?

Uncaught mysqli_sql_exception: Truncated incorrect DOUBLE value: '0-' in ... Stack trace: #0 ...(68): mysqli->query('UPDATE `Results...') #1 {main} thrown in ... on line 68
That's the error I am getting with the ellipses representing the file pathway.
The php I have:
for($i = 1; $i < $maxQuestions; $i++){
$answer = $_POST["question$i"] == "Yes" ? "1-" : "0-";
$connection->query("UPDATE `Results`
SET `question$i` = `question$i` + '$answer'
WHERE `ID` = '$id'");
}
The problem is with the SET `question$i` = `question$i` + '$answer' as I am trying to basically keep a history of the question's answers. For example, I may want the stored data to go from "0-" to "0-1-". How do you += a string with php/sql?
EDIT:
I have tried SET `question$i` = concat(`question$i` + '$answer') and I am getting the same error.
I changed it to
for($i = 1; $i < $maxQuestions; $i++){
$answer = $_POST["question$i"] == "yes" ? "1-" : "0-";
$qColumn = "question" . strval($i);
$questionData = $data["question$i"] . $answer;
$connection->query("UPDATE `Results`
SET `$qColumn` = '$questionData'
WHERE `ID` = '$id'");
}
This worked, but I'm still not sure why my initial code did not work. If someone could post a better answer/solution and why my initial code didn't work, please do. Thanks!
In mysql You can do it dierctly using concat this way
SET `question$i` =concat(`question$i`, '$answer')
You should not have column names ending with numbers because this is an indicator that your schema is not correct. You should normalise the database and have questions as a separate tables joined to your results table. Your results should not be concatenated into a single column either. Have a separate row for each result.
However, if you want to achieve this with your current set-up you could use CONCAT(). The query should look similar to this:
$types = '';
$setString = [];
$values = [];
for($i = 1; $i < $maxQuestions; $i++){
// concat types
$types .= 's';
// gather values
$values[] = isset($_POST["question$i"]) ? "1-" : "0-";
// build SET statement
$columnName = "question" . $i;
$setString[] = $columnName.' = CONCAT('.$columnName.', ?)';
}
$sql = "UPDATE Results SET ".implode(', ', $setString).' WHERE ID = ?';
$stmt = $connection->prepare($sql);
$stmt->bind_param($types, ...$values);
$stmt->execute();

Code creates two MySQL rows instead of one

I´m trying to create just one new row in a MySQL table
The problem is that I´m getting two new rows in my database.
I really can´t see why this is happening. The debug_to_console( "makepass" ); - my debug function - only gets executed once? AND the two rows it creates is not identical/copies
debug_to_console( "makepass" );
$salt = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
$len = strlen($salt);
$makepassJBH = '';
for ($i = 57; $i < $len; $i ++) {
$makepassJBH .= $salt[mt_rand(0, $len -1)];
}
$newpassJBH = password_hash($makepassJBH, PASSWORD_BCRYPT );
$licensidentifierJBH = '';
for ($i = 57; $i < $len; $i ++) {
$licensidentifierJBH .= $salt[mt_rand(0, $len -1)];
}
$fullkey = $makepassJBH . $licensidentifierJBH;
try {
// Get a db connection.
$db = JFactory::getDbo();
// Create a new query object.
$query = $db->getQuery(true);
// Insert columns.
$columns = array('licenskey','licenskey_Identifier','dateCreated', 'printed');
// Insert values.
$values = array($db->quote($newpassJBH), $db->quote($licensidentifierJBH), $db->quote(date("Y-m-d")), $db->quote(0));
// Prepare the insert query.
$query
->insert($db->quoteName('#__licenskey'))
->columns($db->quoteName($columns))
->values(implode(',', $values));
$query .= ' ON DUPLICATE KEY UPDATE ' . $db->quoteName('licenskey_Identifier') . ' = VALUES(' . $db->quoteName('licenskey_Identifier') . ')';
// Set the query using our newly populated query object and execute it.
$db->setQuery($query);
echo $db->replacePrefix((string) $query);
$db->execute();
}
The SQL dump:
INSERT INTO `mdh_licenskey` (`licenskey`,`licenskey_Identifier`,`dateCreated`,`printed`) VALUES ('$2y$10$jXkjJX1OZ7Vu0okV/QlxcehF5T2SSPZFhVHIx.E64HhidgYY.3URS','juLEo','2018-07-23','0') ON DUPLICATE KEY UPDATE `licenskey_Identifier` = VALUES(`licenskey_Identifier`)
Since the license key is generated by the PHP code above, that code must be executed twice. This can happen for multiple reasons but it can be difficult for us to guess exactly why. Either check if your browser is calling it twice, or if it is called twice from within the PHP code.
Make sure your script isn't executed twice. I had this issue when using firebug for example. This plugin made my page execute twice but not outputting to the console.
Sort of like a "prefetch" of the page before showing, don't know for sure.
Maybe add a 'debug to console' point on every line, like 'here 1, here 2'..

I need to have a variable IN my variable name, not AS my variable name

How would I do that?
According to PHP.net,
$a = "hi";
$hi = 2;
$$a; // returns 2
However, I need:
$i = 2;
$_POST['link$i']; // I need this to return the same thing as $_POST['link2']
Here is how I have my code.
for ($i = 1; $i <= 40; $i++)
{
if(!empty($link$i))
{
$link$i = mysql_real_escape_string($_POST['link$i']);
mysql_query("
INSERT INTO links (link, rimageid) VALUES
('".$link$i."', '".$id."') ");
} else { }
}
The reason I'm doing this is because I have a lot of text input fields posting their values to this file, and I'd like to define and insert each of their values via a for loop instead of manually inserting each single link into mysql.
Right now, I get:
Parse error: syntax error, unexpected T_VARIABLE, expecting ')' in C:\xampp\htdocs\new2.php on line 22
How would I go about doing this?
Thanks!
For array index concatenation, ok, but this code
for ($i = 1; $i <= 40; $i++)
{
if(!empty($link$i))
{
$link$i = mysql_real_escape_string($_POST['link$i']);
mysql_query("
INSERT INTO links (link, rimageid) VALUES
('".$link$i."', '".$id."') ");
} else { }
}
won't work as you expect, i.e. name a variable like the result it's not necessary, why would you want to do that? PHP doesn't care about the variable name and if it's coordinated with the result.
Just do:
for ($i = 1; $i <= 40; $i++)
{
if(!empty($_POST['link'.$i]))
{
$regular_variable_name = mysql_real_escape_string($_POST['link'.$i]);
mysql_query("INSERT INTO links (link, rimageid) VALUES ('".$regular_variable_name."', '".$id."') ");
} else { }
}
How about string concatenation?
$_POST['link'.$i];
You are receiving a syntax error because $link$i is not valid.
if you want the end value to be link2 then you need a solution like Nick Shepherd suggested.
It could be easier to see what is going on if you create the string that you want for the key first.
$key = 'link' . $i;
After that you can use the key whenever you want, in a conditional like
if (!empty($_POST[$key])) {
and again in your mysql_escape
mysql_real_escape_string($_POST[$key]);
$_POST['link' . $i];
This should solve your problem. For indexes of an array you can simply concatenate the string for the index that you are trying to resolve.
yep... you can do the following
$ = 2;
$link = "link" . $i;
if(isset($_POST[$link])){
//do something
}
or
$_POST[$link.$i]
the same goes for methods
$type = "Something";
$method = "get" . $type;
$this->$method(); //calls method -> getSomething()

Script to match names submitted via a form with MySQL database breaks when name contains apostrophe

I have script that enters names into a MySQL database, using mysql_real_escape_string so that apostrophes are handled correctly. The trouble I am experiencing is with the script below that checks to see if names entered using another form correspond to names already in my database and if names are found updates the row.
When I try to enter a name with an apostrophe into the form processed by this script, I get an error message stating that the name wasn't found, and the name in the error message contains a backslash before the apostrophe, which is obviously the issue.
So the question is, how can I amend the script below so that it will work with names with apostrophes?
Thanks,
Nick
$row_count = count($_POST['name']);
if ($row_count > 0) {
mysql_select_db($database, $connection);
$name = array();
$workshop = array();
$not_found = array();
for($i = 0; $i < $row_count; $i++) {
// variable sanitation...
$name[$i] = mysql_real_escape_string(ucwords($_POST['name'][$i]));
$workshop[$i] = mysql_real_escape_string($_POST['workshop'][$i]);
}
$names = "('".implode("','",$name)."')";
$not_in = Array();
// lets say all names doesn't exist in `conference`
foreach($name as $value) {
// names in array are keys, not values
$not_in[$value] = true;
}
$query = mysql_query("SELECT Name FROM conference WHERE Name IN $names");
while(list($dbname) = #mysql_fetch_row($query)) {
// delete those name from $not_in who exists
unset($not_in[$dbname]);
}
// names in $not_in array are keys, not values
$not_in = array_keys($not_in);
if(empty($not_in)) {
// its ok, all names have been found. do the magic.
for($i = 0; $i < $row_count; $i++) {
$sql = "UPDATE conference SET Workshop = '$workshop[$i]' WHERE Name LIKE '$name[$i]'";
mysql_query($sql);
$body .= "Name: " . $name[$i] . " Workshop: " . $workshop[$i] . "\n\n";
}
Hmmm! I think I might have found the issue. The problem might not be with the query but with the PHP code. I'll try to explain below using your example John O'Shea.
for($i = 0; $i < $row_count; $i++) {
// variable sanitation...
$name[$i] = mysql_real_escape_string(ucwords($_POST['name'][$i]));
$workshop[$i] = mysql_real_escape_string($_POST['workshop'][$i]);
}
$names = "('".implode("','",$name)."')";
$not_in = Array();
// lets say all names doesn't exist in `conference`
foreach($name as $value) {
// names in array are keys, not values
$not_in[$value] = true;
}
After the above code, Array $not_in will contain escaped keys because $name already contains values escaped using mysql_real_escape_string(). Hence, for example:
$not_in[John] = true;
$not_in[John O\'Shea] = true;
$query = mysql_query("SELECT Name FROM conference WHERE Name IN $names");
while(list($dbname) = #mysql_fetch_row($query)) {
// delete those name from $not_in who exists
unset($not_in[$dbname]);
}
Now $dbname in the above code contains unescaped values retrieved from the DB, for example John O'Shea without the backslashes. Since this is not what $not_in contains, the unset() will not work. This means that all apostrophe values remain in the $not_in array.
So the fix is to keep unescaped values in $not_in.
Hope this makes sense!
========== EDIT: In response to how to keep unescaped values in $not_in:
The idea is to do escaping just where it is needed. Here are the changes that you may do to your code:
Rewrite the first for() as below:
for($i = 0; $i < $row_count; $i++) {
// variable sanitation...
//$name[$i] = mysql_real_escape_string(ucwords($_POST['name'][$i]));
$name[$i] = ucwords($_POST['name'][$i]);
$workshop[$i] = mysql_real_escape_string($_POST['workshop'][$i]);
}
$names = "('" . mysql_real_escape_string(implode("','",$name)) . "')";
And rewrite the UPDATE statement as:
$sql = "UPDATE conference SET Workshop = '$workshop[$i]' WHERE Name LIKE '" . mysql_real_escape_string($name[$i]) . "'";
By the way, According to your code, the UPDATE will not run if there is one name that does not exist in the database. Is it absolutely necessary to run the UPDATE only if all the $_POST['name'] are found in the database? If not, you can significantly reduce the amount of code.
I haven't tested the above changes but I think they should work. Let me know if you get any issues.
========== EDIT 2: Code snippet for updating records that exist and generating errors for records that did not
Hey Nick, I think only writing the below code should do the trick:
$row_count = count($_POST['name']);
if ($row_count > 0) {
mysql_select_db($database, $connection);
for ($i = 0; $i < $row_count; $i++) {
mysql_query("UPDATE conference SET Workshop = '" . mysql_real_escape_string($_POST['workshop'][$i]) . "' WHERE Name LIKE '" . mysql_real_escape_string($_POST['name'][$i]) . "'");
$affectedRows = mysql_affected_rows();
if ($affectedRows == 0) {
echo '<br>Name did not exist - ' . $_POST['name'][$i];
}
}
}
Hope this helps!

Categories