Insert statement with automatically generated columns - php

I want to create an INSERT statement using the columns of my table and NULL or blank values for the content except for the id, created_by .etc. I am trying to avoid duplicates. Right now I get:
INSERT INTO testimonials (id, created, created_by, id, quote, name, position, company, published, created, created_by, last_modified_by, last_modified) VALUES ('257927816', NOW(), '1', '')
and I would like to have blank values iterate in the VALUES section for everything but the first 3, which I define.
function insertBlankWithID($table, $postFxn) {
global $randomID;
$id = $randomID;
$resultInsert = mysql_query("SELECT * FROM " . $table);
if (!$resultInsert) {
echo '<div class="ec-messages messages-error">'.QUERY_ERROR.'</div>';
include($cmsdir . FOOTER_EXIT);
exit();
}
$columns = array();
while ($row = mysql_fetch_assoc($resultInsert)) {
if (empty($columns)) {
$columns = array_keys($row);
}
}
//$sql = 'INSERT INTO `testimonials` (`id`, `quote`, `name`, `position`, `company`, `published`, `created`, `created_by`, `last_modified_by`, `last_modified`) VALUES ('.$id.', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);';
$sql = sprintf("INSERT INTO %s (id, created, created_by, %s) VALUES ('".$id."', NOW(), '".$_SESSION['user_id']."', '%s')", $table, implode(', ', $columns), implode("', '", ''));
mysql_query($sql);
/*
if (!$sql) {
echo '<div class="ec-messages messages-error">'.QUERY_ERROR.'</div>';
exit();
}
*/
echo $sql;
}
// redirect(basename($_SERVER['PHP_SELF'], ".php").'?s=output&id='.$id
insertBlankWithID('testimonials', $postFxn);

Looking at your code, you should limit the select to 1, (ie $resultInsert = mysql_query("SELECT * FROM " . $table. " limit 1"); as you don't need the information, just the keys. That removes the need for the while loop.
Now, to get all the keys except the first three, for your $columns variable, use array_slice such as $columns = array_slice($columns, 3); Or, if it isn't the first three when you select *, you can do $columns = array_diff($columns, array('id', 'created', 'created_by') );
Now, to insert null after the first three, you are imploding a string - which won't work, instead you can make an array of null values matching the count of the new $columns such as:
$blanks = array_fill(0, count($columns), 'null');
and when creating your statement, do implode(", ", $blanks), which would make your $sql look like:
$sql = sprintf("INSERT INTO %s (id, created, created_by, %s) VALUES ('".$id."', NOW(), '".$_SESSION['user_id']."', '%s')", $table, implode(', ', $columns), implode(", ", $blanks));
And that should fix the issue you've described.
Also, while I'm here, it should be noted that you should not use mysql_ functions anymore and move to mysqli_ for the same type of procedure-oriented MySQL access.

Related

How to insert values to table that are there only in the JSON object in PHP

I've a table which is created with below SQL statement
CREATE TABLE example (
col1 varchar(20) DEFAULT NULL,
col2 varchar(20) DEFAULT NULL,
col3 varchar(20) DEFAULT NULL
)
I want to insert values to this table from a JSON object. JSON object is constructed such way that its key is the column name and value is the value to be inserted.
How do I write a PHP code to only insert the values that are there in the JSON object?
For instance, If I have a JSON object
{
"col1": "some value",
"col3": "some value"
}
The insert statement should only insert values to col1 and col3 and the col2 should remain as NULL.
Please help me out to solve this puzzle. PHP with PDO is preferable.
Experiments performed so far
$object = json_decode($jsonObject);
foreach ($object as $col => $val) {
$columns .= $col . ",";
$values .= $val . ",";
}
$sql = "INSERT INTO example (" .substr($columns, 0, strlen($columns)-2) .
") VALUES (" . substr($values, 0, strlen($columns)-2) . ")";
Your code is pretty close. The problem is that you don't have quotes around each value in $values.
Here's another way to write it:
$object = json_decode($jsonObject, true);
$columns = implode(', ', array_keys($object);
$values = implode(', ', array_map(function($x) { return "'$x'"; }, $object));
$sql = "INSERT INTO example($columns) VALUES ($values)";
The function in array_map() returns each value with quotes around it, then implode() combines them all with commas.
If you're using PDO, you can pass an array of values to PDOStatement::execute().
$values = array_values($object);
// Create "?, ?, ?, ..." string with enough placeholders for the values
$placeholders = implode(', ', array_fill(0, count($values), '?'));
$sql = "INSERT INTO example($columns) VALUES ($placeholders)";
$stmt = $pdo->prepare($sql);
$result = $stmt->execute($values);

writing fetch_assoc() array data to table

What is the proper way to reference the array components from fetch_assoc() so that they can be inserted into another table?
Here is my current code:
$sql_read = "SELECT id, data1, data2, date FROM `table1`";
$result = $mysqli->query($sql_read);
if ($result !== false) {
$rows = $result->fetch_all();
}
while ($row = $result->fetch_assoc()){
$sql_write = "INSERT INTO `table2`.`load_records` (`id`, `data1`,`data2`,`date`) VALUES ('.$row['id']', '.$row['data1']', '.$row['data2']', '.$row['date']', NULL);";
}
As suggested in my comment, first your select statement should be:
"SELECT id, data1, data2, date FROM `table1`";
Furthermore, the insert statement should be (see the use of concatenation of strings):
"INSERT INTO `table2`.`load_records` (`id`, `data1`,`data2`,`date`) VALUES ('".$row['id']."', '".$row['data1']."', '".$row['data2']."', '".$row['date']."', NULL);";
There are some errors in your script, as already pointed out.
But you might also be interested in the INSERT INTO ... SELECT variant of the INSERT syntax.
<?php
$query = '
INSERT INTO
table2
(`id`, `data1`,`data2`,`date`)
SELECT
`id`, `data1`,`data2`,`date`
FROM
table1
';
$result = $mysqli->query($query);
if ( !$result ) {
trigger_error('error: ' . $mysqli->error, E_USER_ERROR);
}
else {
echo $mysqli->affected_rows, ' rows have been transfered';
}
You have an extra field in the VALUES that is not referenced in the INTO and the concatenation of the row data is incorrect;
$sql_write = "INSERT INTO `table2`.`load_records`
(`id`, `data1`,`data2`,`date`)
VALUES ('.$row['id'].', '.$row['data1']', '.$row['data2']', '.$row['date']', NULL);";
should be:
$sql_write = "INSERT INTO `table2`.`load_records`
(`id`, `data1`,`data2`,`date`)
VALUES ('".$row['id']."', '".$row['data1']."', '".$row['data2']."', '".$row['date']."');";
Or you need to update the INTO to include an extra column that accepts NULL
See also:
The PHP reference on mysqli_result::fetch_assoc

Inserting array of Ids in Codeigniter

I'm trying to insert two rows but the id of every row is in the same array, how can I insert correctly?
Because I tried by this way but only insert me the first id.
$sql = "
INSERT INTO cars(car, price, createdDate, createdBy)
VALUES (".$this->db->escape($ids).",
".$this->db->escape($price).",
NOW(),
".$this->session->userdata('admin_id').")";
mysql_query($sql);
echo ($sql);
This is what I get:
INSERT INTO cars (car, price, createdDate, createdBy)
VALUES ('217450,217449', '15', NOW(), 150)
In car I want to insert the price, createdDate and createdBy on the two car Ids 217450,217449.
Thank you in advance.
$ids = "217450, 217449";
$id_explode = explode(",", $ids);
foreach($id_explode as $id)
{
$sql = "
INSERT INTO cars(car, price, createdDate, createdBy)
VALUES (".$this->db->escape($id).",
".$this->db->escape($price).",
NOW(),
".$this->session->userdata('admin_id').")
";
mysql_query($sql);
echo ($sql);
}
But I recommend you not to use raw SQL queries as it is vulnerable to SQL injection.Hence, Use CI's active record:
$ids = "217450, 217449";
$id_explode = explode(",", $ids);
$insert_batch = array();
foreach($id_explode as $id)
{
$arr = array(
'car' => $id,
'price' => $price,
'createdDate' => NOW(),
'createdBy' => $this->session->userdata('admin_id'),
);
$insert_batch[] = $arr;
}
$this->db->insert_batch('cars', $insert_batch);
Documentation:
https://ellislab.com/codeigniter/user-guide/database/active_record.html
Use PHP function explode:
$ids= explode(',', $ids);
foreach($ids as $id)
{
$sql = "INSERT INTO cars(car, price, createdDate, createdBy)
VALUES (" . $this->db->escape($id) . ", " . $this->db->escape($price)
. ", NOW(), " . $this->session->userdata('admin_id') . ")";
mysql_query($sql);
}
If you use ids as array like
$ids = array('217450','217449');
$sql = "
INSERT INTO cars(car, price, createdDate, createdBy)
VALUES ";
foreach($ids as $id){
$sql .=(".$this->db->escape($id).",
".$this->db->escape($price).",
NOW(),
".$this->session->userdata('admin_id')."),";
}
mysql_query($sql);
echo ($sql);
Now it will create query
INSERT INTO cars (car, price, createdDate, createdBy)
VALUES ('217450', '15', NOW(), 150),('217450', '15', NOW(), 150);

How to select the last inserted ID on concatenated values

I'm trying to get the last inserted id of multiple inserted rows.
record_id is auto increment
$sql = "INSERT INTO records (record_id, user_id, status, x) values ";
$varray = array();
$rid = $row['record_id'];
$uid = $row['user_name'];
$status = $row['status'];
$x = $row['x'];
$varray[] = "('$rid', '$uid', '$status', '$x')";
$sql .= implode(',', $varray);
mysql_query($sql);
$sql2 = "INSERT INTO status_logs (id, record_id, status_id, date, timestamp, notes, user_id, x) VALUES";
$varray2[] = "(' ', mysql_insert_id(), '$status', '$uid', '$x')";
$sql2 .= implode(',', $varray2);
mysql_query($sql2);
This is the result:
INSERT INTO records (record_id, user_id, notes, x) values ('', '1237615', 'this is a note', 'active')
INSERT INTO status_logs (log_id, record_id, status_id, date, timestamp, notes, user_id, x) VALUES('', INSERT INTO records (record_id, user_id, notes, x) values ('', '1237615', 'this is a note', 'active')
INSERT INTO status_logs (log_id, record_id, status_id, date, timestamp, notes, user_id, x) VALUES('', mysql_insert_id(), '1', '2013:05:16 00:00:01', '', this is a note'', '1237615', 'active'), '1', '2013:05:16 00:00:01', '', this is a note'', '1237615', 'active')
There is no value for mysql_insert_id().
You're mixing php function mysql_insert_id() and SQL INSERT statement syntax.
Either use MySQL function LAST_INSERT_ID() in VALUES clause of INSERT statement
INSERT INTO records (user_id, notes, x) VALUES('1237615', 'this is a note', 'active');
INSERT INTO status_logs (record_id, status_id, date, timestamp, notes, user_id, x)
VALUES(LAST_INSERT_ID(), '1', ...);
^^^^^^^^^^^^^^^^^
or retrieve the last inserted id by making a separate call to mysql_insert_id() right after first mysql_query(). And then use that value when you as a parameter to your second query.
$sql = "INSERT INTO records (user_id, ...)
VALUES(...)";
$result = mysql_query($sql);
if (!$result) {
die('Invalid query: ' . mysql_error()); //TODO beter error handling
}
$last_id = mysql_insert_id();
// ^^^^^^^^^^^^^^^^^^
$sql2 = "INSERT INTO status_logs (record_id, ...)
VALUES $last_id, ...)";
$result = mysql_query($sql);
if (!$result) {
die('Invalid query: ' . mysql_error()); //TODO beter error handling
}
Note:
You don't need to specify auto_incremented column in column list. Just omit it.
Use at least some sort of error handling in your code
On a side note: Instead of interpolating query strings and leaving it wide open to sql-injections consider to use prepared statements with either mysqli_* or PDO.
Unless I mis-reading your code, you're calling the PHP function mysql_insert_id from within the SQL?
What you need to do is grab that into a PHP variable first, then use the variable in the SQL. Something like this:
// Run the first query
mysql_query($sql);
// Grab the newly created record_id
$recordid= mysql_insert_id();
Then in the second INSERTs just use:
$varray2[] = "(' ', $recordid, '$status', '$uid', '$x')";

How to create sql insert query dynamically in mysql

I am creating an application where I am generating pins dynamically based on user's input and storing them into mySql database.
$sql = "INSERT INTO tblpin ('pinId', 'ownerId', 'usedby', 'status')
VALUES
for($i=0;$i<$npin;$i++)
{
('$pin[$i]','$ownerid', 'Free', '1');
}
;";
how can I do that?
$s = $pdo->prepare("INSERT INTO xy (a,b,c,d) VALUES (?,?,?,?)");
foreach ($pins as $i) {
$s->execute($i,$ownerID,"free",1);
}
Try this:
$sql = "INSERT INTO tblpin ('pinId', 'ownerId', 'usedby', 'status') VALUES ";
for($i=0; $i<sizeof($pin); $i++) {
if ($i>0)
$sql .= ", ";
$sql .= "('$pin[$i]', '$ownerid', 'Free', '1')";
}
Of course you need to escape the values of $pin in case they contain any characters which could mess with the SQL query.
Something like
$sql = sprintf( "INSERT INTO `tblpin` (`pinId`, `ownerId`, `usedby`, `status`) VALUES ('%s', '%s', '%s', '%s')",
generatePIN($pin),
mysql_real_escape_string($ownerId),
mysql_real_escape_string($usedBy),
mysql_real_escape_string( $status) );
or (edited for Conspicuous Compiler)
$pins = generatePINS($user); // ? however they're generated
foreach( $pins as $pin) {
$sql = sprintf( "INSERT INTO `tblpin` (`pinId`, `ownerId`, `usedby`, `status`) VALUES ('%s', '%s', '%s', '%s')",
$pin,
mysql_real_escape_string($ownerId),
mysql_real_escape_string($usedBy),
mysql_real_escape_string( $status) );
$result = mysql_query($sql);
}
where generatePIN is your function to make your pin based on whatever the heck you're basing it off of. or generatePINS returns an array of them

Categories