insert new rows from db1.table1 into db2.table1 - php

I have two databases($db1, $db2) with exact table structure(table1). $db2.table1 has new rows which i want to insert into $db1.table1 (i.e. if $db2 is new and $db1 is old, I want to update $db1 with new entries from $db2).
I came up with following php code, and it should work fine, but I am worried about special characters in column ids as well as values to be inserted in it.
Here's the code:
require('update_functions.php'); //contains helper functions
function arraywalk_mysql_real_escape_string(&$value, &$key, $sql_connection) {
$value = mysql_real_escape_string($value, $sql_connection);
$key = mysql_real_escape_string($key, $sql_connection);
}
$sql_connection_old = connectdb('old');
$sql_connection_new = connectdb('new');
$table = 'member'; $pkey = 'id'; //table name and primary key
$last_row_member = mysql_fetch_assoc(last_row($sql_connection_old, $table, $pkey));
//fetches last row from old db
$new_row = new_row($sql_connection_new, $pkey, $last_row_member[$pkey], $table, 'ASC LIMIT 1');
//the new_row function executes following query (after sanitizing input)
//'SELECT * FROM '.$table.' WHERE '.$pkey.'>'.$pkey_value.' ORDER BY '.$pkey.' '.$extra
while($result = mysql_fetch_assoc($new_row)) {
array_walk($result, 'arraywalk_mysql_real_escape_string', $sql_connection_old);
$update_member_query = 'INSERT INTO ' . $table . '( '
. implode(", ", array_keys($insert_vars))
. ' ) VALUES ( \''
. implode("', '", $insert_vars)
. '\' )';
}
I don't know if there will be any special characters in column names. Should I enclose them in backticks?
If yes then should I parse them using mysql_real_escape_srting()?
What about VALUES ? Should I enclose them in quotes 'value'? What if the value to be inserted is a number? what if its Date/Time?
Is there a way where I can bypass fetching data from old database into PHP variables and inserting it back to database (so above questions become irrelevant)?
Note : Even though there are two connections, I have the same SQL server serving the two $db

You can do it in SQL:
INSERT INTO db1.table1
SELECT * FROM db2.table1
WHERE db2.table1.id > (SELECT MAX(id) FROM db1.table1)

Related

I need help getting my sub-query to work? I would like to know if it is faster using a sub-query then my foreach loop way?

// I will be transferring data from one table to another for a frontend-app, which will involove many tables. Time matters here. Original way I would repopulate one table to another
and my DB class works, it is not the problem so no need to put it up here. Thank you for help
$SQL = "SELECT * FROM staging_flows";
$RES = $db->query($SQL);
// looping thruogh the results of my query into staging_flows table
foreach($RES as $row){
$id = $row['id'];
$flow_name = $row['flow_name'];
$coops = $row['coops'];
$changed_flag = $row['changed_flag'];
$removed_flag = $row['removed_flag'];
// Updating the flows table with the data collected from staging_flows table
$SQL1 = "UPDATE flows SET flow_name='$flow_name', coops='$coops',
changed_flag='$changed_flag', removed_flag='$removed_flag' WHERE id='$id'";
$RES = $db->query($SQL1);
//I have been trying a truncate function I developed and the use of sub-query but I
can't get it to sub-query to work. I think the performTruncateTable() function is
sounds.
// Function for Truncate Table
function performTruncateTable($table_name){
$db = new Db();
$link = $db->connect();
$query = "TRUNCATE TABLE `" . $table_name . "`";
$query_response = $db->query($query);
return $query_response;
}
function performTruncateTable_DB($db,$table_name){
$link = $db->connect();
$query = "TRUNCATE TABLE `" . $table_name . "`";
$query_response = $db->query($query);
return $query_response;
}
// Truncate flows table
performTruncateTable_DB($db,'flows')
// Populate flows table with data from the staging flows table using a sub-query
$sql2 = "INSERT INTO flows (id,flow_name,coops) SELECT (id,flow_name,coops) FROM
staging_flows";
$res2 = $db->query($sql2);

MySQL returning wrong insert ID

I ran this SQL statement in PHP to copy data from all columns from "other" into "table" (both table and other have same column names)
$x=mysqli_query($conn,"INSERT INTO table SELECT * from other WHERE item_id='33'");
$nid=mysqli_insert_id($conn);
I would expect $nid to have the new ID from "table" that it just inserted, but instead it returns "33", the ID of the other table coping from.
Maybe it copied everything including the ID from the other table and returned that?
Anybody knows why or how to fix?
Thanks
As both tables have the same column names your insert is setting the id as well as all the other fields.
To avoid that select from other all the fields except the item_id
You can write statically all the column names (except one) in the query in place of * or you can build the column list dinamically with a preliminary query:
// Get all columns names except one
// as comma separated list
// Column names are bacltick quoted
$result = $conn->query(
"SELECT `COLUMN_NAME` "
. "FROM `INFORMATION_SCHEMA`.`COLUMNS` "
. "WHERE `TABLE_SCHEMA`='your_db_name' " // DB name here
. "AND `TABLE_NAME`='other' " // TABLE name here
. "AND `COLUMN_NAME` != 'item_id'" ); // EXCLUDED column here
if( ! $result )
{
// HANDLE EXCEPTION
}
$columns = $result->fetch_all();
foreach( $columns as &$c )
{
$c = '`' . $c[ 0 ] . '`';
}
$columns = implode( ',', $columns );
// Perform the copy
$x = mysqli_query( $conn, "INSERT INTO `table` SELECT $columns from `other` WHERE item_id='33'");
$nid = mysqli_insert_id( $conn );
Side note: if your destination table name is table it must be escaped between backticks `table`.

Copy column values to another column in the same table

I'm trying to copy title column to keywords column in database, so the keywords will be inserted automatically from the title.
http://store2.up-00.com/2015-06/1435609110941.png
I want to add comma ', ' before each word for example.
" It's my first program "
it will turn into
" It's, my, first, program, "
This the code I wrote.
<?php
// $id =mysql_insert_id;
$select_posts = mysql_query("SELECT * FROM `posts`");
while($row = mysql_fetch_array($select_posts)){
$id = $row['post_id'];
$text = $row['post_title'];
$delim = ' \n\t,.!?:;';
$tok = strtok($text, $delim);
while ( $tok !== false){
echo $tok1 = $tok.',';
mysql_query("UPDATE `posts` SET `post_keywords` = '$tok1' WHERE `post_id` = $id ");
$tok = strtok($delim);
}
}
?>
it insert the last word in each title column , because the words is overwritten by while loop.
Please help me .
Concat the values:
... SET post_keywords = CONCAT(post_keywords, '$tok1')
and note that you're vulnerable to sql injection attacks. Just because that $tok1 value came out of a database doesn't mean it's safe to REUSE in a query...
You can do it with a single query :
UPDATE `posts` SET post_keywords = REPLACE(post_title, ' ', ',');

Insert data array in SQL after searching from another SQL table

I have an array $members that contains some ID(maximum 6 in number) from the table users. Using the following code, I loop through each index of $members, search for the details and store them in another array.
foreach($members as $key=>$value){
$res = mysql_query("SELECT id,name,email FROM users WHERE id='$value'");
if ($res === false) {
echo mysql_error();
die;
}
$row = mysql_fetch_assoc($res);
if($row['id'])
{
$members_name[]=$row['name'];//array for name
}
}
Now I want to insert the ID & names that are stored in the array into another TABLE register in the following format:
(The left side are the rows in my TABLE register)
mem_0_id-->$members[0]
mem_0_name-->$members_name[0]
mem_1_id-->$members[1]
mem_1_name-->$members_name[1]
mem_2_id-->$members[2]
mem_2_name-->$members_name[2]
mem_3_id-->$members[3]
mem_3_name-->$members_name[3]
mem_4_id-->$members[4]
mem_4_name-->$members_name[4]
How can I insert in this way? using just a single INSERT statement?
haven't tried this, but here is my answer anyway :)
$query = "INSERT INTO register(id, name) VALUES ($members[0], $members_name[0])";
for($i=1; $i<count($members); $i++)
{
$query .= ", ($members[$i], $members_name[$i])";
}
then try to execute the query..
Do you do anything else with the array, or are you just retrieving it from one table in order to insert it into another?
If so then you can do the whole thing like this.
$memberIds = implode(',', $members); // comma separated list of member ids
$query = "insert into register (id, name) select id, name from users where id in ($memberIds)";
mysql_query($query); // this will select and insert in one go
If you do need to keep the array in memory, then it's still a good idea to get it all out at once
$memberIds = implode(',', $members); // comma separated list of member ids
$query = "select id, name from users where id in ($memberIds)";
$res = mysql_query($query);
while ($row = mysql_fetch_assoc($res)) {
$memberData[] = $row;
}
That's because running a query inside a loop is very bad for performance. Every time you run a query there is an overhead, so getting all the data at once means you pay this overhead once rather than multiple times.
Then you can build a statement to insert multiple rows:
$sql = "insert into register (id, name) values ";
$sql .= "(" . $memberData[0]['id'] . "," . $memberData[0]['name'] . ")";
for($i = 1; $i < count($memberData); $i++) {
$sql .= ",(" . $memberData[$i]['id'] . ",'" . $memberData[$i]['name'] . "')";
}
mysql_query($sql);
It's a bit nasty because of the commas and quotes but if I've done it correctly then if you do
echo $sql;
you should get something like
insert into register (id, name) values (1, 'john'), (2, 'jane'), (3, 'alice');
You can see that the first way, where you select and insert in one statment, is a lot nicer and easier so if you don't do anything else with the array then I highly recommend doing it that way.

Query a table by one or multiple array values

I am trying to run a query to determine if a column A is true. If its true, get the contents of a different column B (possible array separated by ",") and use those contents to query a different table. My problem is, column B may be one number or may be 10 numbers all separated by "," and I need to query the second table for a column for each of the numbers of the previous query. If someone can help that would be great.
edit: I tried to use the array explode function but can't figure out how to query the next table to include those values.
I picture it being something like
query = select * from table where location = arrayValue[1] or location = arrayValue[2]
Adaptation of Telmo Marques here but improved :
<?php
//Let's say $bcolumn is a string with the values of B column, separated by colons
$bcolumnArray = explode(",", $bcolumn);
array_walk($bcolumnArray, 'htmlentities');
//Build SQL query
$SQL = 'SELECT * FROM table';
if(count($bcolumnArray)){
$SQL.= ' WHERE IN ("'.implode('", "', $vbcolumnArray).'")';
}
//Query your second table here
$Qry = mysql_query($sql);
// Results here :
while($Res = mysql_fetch_assoc($Qry)){
print_r($Res);
}
?>
I would suggest PDO also... take a look : PDO.
Use PHP's explode() function to transform your string into an array.
<?php
//Let's say $bcolumn is a string with the values of B column, separated by colons
$bcolumnArray = explode(",", $bcolumn);
//Build SQL query
$sql = "SELECT * FROM table WHERE ";
for($i=0; $i < count($bcolumnArray); $i++)
{
$sql .= "location = " . $value;
if($i != count($bcolumnArray)-1)
{
$sql .= " or ";
}
}
//Query your second table here
mysql_query($sql);
?>
Documentation: http://php.net/manual/en/function.explode.php

Categories