I'm exploding a comma separated list into a variable named $tagArray and trying to write those values into incrementing rows of a table.
The code below works in so much as it creates the appropriate number of rows in my table but it only writes the first letter of the comma separating string (ie. if the string reads as "one, two, three", "o" is written in the first row and the remaining two rows have a blank value for column "blog_tag":
$tagInput = $_POST["blog_tags"];
$tagArray = explode(",",$tagInput);
$sql_2 = "INSERT INTO blog_tags (blog_tag, blog_id)
VALUES ";
$valuesArray = array();
foreach($tagArray as $row){
$tag = mysqli_real_escape_string($conxn, $row['blog_tag']);
$valuesArray[] = "('$tag','$lastID')";
}
$sql_2 .= implode(',', $valuesArray);
if (!mysqli_query($conxn,$sql_2)) {
die('Error: ' . mysqli_error($conxn));
}
This is spaghetti pieced together from various searches here and it's getting close but I can't figure out where it's grabbing just that first letter of the string.
Explode doesn't create associative arrays
$tag = mysqli_real_escape_string($conxn, $row); //instead of $row['blog_tag']
just replace your foreach with this for inserting values of array
foreach($tagArray as $row){
$a=mysqli_real_escape_string($row)
$sql_2 = "INSERT INTO blog_tags (blog_tag, blog_id) VALUES
('$a','$lastID') ";
}
Related
$stuffname=$_GET['stuffname'];
$pieces = explode(" ", $stuffname);
$pieces can have any number of words in it.
I want to loop this query so that each word is added from pieces as a separate entry into the table keywords
$query=$con->prepare("INSERT INTO keywords (stuffname) VALUES (?)");
$query->execute([$pieces]);
Thanks for your time
It's unclear if you've tried anything or where you got stuck, but this should be very simple with a loop.
Either
execute a separate INSERT for each new row
$query = $con->prepare("INSERT INTO keywords (stuffname) VALUES (?)");
foreach ($pieces as $piece)
$query->execute([$piece]);{
}
or
Try to build a single INSERT with multiple sets of values:
$sql = "INSERT INTO keywords (stuffname) VALUES ";
$vals = "";
foreach ($pieces as $piece)
{
$vals .= ($vals != "" ? "," : "")."(?)";
}
$query = $con->prepare($sql.$vals);
$query->execute([$pieces]);
In a form, multiple Checkbox values to be inserted into database:
My Code:
Array: ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 )
$a = $_POST['id']; // data from form
$query = "INSERT INTO abc(`x`,`y`,`z`) VALUES " . implode (",","(NULL,$a,'1')");
mysqli_query($dbc,$query);
There seems to be a problem with implode function. How do you concat array using implode?
// Expected output
INSERT INTO abc(`x`,`y`,`z`) VALUES (NULL,1,'1'),(NULL,2,'1'),(NULL,3,'1'),(NULL,4,'1'),
Column y of table abc needs to loop with $a.
If you want to create a batch multiple insertions, first build the batches first, then implode those batches:
$multiple = array_map(function($e) use($dbc) {
$e = $dbc->real_escape_string($e);
return "(NULL, $e, '1')";
}, $a);
$query = "INSERT INTO abc(`x`,`y`,`z`) VALUES " . implode (',', $multiple);
mysqli_query($dbc,$query);
Sidenotes: Its not VALUE, Its VALUES. And remember to use the correct quotes on identifiers. Its supposed to be backticks not single quotes.
INSERT INTO abc('x','y','z') // NOT OK
INSERT INTO abc(`x`,`y`,`z`) // OK
Here you do implode concate.
$query = "INSERT INTO abc('x','y','z') VALUE " . "('" . implode("','", $a) . "')";
Youre using wrong arguments in implode implode() and check your insert query you must use values instead of value
$query = "INSERT INTO abc('x','y','z') VALUES (".implode(",",$a).")";
$a = array(1,2,3,4);
$string = '';
foreach($a as $v){
$string .= "(NULL, $v, 1),";
}
$string = substr($string,0,-1);
$query = "INSERT INTO abc('x','y','z') VALUES $string";
As per your comments in question, This should be your code:
foreach($a as $item)
{
$str[] = "(NULL, '$item', 1)";
}
$query = "INSERT INTO abc(x,y,z) VALUES ".implode(',', $str);
So, you were doing two mistakes:
VALUE should be VALUES
Using implode at wrong place
I have a column in a table of a MySQL database that stores numbers separated by commas. Here's an example:
,,322,,,,455,,,,698,,,,722,
There is a specific pattern:
The first number always has two commas before it
The numbers in between the first and last are separated by 4 commas
The last number is followed by a single comma
The numbers are ALWAYS separated by commas
I'm having some difficulty maintaining this pattern.. sometimes this field updates incorrectly resulting in too many or too few commas in certain places like so:
,,166,,,,845,,,,,,,,846,
I use this PHP to add/remove commas:
public function serializeArray($array) {
$string = ',';
foreach ($array as $obj) {
$string .= ',' . $obj . ',';
}
return $string;
}
public function unserializeArray($string) {
$array = explode(",,",$string);
unset($array[0]);
$array = array_values($array);
return $array;
echo "Array: " . print_r($array);
}
SQL to update column:
$query = $this->pdo->prepare(
'UPDATE `' . $this->table . '` SET
`team_ids` = :team_ids
WHERE `id` = :customer_id LIMIT 1;');
$query->bindParam(':customer_id', $customer_id, PDO::PARAM_INT);
$query->bindParam(':team_ids', $team_ids);
$query->execute();
What SQL can I use to UPDATE all of the values in the column to follow the specific pattern requirements mentioned above?
The issue here looks like you're missing a number, not that it is not following your pattern.
,,166,,,,845,,,,Missing No,,,,846,
Are you sure you want to delete this? I would instead focus on catching the null or blank number.
If so, it looks like you should be able to do a replace
Update TableName
Set NumberPattern = Replace(NumberPattern, ',,,,,,,,', ',,,,') --Repalce 8 ',' with 4 ','
What I am doing is adding values to a mysql table with each value seperated by a comma. And each new value is appended to that last value once again seperated by a comma. Now this is all dynamic. What I am having an issue is on how to remove a selected value and the comma. I am using php and mysql.
I can read the values out with explode and line[value].
table name is values
table consist of id, value, value_array
$value_selected would be a $_GET['value']
value_array is the column that contains all the values seperated by comma.
The database selects from values where the id is equal to the Get value.
Then returns all values in the value_array
I then explode the values and have each value from the value_array read through the for loop and line[value].
the code:
start php
$value_selected = $_GET['value'];
$query = mysql_query("SELECT * FROM values WHERE id='$value_selected'");
while($result = mysql_fetch_assoc($query))
{
$check_values = $result['value_array'];
}
$values = explode(",",$check_values);
$count_values = count($values);
for($counter = 0; $counter < $count_values; $counter++)
{
$line = each($values);
$query = mysql_query("SELECT * FROM values WHERE id='$line[value]'");
while($result = mysql_fetch_assoc($query))
{
echo $result['value'].'<br/>';
}
}
php end
I don't have an issue reading it out. What I'm trying to do is being able to select a value via GET and remove that value from the value_array while also removing the trailing comma. I hope I was able to expalin in more detail my issue.
Use a foreach loop, take the exploded string and reassemble it minus the string $value_selected by doing this:
$NewValue = '';
$i = 1;
foreach ($values as $Value) {
if ($i > $count_values) {
break;
} else {
if ($Value !== $value_selected) {//reassemble comma-sep string - $_GET['value']
$NewValue = $NewValue . $Value . ",";
}
}
$i++;
}
Now $NewValue no longer contains $_GET['value'], because the concatenation in the if statement only occurs when the exploded fragment $Value does not match $_GET['value']. Update the database or echo $NewValue, etc. as necessary at this point.
I have a problem where I get an array of words and I have to insert every one of them in DB via a foreach, but the whole thing is running too slow.
foreach($words as $word) {
// even more checks
if(strlen($word) < 3) continue;
$word = $this->db->escapeString(strtolower($word));
// word not found?
$result = $this->db->querySingle("SELECT id FROM words WHERE word = '{$word}'");
if(!$result) {
$this->db->exec("INSERT INTO words (word) VALUES ('{$word}')");
$this->db->exec("INSERT INTO search (reply, word) VALUES ('{$id}', '{$this->db->lastInsertRowID()}')");
// word found
} else $this->db->exec("INSERT INTO search (reply, word) VALUES ('{$id}', '{$result}')");
}
Basically lets say $words = array('hello', 'kitten');
Within that foreach, it will take my first word (hello) and check if it exists in the words table. If it cannot find the word, it will then insert it there and also insert it into another table with a variable $id that will not change within the foreach. If however it found the word it will insert it directly in the 2nd table. After that it will take the 2nd word (kitten) and do the same thing.
Using php5 with sqlite3
$this->db = new \SQLite3(ROOT . DS . 'db' . DS . 'app.db');
The tables in question are very light
CREATE TABLE words (id INTEGER PRIMARY KEY AUTOINCREMENT, word TEXT);
CREATE TABLE search (reply INTEGER, word INTEGER);
CREATE INDEX search_reply_idx ON search (reply);
CREATE INDEX search_word_idx ON search (word);
This works fine most of the time for 10-15 words, but if i have over 150 words it will be as slow as 8 seconds. Can i combine the queries into just one? Am i missing something?
Thanks.
This method is based on the premise that SQLite support this syntax for insertion (this syntax works in MySQL):
INSERT INTO table (column) VALUES ('value1'), ('value2'), ('value3'), ('valueN');
What you can do is use PHP to build the SQL insert string using logic from the SELECT statement, and then at the end perform two queries; One on the words table and one on the search table:
$sql_words = 'INSERT INTO words (word) VALUES ';
$sql_search = 'INSERT INTO search (reply, word) VALUES ';
$count = count($words);
$i = 0;
$last_insert_id = '';
$delim = '';
foreach ($words as $word)
{
$result = $this->db->querySingle("SELECT id FROM words WHERE word = '{$word}'");
if ($i < $count) {
$delim = ', ';
} else {
$delim = '';
}
if ($result) {
$sql_search .= "('{$result}','{$word}')".$delim;
} else {
$sql_words .= "('{$word}')".$delim;
$sql_search .= "('{$result}','{$last_insert_id}')".$delim;
}
$last_insert_id = $result;
$i++;
}
$this->db-exec($sql_words);
$this->db->exec($sql_search);
As for the validity of this code I am unsure, I was a bit confused where $id came from, and assumed it was the same as $result.
So in order to achieve blazing fast performance some things had to be changed.
Firstly, the use of transactions (sort of like mulquin's answer) and secondly I've added a unique index for the column word in the words table. This will help me skip the sql that checked if a word already existed and just ignore the insert statements from that transaction.
This is the new table which will create my unique index automatically
CREATE TABLE words (id INTEGER PRIMARY KEY AUTOINCREMENT, word TEXT UNIQUE)
And here is the modified foreach
$t1 = $t2 = null;
foreach($words as $word) {
// even more checks
if(strlen($word) < 3) continue;
$word = $this->db->escapeString(strtolower($word));
$t1 .= "INSERT OR IGNORE INTO words (word) VALUES ('{$word}');";
$t2 .= "INSERT INTO search (reply, word) SELECT '{$id}', id FROM words WHERE word = '{$word}';";
}
// run transactions
if(!is_null($t1)) $this->db->exec("BEGIN TRANSACTION;" . $t1 . "COMMIT;");
if(!is_null($t2)) $this->db->exec("BEGIN TRANSACTION;" . $t2 . "COMMIT;");
So, when in doubt, use transactions :)