Change Static SQL update to dynamic based on changing column names - php

Ok, I asked a question last night and received a number of really great responses. Since that was my first time using StackOverflow I was really pleased.
I'm hoping you guys can help with a new one. Hopefully, down the road, I'll be able to repay the favor to some NEW newbies.
I have the following code in a php file:
$sql = "";
$now=date("Y-m-d h:i:s");
$updatedRecords = $json1->{'updatedRecords'};
foreach ($updatedRecords as $value){
$sql = "update `acea` set ".
"`ACEA_A1`='".$value->ACEA_A1 . "', ".
"`ACEA_A2`='".$value->ACEA_A2 . "', ".
"`ACEA_A3`='".$value->ACEA_A3 . "', ".
"`ACEA_A4`='".$value->ACEA_A4 . "', ".
"`ACEA_A5`='".$value->ACEA_A5 . "', ".
"`ACEA_B1`='".$value->ACEA_B1 . "', ".
"`ACEA_B2`='".$value->ACEA_B2 . "', ".
"`ACEA_B3`='".$value->ACEA_B3 . "', ".
"`ACEA_B4`='".$value->ACEA_B4 . "', ".
"`ACEA_B5`='".$value->ACEA_B5 . "', ".
"`ACEA_E1`='".$value->ACEA_E1 . "', ".
"`ACEA_E2`='".$value->ACEA_E2 . "', ".
"`ACEA_E3`='".$value->ACEA_E3 . "', ".
"`ACEA_E4`='".$value->ACEA_E4 . "', ".
"`ACEA_E5`='".$value->ACEA_E5 . "', ".
"`ACEA_E7`='".$value->ACEA_E7 . "' ".
"where `acea_id`=".$value->acea_id;
if(mysql_query($sql)==FALSE){
$errors .= mysql_error();
}
}
The "ACEA_XX" portions relate to columns in the "acea" database table (obviously), but the programmer set them statically. Unfortunately, these columns need to be added to periodically, with new columns being created related to the new ACEA specs that are introduced.
As a result, this code becomes outdated.
Without having to go in and update this code each time I add a new column, how can I redesign this code so that it updates itself dynamically to include the new columns? I've been trying all morning to make it work, and I can set it so that I can dynamically insert the actual column names into the update statement, but, I can't seem to dynamically grab the associated values dynamically (and I think my method for grabbing and inserting the column names is a little convoluted).
My actual database table columns are currently:
acea_id ACEA_A1 ACEA_A2 ACEA_A3 ACEA_A4 ACEA_A5 ACEA_B1 ACEA_B2 ACEA_B3 ACEA_B4 ACEA_B5 ACEA_E1 ACEA_E2 ACEA_E3 ACEA_E4 ACEA_E5 ACEA_E6 ACEA_E7 ACEA_E9 oil_data_id
The first and last columns will never change and will continue to be the first and last columns. Any new columns will be added somewhere in between, but not necessarily immediately preceding the "oil_data_id" column.
I've tried revising the code numerous ways in order to properly grab the values, but just can't make it work.
Anyone have a concise modification to the code to do what I want? It would be greatly appreciated.

Seems like Doug Kress' method spits some errors out so here is my shot:
$errors = array();
foreach($json1->updatedRecords as $record)
{
$fields = array();
foreach($record as $field => $value)
{
if(substr($field, 0, 5) === 'ACEA_')
{
$fields[] = $field.' = '.mysql_real_escape_string($value);
}
}
// Check if there are any fields set to be updated.
if(isset($fields[0]))
{
// I'm assuming $record->acea_id is an integer. If not,
// replace '%d' with '%s'.
$sql = "UPDATE `acea` SET %s WHERE `acea_id` = '%d';";
$sql = sprintf($sql, implode(',', $fields), $record->acea_id);
if(mysql_query($sql) === false)
{
$errors[] = mysql_error();
}
}
}

First, I would highly recommend making that into a separate table (turning the data 'sideways', if you will). Assuming that's not feasible:
$sql = "";
$updatedRecords = $json1->{'updatedRecords'};
foreach ($updatedRecords as $values){
$flist = array();
$params = array();
foreach ($values as $key => $value) {
if (preg_match('/^ACEA_[A-Z]+\d+$/', $key)) {
$flist[] = $key .'="%s"';
$params[] = mysql_real_escape_string($value);
}
}
$sql = "update `acea` set ". implode(', ', $flist) .
"WHERE `acea_id`='%s'";
$params[] = mysql_real_escape_string($value->acea_id);
$sql = sprintf($sql, $params);
if(mysql_query($sql)==FALSE){
$errors .= mysql_error();
}
}

Related

PHP Simple HTML DOM Parser array to database

So the problem is, when uploading to mysql the database is only uploading the last value in the array.
if (substr($avsnitt["serier"], 0, 16) === 'http://random'){
// Create DOM from URL or file
$html = file_get_html($avsnitt["serier"]);
$array_title = array();
$array_link = array();
foreach($html->find('div[class=entry]') as $element){
foreach ($element->find('a') as $text) {
$array_title[] = $text->plaintext;
}
foreach ($element->find('a') as $test) {
$array_link[] = $test->href;
}
$count_name = count($array_title);
for($i=0; $i<$count_name; $i++){
$_array_title = mysql_escape_string($array_title[$i]);
$_array_link = mysql_escape_string($array_link [$i]);
print_r($_array_title);
print_r($_array_link);
$sql2 = "INSERT INTO episodes (name, ID, link) VALUES ('" . #$_array_title. "','" . #$avsnitt["ID"] . "', '" . #$_array_link . "');";
mysqli_query($CON, $sql2);
}
}
}
i'm new to php mysql so i dont relly know how arrays is uploaded to mysql, fast answers will be appreciated thanks.
I think, your database-field "link" is type string.
You want to insert your variable $_array_link, witch is type array.
So try serialize($_array_link) to "convert" array to string.
I think, the # are not nessessary, without it is better to read.
$sql2 = "INSERT INTO episodes (name, ID, link)
VALUES ('" . #$_array_title. "','" . #$avsnitt["ID"] . "', '" . serialize($_array_link). "');";
Later, you want to use the variable from the database. So after you SELECT your data, use unserialize() to get the array back.
problem was the database ID was primery key only allowing one withe a specific ID

Create a Dynamic insert statement - PHP - Mysql

I have a form which has multiple drop downs (16) speed[] and some other fields
The data from the dropdown boxes has to be inserted into a Mysql table
What I did is I took the count count($_POST["speed"]);and then loop through until the end of the speed array.
The problem is:
If Anyone of the dropdown is not selected it returns "-1", if used `($_POST["speed"][$i]!="-1")for that but it does not compare and goes into the IF loop
The Insert Query is not a valid not sure how to append the extra commas
$sql when printed
INSERT INTO mytablename (w_name,wtype,speed1,speed2, speed3, speed4, speed5, speed6, speed7, speed8, speed9, speed10, speed11, speed12, speed13, speed14, speed15, speed16, coach_id) VALUES ('name', '', ''-1''800''-1''-1''200''-1''-1''-1''-1''-1''-1''-1''-1''-1''-1''200'', '208')
My PHP code
$itemCount = count($_POST["speed"]);
$itemValues=0;
$query = "INSERT INTO mytablename (w_name,wtype,speed1,speed2, speed3, speed4, speed5, speed6, speed7, speed8, speed9, speed10, speed11, speed12, speed13, speed14, speed15, speed16, coach_id) VALUES ";
$bldSpltString="";
$queryValue = "";
for($i=0;$i<$itemCount;$i++) {
if(($_POST["speed"][$i]!="-1") || !empty($_POST["speed"][$i])) {
$bldSpltString .= "'" . $_POST["speed"][$i] ."'";
}
}
$queryValue .= "('" . $wkout . "', '" . $wtype . "', '" . $bldSpltString . "', '" .$_SESSION['id']."')";
$sql = $query.$queryValue;
echo $sql;
exit;
I would do something like this:
<?php
function dynamicInsert($table_name, $assoc_array){
$keys = array();
$values = array();
foreach($assoc_array as $key => $value){
$keys[] = $key;
$values[] = $value;
}
$query = "INSERT INTO `$table_name`(`".implode("`,`", $keys)."`) VALUES('".implode("','", $values)."')";
echo $query;
}
dynamicInsert("users", array(
"username" => "Test User",
"password" => "Password123"
));
?>
WARNING: This code is not secure, I would run a mysql_real_escape_string and any other necessary sanitation on the variables being sent to mysql. I would also steer clear of allowing this script to run on anything public facing as a dynamic insert could allow for huge security risks!

Handling optional search parameters in a PHP SQL query

I'm querying my SQL database in a PHP file from up to three optional search fields (passed through by jQuery). Any one, two or three of these fields can be used at any time to make the query as expansive or as narrow as the user likes. If nothing is in a search field nothing will be returned.
I've written the code so far to handle very basic one search queries and have just begun to add in the multiple parameters - this is where it's starting to get tricky. I can query two fields together without too much bother but adding a third LOCATION parameter is beginning to take up too much code for all of the querying possibilities a user might make.
Here's how my PHP file is set up for two parameters:
if (!empty($_POST['title']) && (!empty($_POST['name'])))
{
require '../db/connect.php';
$sql = "SELECT
....
FROM
....
WHERE
`table 3`.`TRACKTITLE` = '" . mysql_real_escape_string(trim($_POST['title'])) . "' AND `table 3`.`ARTIST` = '" . mysql_real_escape_string(trim($_POST['name'])) . "'";
}
if (!empty($_POST['name']))
{
require '../db/connect.php';
$sql = "SELECT
...
FROM
...
WHERE
`table 3`.`ARTIST` = '" . mysql_real_escape_string(trim($_POST['name'])) . "'";
}
if (!empty($_POST['title'])) {
require '../db/connect.php';
$sql = "SELECT
...
FROM
...
WHERE
`table 3`.`TRACKTITLE` = '" . mysql_real_escape_string(trim($_POST['title'])) . "'";
}
$result = mysql_query($sql);
$data = array();
while ($array = mysql_fetch_assoc($result)) {
$data[] = $array;
Which is the simplest way to build a query with multiple optional parameters in PHP, accounting for any additional parameters that might be added on at a later date? I've read up on isnull values but do they perform a similar function to !emtpy?
Do something along this line:
$whereclauses = array();
$subsets = false;
// for every field
if(!empty($_POST['name']))
{
$subsets = true;
$whereclauses[] = " artist = ". mysql_real_escape_string(trim($_POST['name']));
}
if($subsets)
{
$whereclauses = implode(", ". $whereclauses);
}
else
{
$whereclauses ="";
}
// now build your query

php, mysql, my memory leaking

I didn't expect this script (throw-away) to be leaking and I haven't figured out what the culprit is. Can you spot anything? Although this is throw-away code, I'm concerned that I'll repeat this in the future. I've never had to manage memory in PHP, but with the number of rows in the db, it's blowing up my php instance (already upped the memory to 1Gb).
The california table is especially larger than the others (currently 2.2m rows, less as I delete duplicate rows). I get a memory error on line 31 ($row = mysql_fetch_assoc($res))
Fatal error: Allowed memory size of 1073741824 bytes exhausted (tried
to allocat e 24 bytes) in C:\Documents and Settings\R\My Documents\My
Webpages\cdiac\cdiac_ dup.php on line 31
PHP 5.3.0, mysql 5.1.36. part of a wamp install.
here's the entire code. the purpose of this script is to delete duplicate entries (data was acquired into segmented tables, which was far faster at the time, but now I have to merge those tables.)
what's causing it? something I'm overlooking? or do I just need to watch the memory size and call garbage collection manually when it gets big?
<?php
define('DBSERVER', 'localhost');
define('DBNAME', '---');
define('DBUSERNAME', '---');
define('DBPASSWORD', '---');
$dblink = mysql_connect(DBSERVER, DBUSERNAME, DBPASSWORD);
mysql_select_db(DBNAME, $dblink);
$state = "AL";
//if (isset($_GET['state'])) $state=mysql_real_escape_string($_GET['state']);
if (isset($argv[1]) ) $state = $argv[1];
echo "Scanning $state\n\n";
// interate through listing of a state to check for duplicate entries (same station_id, year, month, day)
$DBTABLE = "cdiac_data_". $state;
$query = "select * from $DBTABLE ";
$query .= " order by station_id, year, month, day ";
$res = mysql_query($query) or die ("could not run query '$query': " . mysql_errno() . " " . mysql_error());
$last = "";
$prev_row;
$i = 1;
$counter = 0;
echo ".\n";
while ($row = mysql_fetch_assoc($res)) {
$current = $row["station_id"] . "_" . $row["year"] . "_" . sprintf("%02d",$row["month"]) . "_" . sprintf("%02d",$row["day"]);
echo str_repeat(chr(8), 80) . "$i $current ";
if ($last == $current) {
//echo implode(', ', $row) . "\n";
// merge $row and $prev_row
// data_id station_id, state_abbrev, year, month, day, TMIN, TMIN_flags, TMAX, TMAX_flags, PRCP, PRCP_flags, SNOW, SNOW_flags, SNWD, SNWD_flags
printf("%-13s %8s %8s\n", "data_id:", $prev_row["data_id"], $row["data_id"]);
if ($prev_row["data_id"] == $row["data_id"]) echo " + ";
$set = "";
if (!$prev_row["TMIN"] && $row["TMIN"]) $set .= "TMIN = " . $row["TMIN"] . ", ";
if (!$prev_row["TMIN_flags"] && $row["TMIN_flags"]) $set .= "TMIN_flags = '" . $row["TMIN_flags"] . "', ";
if (!$prev_row["TMAX"] && $row["TMAX"]) $set .= "TMAX = " . $row["TMAX"] . ", ";
if (!$prev_row["TMAX_flags"] && $row["TMAX_flags"]) $set .= "TMAX_flags = '" . $row["TMAX_flags"] . "', ";
if (!$prev_row["PRCP"] && $row["PRCP"]) $set .= "PRCP = " . $row["PRCP"] . ", ";
if (!$prev_row["PRCP_flags"] && $row["PRCP_flags"]) $set .= "PRCP_flags = '" . $row["PRCP_flags"] . "', ";
if (!$prev_row["SNOW"] && $row["SNOW"]) $set .= "SNOW = " . $row["SNOW"] . ", ";
if (!$prev_row["SNOW_flags"] && $row["SNOW_flags"]) $set .= "SNOW_flags = '" . $row["SNOW_flags"] . "', ";
if (!$prev_row["SNWD"] && $row["SNWD"]) $set .= "SNWD = " . $row["SNWD"] . ", ";
if (!$prev_row["SNWD_flags"] && $row["SNWD_flags"]) $set .= "SNWD_flags = '" . $row["SNWD_flags"] . "', ";
$delete = "";
$update = "";
if ($set = substr_replace( $set, "", -2 )) $update = "UPDATE $DBTABLE SET $set WHERE data_id=".$prev_row["data_id"]." and year=".$row["year"]." and month=".$row["month"]." and day=".$row["day"].";\n";
if ($row["data_id"] != $prev_row["data_id"]) $delete = "delete from $DBTABLE where data_id=".$row["data_id"]." and year=".$row["year"]." and month=".$row["month"]." and day=".$row["day"].";\n\n";
if ($update) {
$r = mysql_query($update) or die ("could not run query '$update' \n".mysql_error());
}
if ($delete) {
$r = mysql_query($delete) or die ("could not run query '$delete' \n".mysql_error());
}
//if ($counter++ > 5) exit(0);
}
else {
$last = $current;
unset($prev_row);
//copy $row to $prev_row
foreach ($row as $key => $val) $prev_row[$key] = $val;
}
$i++;
}
echo "\n\nDONE\n";
?>
I would try two things:
1) Instead of running the UPDATE and DELETE queries inside the loop using mysql_query, save them in a text file, to execute later. For example: file_put_contents('queries.sql', $update, FILE_APPEND );
2) Instead of doing everything inside the while ($row = mysql_fetch_assoc($res)) loop, first grab all SELECT query results, then close database connection freeing all database resources, including the query result. Only after this, perform the loop process.
If you run out of memory while storing the database results in one array, you can try saving the results in a temporary file instead (one record per line / FILE_APPEND), and then use this file in the loop (reading one line per record, using fgets function).
Work smarter, not harder:
SELECT station_id, year, month FROM table
GROUP BY station_id, year, month
HAVING COUNT(*) > 1
That'll get you all the station_id/year/month tuples that appear in the table more than once. Assuming that most of your data is not duplicates, that'll save you a lot of memory, since now you just have to go through these tuples and fix up the rows matching them.
I found this when trying to trace down a memory use problem on a script of mine. Having solved the issue for mine I thought it worth adding a reply here for the next person who comes along with the same issue.
I was using mysqli, but much the same applies for mysql.
The problem I found was the queries not freeing their results. The solution was to use mysqli_free_result() after executing the update and delete queries. But more importantly on the mysqli_query for the loop I used the extra parameter of *MYSQLI_USE_RESULT* . There are side effects of this, so use a separate connection for the update and delete queries.

insert multiple rows into database from arrays

i need some help with inserting multiple rows from different arrays into my database.
I am making the database for a seating plan, for each seating block there is 5 rows (A-E) with each row having 15 seats.
my DB rows are seat_id, seat_block, seat_row, seat_number, therefore i need to add 15 seat_numbers for each seat_row and 5 seat_rows for each seat_block.
I mocked it up with some foreach loops but need some help turning it into an (hopefully single) SQL statement.
$blocks = array("A","B","C","D");
$seat_rows = array("A","B","C","D","E");
$seat_nums = array("1","2","3","4","5","6","7","8","9","10","11","12","13","14","15");
foreach($blocks as $block){
echo "<br><br>";
echo "Block: " . $block . " - ";
foreach($seat_rows as $rows){
echo "Row: " . $rows . ", ";
foreach($seat_nums as $seats){
echo "seat:" . $seats . " ";
}
}
}
Maybe there's a better way of doing it instead of using arrays?
i just want to avoid writing an SQL statement that is over 100 lines long ;)
(im using codeigniter too if anyone knows of a CI specific way of doing it but im not too bothered about that)
try
<?php
$blocks = array("A","B","C","D");
$seat_rows = array("A","B","C","D","E");
$seat_nums = array("1","2","3","4","5","6","7","8","9","10","11","12","13","14","15");
foreach($blocks as $block){
foreach($seat_rows as $rows){
foreach($seat_nums as $seats){
$querys[] = "('" . $block "','" . $rows . "', '" . $seats . "' )";
}
}
}
$query_inserts = join ( ", ", $querys );
$query = "
INSERT INTO
table
( block, rows, seats )
VALUES
" . $query_inserts . "
";
mysql_query ($query);
?>
One solution is to use prepared statements:
$pdo = new PDO('mysql:dbname=mydb', 'myuser', 'mypass');
$stmt = $pdo->prepare('INSERT INTO seats
(seat_id, seat_block, seat_row, seat_number)
VALUES (?,?,?,?);
');
foreach (...) {
$stmt->execute(array($seat_id, $seat_block, $seat_row, $seat_number));
}

Categories