I have a 2 part html / php form, and one of the $_POST values is the session_id(); m which will be the unique ID in the database table.
On the first part of the form, the user eneters their contact information and it is inserted into a MySQL database.
INSERT INTO $table ($columns) VALUES ($values)
On the 2nd part of the form where they enter extra information, if the session_id() is the same, I just want to update all the columns that are being submitted, which will always be different from the columns in the first part of the form. How do I just update all columns being submitted while leaving previously submitted data intact.
In this example, $columns and $values are CSV string, i.e.
Submission 1
$columns = "'SSID', 'Name', 'Email'";
$values = "'65464s4468fff9864wef68d', 'John Doe', 'someone#something.com'";
Submission 2
$columns = "'SSID', 'Product', 'Comments'";
$Values = "'65464s4468fff9864wef68d', 'Apple', 'some comments'";
So I would just need to update the columns 'Product' and 'Comments'. I need to do this dynamically with many different forms so I would rather not have to specify which columns to update since they are already the only ones being inserted.
I'm attempting something like:
INSERT INTO $table ($columns) VALUES ($values) ON DUPLICATE KEY UPDATE $columns = $columns
What would be the proper syntax? Currently this gives me a syntax error
Edit: Added last line
You could also do:
REPLACE INTO $table ($columns) VALUES ($values);
Related
I have unknown keys and values to import to database from CSV.
My code is
while($data = fgetcsv($handle,1000,",",'"'))
{
$data=array_map('addslashes',$data); // apply addslashes() to all values
$data=array_combine($csv_fields,$data); // csv fields assoc (key=>value)
$data=array_intersect_key($data,$tbl_fields); // discard redundant
$tbl_fields_str=implode("`,`",array_keys($data));
$tbl_vals_str=implode("','",array_values($data));
$q="INSERT INTO `cmid` (`cmid`,`$tbl_fields_str`) VALUES ('$cmidtrenutni','$tbl_vals_str') ON DUPLICATE KEY UPDATE (`$tbl_fields_str`) VALUES ('$tbl_vals_str')";
$conn->query($q);
}
I need to insert and if exist, update.
I try this code above but doesnt work.
I find something like http://dev.mysql.com/doc/refman/5.5/en/insert-on-duplicate.html
But this doesnt help in my way cause my table doesnt have defined fields. Keys and values are different on every input.
Any solution how to do this?
This is your query:
INSERT INTO `cmid` (`cmid`, `$tbl_fields_str`)
VALUES ('$cmidtrenutni', '$tbl_vals_str')
ON DUPLICATE KEY UPDATE (`$tbl_fields_str`) VALUES ('$tbl_vals_str');
The problem is the UPDATE part. You need to split the values so it looks like:
INSERT INTO `cmid` (`cmid`, `$tbl_fields_str`)
VALUES ('$cmidtrenutni', '$tbl_vals_str')
ON DUPLICATE KEY UPDATE
col1 = newcol1val,
col2 = newcol2val,
. . .
The short-hand that you are using is not valid syntax.
To import from a csv file, take a look at the LOAD DATA INFILE statement or the mysqlimport utility.
Try this one:
$q="INSERT INTO `cmid` (`cmid`,`$tbl_fields_str`) VALUES ('$cmidtrenutni','$tbl_vals_str') ON DUPLICATE KEY UPDATE cmid=cmid";
But I prefer using INSERT IGNORE for your problem:
$q="INSERT IGNORE INTO `cmid` (`cmid`,`$tbl_fields_str`) VALUES ('$cmidtrenutni','$tbl_vals_str')";
You cannot have "unknown" columns in mysql DB. if you want to store pairs of key-value in a mysql table, you should have a table with two columns : one would be named "key" and the other one "value". Add an extra column "cmid" to group your pairs.
This table should have a primary index on "cmid" and "key" columns.
Then you should insert values with a query like:
$sqlVals = "";
foreach ($data as $key => $val) {
$sqlVals .= "($cmidtrenutni, $key, $val),";
}
$sqlVals = substr($sqlVals, 0, -1); //remove last comma.
$query = "REPLACE INTO `myTable` (`cmid`, `key`,`value`) VALUES $sqlVals";
I'm relatively new to MYSQL and am having trouble combining idea I have read about. I have a form generated from a query. I want to be able to insert or update depending on whether there is currently a matching row. I have the following code which works for inserting but I;m struggling with the On DUPLICATE UPDATE part I keep getting a message saying there is an error in my syntax or unexpeted ON depending on how I put the ' .
require_once("connect_db.php");
$row_data = array();
foreach($_POST['attendancerecordid'] as $row=>$attendancerecordid) {
$attendancerecordid=mysqli_real_escape_string($dbc,$attendancerecordid);
$employeeid=mysqli_real_escape_string($dbc,($_POST['employeeid'][$row]));
$linemanagerid=mysqli_real_escape_string($dbc,($_POST['linemanagerid'][$row]));
$abscencecode=mysqli_real_escape_string($dbc,($_POST['abscencecode'][$row]));
$date=mysqli_real_escape_string($dbc,($_POST['date'][$row]));
$row_data[] = "('$attendancerecordid', '$employeeid', '$linemanagerid', '$abscencecode', '$date')";
}
if (!empty($row_data)) {
$sql = 'INSERT INTO attendance (attendancerecord, employeeid, linemanagerid, abscencecode, date) VALUES '.implode(',', $row_data)
ON DUPLICATE KEY UPDATE abscencecode = $row_data[abscencecode];
echo $sql;
$result = mysqli_query ($dbc, $sql) or die(mysqli_error ($dbc));
}
The various echo statements are showing that the correct data is coming through and my select statement was as expected before I added in the ON DUPLICATE statement.
You need to fix the way the sql statement is constructed via string concatenation. When you create an sql statement, echo it and run it in your favourite mysql manager app for testing.
$sql = 'INSERT INTO attendance (attendancerecord, employeeid, linemanagerid, abscencecode, date) VALUES ('.implode(',', $row_data).') ON DUPLICATE KEY UPDATE abscencecode = 1'; //1 is a fixed value yiu choose
UPDATE: Just noticed that your $row_data array does not have named keys, it just contains the entire new rows values as string. Since you do bulk insert (multiple rows inserted in 1 statement), you have to provide a single absencecode in the on duplicate key clause, or you have to execute each row in a separate insert to get the absence code for each row in a loop.
Suppose I have a very large array of information for a user:
$user=array(
"name"=>"john",
"ip"=>"xx.xx.xx.xx",
"email"=>"john#something.com",
//lots more values
)
Let's also suppose that this information needs to go into more than one table. For instance a username needs to go table users, address needs to go into a details table, etc.
Now, I use a certain self-made function to insert into my tables that matches array keys to column names and array values to the values being inputted. Something similar to this:
function insert_sql($table, arr $values){
GLOBAL $dbc;
$sql="INSERT INTO `$table` (".implode(array_keys($values), ", ").") VALUES (".implode(array_values($values), ", ").")";
$dbc->prepare($sql)->execute();
return $dbc->lastInsertId();
}
//I don't actually use this function, just trying to show you what is being accomplished.
The problem is that my function uses all the keys and all the values, so when I just need certain parts of the array put into multiple tables, it doesn't work.
The question is:
How do I make an INSERT statement ignore a column if it doesn't exist? So if I insert name,email,address, into table users, but this table doesn't have an address column, I need it to insert the row with the name and email but simply ignore the fact that the address column is not there.
EDIT: The other option is to make an array with the columns of a table and use it to filter the values array. Although I am not really sure how to set this up.
Find given table column names:
SELECT
column_name
FROM
information_schema.columns
WHERE
table_name = 'tablename'
And then just whitelist your keys in $values array
Example:
function insert_sql($table, array $values){
global $connection;
$query = "SELECT column_name FROM information_schema.columns WHERE table_name = :tablename";
/* #var $stmt PDOStatement */
$stmt = $connection->prepare($query);
$stmt->execute(array(
'tablename' => $table
));
$columns = array_flip($stmt->fetchAll(PDO::FETCH_COLUMN, 0));
$values = array_intersect_key($values, $columns);
var_dump($values);
}
How do I make an INSERT statement ignore a column if it doesn't exist?
So if I insert name,email,address, into table users, but this table
doesn't have an address column, I need it to insert the row with the
name and email but simply ignore the fact that the address column is
not there.
You can't
Instead you should map your data to the appropriate tables with separate inserts.
I am using php to insert element values of a form in MYSQL. My form contains 20 different elements, that means
count($_POST)
returns 20. How can I make an INSERT query efficiently in PHP.
I will extract 20 values one by one then concatenate them again one by
one. I do not want to follow this method. Do you have some better
method?
Yes, you can use foreach. Example below assumes 3 thigs:
all of your form fields are text fields,
form fields are in the same order as columns in your table
form elements (<input>) have the same name attribute as columns names in your table
It can go like this:
$sql = 'INSERT INTO table_name VALUES (';
foreach ($_POST as $key => $value)
$sql .= mysqli_real_escape_string($value);
$sql .= ')';
I have a complex form that has 11 columns. As for rows they will vary from about 20 to 50 depending on number of students. I am capturing data via a php script as arrays. Each column produces an array. Example, from the form I have fname[], lname[], exam_no[] etc so when the form is submitted with say, 10 rows, I end up with 11 arrays each with 10 entries, which I pass through some php function to remove empty elements. The arrays are being generated with no issues.
I want to insert data from these arrays into mysql using a loop. Basically, lname array will have all first_name for the first name column, lname array will feed the last_name column of the db and so on.
I am just unable to even start constructing the MySQL query to insert the data, I am well conversant with the 'ordinary' insert where you have columns and values and you already know how many rows will insert, mostly one row per insert.
Is is even possible to populate a MySQL Database Table with an insert using a PHP loop and with this many number of columns and making it flexible to insert any number of rows as that will vary each time a user enters student data?
UPDATE
This is what I came up with. It works but NOT as desired!
Arrays are coming like $fname[], lname[] etc
Then I built the master array to be $master_array=array['$fname, $lname];
$sql = "INSERT INTO testing (date, fname, lname) VALUES ";
foreach($master_array as $subarray) {
$sql .= "(NOW( )";
echo 'A nested array: '.$subarray.'<br />';
foreach($subarray as $value) {
$sql .= ", '$value'";
echo 'A Name: '.$value.'<br />';
}
$sql.= "), ";
}
$sql = substr($sql,0,-2); //removes extraneous , at end.
echo $sql;
$result=mysqli_query($dbc, $sql)
or die('Query Failed!');
?>
Since my query involves conactinating small pieces of code, I was printing it after its built to see what is to be inserted. It looked like so;
INSERT INTO table (date, fname, lname) VALUES (NOW( ), 'Andrew', 'Alex'), (NOW( ), 'Peterson', 'Marlon')
As I suspected, it inserts all first names in the first row, and all last names in the second row. The desired result is to insert first names in the first-name column and second names in the second name column. So now I need a way to insert all elements of one array into a single column and then move to the second array and insert it in the next column. That sounds complex, and I wonder if it's doable! Let me be educated by the masters of the php language as I am an intermediate or may be brand new newbie!
Isn't it better to group the information by student?
Example:
<form...>
<? foreach ($students as $id => $info) : ?>
<input type="text" name="fname;<=$id;?>" value="<?=$info['fname'];?>" />
<input type="text" name="lname;<=$id;?>" value="<?=$info['lname'];?>" />
etc
<? endforeach ?>
</form>
(I'm using PHP short tags here)
Then, when you process the form:
$update = array();
foreach ($_POST as $key => $value) {
// key will look like: fname;1, fname;2, etc
// so, split it on the ; sign to separate the field name from the student's id
$data = explode(';',$key);
// result:
// $data[0] = fname, lname, etc
// $data[1] = 1, 2, etc
// you can add some checks to make sure that this field is valid
// and that the id is in fact a valid id (number, > 0, etc)
// sanitize data (however you want, just an example)
$value = mysql_real_escape_string(trim($value));
// now add it to the update array, grouped by student id
$update[$data[1]][$data[0]] = $value;
// result:
// $update[1]['fname'] = 'First name student 1';
// $update[1]['lname'] = 'Last name student 1';
// $update[2]['fname'] = 'First name student 2';
// $update[2]['lname'] = 'Last name student 2';
// etc
}
After that, go through the update array:
foreach ($update as $id => $info) {
$sql = "UPDATE students
SET fname = '".$info['fname']."', lname = '".$info['lname']."'
WHERE id = $id";
mysql_query($sql);
}