Refactor PHP script to do mysql update between 2 database servers - php

I'm trying to finish a script that connects to two databases, each on a different server, and preforms an update. Basically, the tables being selected from and inserted to are identical: I did a dump/import the other day. The script needs to keep my local table up to date from the remote once since there will be daily records inserted into the remote one and I need to keep it up to date locally.
The key here is that I'm determining the new rows on the remote server by looking at the Auto-incremented Primary key that the tables share, SESSIONID . I'm trying to get my loop below to say, if the id exists in remote server and not local, then insert those records in local server.
I run the below script in powershell by typing php 'filename', and I get both of my successful connection messages, but then it hangs. After about 10 minutes, it had a memory error so I added ini_set('memory_limit', '256M');. After this it would still hang for about 10 minutes, and then say that MySQL server has gone away and result header couldn't be found, both errors occurring on the line where I check to see if the $rowCount failed.
Note: Replication and large dump/import/table recreations are not an option for us in this situation. We have several similar scripts to this running and we want to keep the same process here. I'm merely looking to resolve these errors or have someone give me a more efficient way of coding this script, perhaps using a max id or something along those lines.
Here's the script:
ini_set('memory_limit', '256M');
// Create connection
$conn = new mysqli($servername, $username, $password);
$conn2 = new mysqli($servername2, $username2, $password2);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
echo "Connected successfully";
// Check connection2
if ($conn2->connect_error) {
die("Connection failed: " . $conn2->connect_error);
}
echo "Connected successfully";
//Start queries
//Select All rows from the source phone database
$source_data = mysqli_query($conn, "select * from cdrdb.session");
// Loop on the results
while($source_item = $source_data->fetch_assoc()) {
// Check if row exists in destination phone database
$row_exists = $conn2->query("SELECT SESSIONID FROM ambition.session WHERE SESSIONID = '".$source_item['SESSIONID']."' ");
//if query returns false, rows don't exist with that new ID.
if (!$row_exists){
//Insert new rows into ambition.session
$conn2->query("INSERT INTO ambition.session (SESSIONID,SESSIONTYPE,CALLINGPARTYNO,FINALLYCALLEDPARTYNO,DIALPLANNAME,TERMINATIONREASONCODE,ISCLEARINGLEGORIGINATING,CREATIONTIMESTAMP,ALERTINGTIMESTAMP,CONNECTTIMESTAMP,DISCONNECTTIMESTAMP,HOLDTIMESECS,LEGTYPE1,LEGTYPE2,INTERNALPARTYTYPE1,INTERNALPARTYTYPE2,SERVICETYPEID1,SERVICETYPEID2,EXTENSIONID1,EXTENSIONID2,LOCATION1,LOCATION2,TRUNKGROUPNAME1,TRUNKGROUPNAME2,SESSIONIDTRANSFEREDFROM,SESSIONIDTRANSFEREDTO,ISTRANSFERINITIATEDBYLEG1,SERVICEEXTENSION1,SERVICEEXTENSION2,SERVICENAME1,SERVICENAME2,MISSEDUSERID2,ISEMERGENCYCALL,NOTABLECALLID,RESPONSIBLEUSEREXTENSIONID,ORIGINALLYCALLEDPARTYNO,ACCOUNTCODE,ACCOUNTCLIENT,ORIGINATINGLEGID,SYSTEMRESTARTNO,PATTERN,HOLDCOUNT,AUXSESSIONTYPE,DEVICEID1,DEVICEID2,ISLEG1ORIGINATING,ISLEG2ORIGINATING,GLOBALCALLID,CADTEMPLATEID,CADTEMPLATEID2,ts,INITIATOR,ACCOUNTNAME,APPNAME,CALLID,CHRTYPE,CALLERNAME,serviceid1,serviceid2)
VALUES ('".$source['SESSIONID']."' ,
'".$source['SESSIONTYPE']."' ,
'".$source['CALLINGPARTYNO']."' ,
'".$source['FINALLYCALLEDPARTYNO']."',
'".$source['DIALPLANNAME']."',
'".$source['TERMINATIONREASONCODE']."',
'".$source['ISCLEARINGLEGORIGINATING']."',
'".$source['CREATIONTIMESTAMP']."',
'".$source['ALERTINGTIMESTAMP']."',
'".$source['CONNECTTIMESTAMP']."',
'".$source['DISCONNECTTIMESTAMP']."',
'".$source['HOLDTIMESECS']."',
'".$source['LEGTYPE1']."',
'".$source['LEGTYPE2']."',
'".$source['INTERNALPARTYTYPE1']."',
'".$source['INTERNALPARTYTYPE2']."',
'".$source['SERVICETYPEID1']."',
'".$source['SERVICETYPEID2']."',
'".$source['EXTENSIONID1']."',
'".$source['EXTENSIONID2']."',
'".$source['LOCATION1']."',
'".$source['LOCATION2']."',
'".$source['TRUNKGROUPNAME1']."',
'".$source['TRUNKGROUPNAME2']."',
'".$source['SESSIONIDTRANSFEREDFROM']."',
'".$source['SESSIONIDTRANSFEREDTO']."',
'".$source['ISTRANSFERINITIATEDBYLEG1']."',
'".$source['SERVICEEXTENSION1']."',
'".$source['SERVICEEXTENSION2']."',
'".$source['SERVICENAME1']."',
'".$source['SERVICENAME2']."',
'".$source['MISSEDUSERID2']."',
'".$source['ISEMERGENCYCALL']."',
'".$source['NOTABLECALLID']."',
'".$source['RESPONSIBLEUSEREXTENSIONID']."',
'".$source['ORIGINALLYCALLEDPARTYNO']."',
'".$source['ACCOUNTCODE']."',
'".$source['ACCOUNTCLIENT']."',
'".$source['ORIGINATINGLEGID']."',
'".$source['SYSTEMRESTARTNO']."',
'".$source['PATTERN']."',
'".$source['HOLDCOUNT']."',
'".$source['AUXSESSIONTYPE']."',
'".$source['DEVICEID1']."',
'".$source['DEVICEID2']."',
'".$source['ISLEG1ORIGINATING']."',
'".$source['ISLEG2ORIGINATING']."',
'".$source['GLOBALCALLID']."',
'".$source['CADTEMPLATEID']."',
'".$source['CADTEMPLATEID2']."',
'".$source['ts']."',
'".$source['INITIATOR']."',
'".$source['ACCOUNTNAME']."',
'".$source['APPNAME']."',
'".$source['CALLID']."',
'".$source['CHRTYPE']."',
'".$source['CALLERNAME']."',
'".$source['serviceid1']."',
'".$source['serviceid2']."')");
}
}

// Check if row exists in destination phone database
$row_exists = $conn2->query("SELECT SESSIONID FROM ambition.session WHERE SESSIONID = '".$source_item['SESSIONID']."' ");
//if query returns false, rows don't exist with that new ID.
if (!$row_exists){
This is incorrect: if query returns false, the query failed to execute. You need to check if ($row_exists->num_rows == 0) instead. The way your code is now, it will always insert every record, again and again. Since you're not checking for errors on the INSERT query you're not noticing the failures you're getting on the duplicate entries for your SESSIONID column (I assume that's the primary key column in your local database as well).
Additionally, it would probably be a lot faster if you only SELECT the sessions you don't already have. Since you're working with an auto increment column, you can pretty much assume that anything in the remote database with a SESSIONID that came after the latest SESSIONID from your local database is new:
//Start queries
$latest_result = $conn2->query("SELECT MAX(`SESSIONID`) FROM `ambition`.`session`");
$latest_row = $latest->fetch_row();
$latest_session_id = $latest_row[0];
//Select All rows from the source phone database
$source_data = mysqli_query($conn, "SELECT * FROM `cdrdb`.`session` WHERE `SESSIONID` > $latest_session_id");
Tables in MySQL are usually sorted by the primary key column by default, but if you're concerned about the order in which you're inserting data in your local database in case your script gets interrupted for some reason, you could add an explicit ORDER BY `SESSIONID` ASC to the query.

Related

How to Update 1 Million of rows quickly in MYSQL [duplicate]

This question already has answers here:
Best way to INSERT many values in mysqli?
(4 answers)
Closed 1 year ago.
I have only 1 table with 1 million rows that i need to update. The data what I need to update is in a file.txt and its only 1 value to update in 1 million rows.
I use PHP to read file and make the Update.
The problem is the time. Is so slow. Any idea to improve and make more fast?
What I have is:
UPDATE productos SET urlRedirect = getChangeProducto WHERE url LIKE 'getUrlProducto'
TXT file, 2 values separated by (;) first are getChangeProducto and second getUrlProducto:
https://www.example.com/guess/8595651?o=34&t=direct&f=102.301&ord=111;https://example.com/p/guess-jeans-116-175-cm-327554`
PHP FILE:
$mysqli = get_dbc();
if ($mysqli->connect_errno) {
echo "Failed to connect to MySQL: (".$mysqli->connect_errno.") ".$mysqli->connect_error;
exit();
}
$mysqli->set_charset("utf8");
if (!$mysqli) exit(mysqli_connect_error());
$handle = fopen("fileToUpdate.txt", "r");
$total_lines = 0;
if ($handle) {
$line = fgets($handle);
while ($line !== false) {
$url_to_delete = trim($line);
$trozos = explode(";", $url_to_delete);
$total_lines++;
if ($stmt = $mysqli->prepare("UPDATE productos SET urlRedirect = ? WHERE url = ? ")) {
$stmt->bind_param('ss', $trozos[1],$trozos[0]);
$stmt->execute(); // Execute the prepared query.
}
$stmt->close();
$line = fgets($handle);
}
fclose($handle);
}
// Output — Total Lines: 6305.
echo "Total Lines: $total_lines.\n";
I also encountered this problem before. That was around 2009 or 2010 where I need to update multiple entries fast because of the request timeout. Some solution I found was to extend the request timeout configuration of the server but another solution I found was the create a temporary table on the database server and relate the two tables but unfortunately, I cannot share with you the link because that was a long time ago.
So here what I did as long as I could recall:
Create a temporary table with similar structure to your CSV bearing the primary key to which relates to the table you like to perform the update. I know MySQL has the temporary table capability.
From your CSV, upload data by insert the record at once (by batch or multiple values on INSERT statement). This will be fast
Once you have inserted all the record, relate the temporary to your table on UPDATE statement.
Example: UPDATE orig_table ot, temp_table tt SET ot.URLRedirect=tt.URLRedirect WHERE ot.ID=tt.ID
Destroy your temporary table.
The UPDATE statement will set the value of orig_table to the new value from temp_table provided that they relate through their ID.

how to display information from a database in a web page without php

for my homework assignment, I need to display this information from my database in a table on a webpage. with all the research I've done, it seems that I need to use php. is there anyway to do this without php and just html? we haven't learned php yet so I'm confused. here is the database:
CREATE TABLE album (
id serial PRIMARY KEY,
name text,
number text,
year text,
artist text,
description text
);
CREATE TABLE label (
id serial PRIMARY KEY,
title text,
title_id integer REFERENCES album (id)
);
INSERT INTO album (name, number, year, artist, description) VALUES ('Reputation','15','2017','Taylor Swift','Reputation is Taylor Swifts sixth studio album');
INSERT INTO label (text, title_id) VALUES (Big Machine Records, 1);
INSERT INTO album (name, number, year, artist, description) VALUES ('Ripcord','13','2016','Keith Urban','Ripcord is Keith Urbans ninth studio album');
INSERT INTO label (text, title_id) VALUES (Capital Records Nashville, 2);
You can use Node, but I will recommend using php. It can be learned easily.
Remember those steps and it will be easy for you:
1)Php code is written inside tags and file must be saved with .php extension.
2)You need to connect to the database, there are multiple methods
https://www.w3schools.com/php/php_mysql_connect.asp
<?php
$servername = "localhost";
$username = "enterusername";
$password = "enterdatabasepassword";
$database="enterdatabasename";
// Create connection
$con = mysqli_connect($servername, $username, $password,$database);
// Check connection
if (!$con) {
die("Connection failed: " . mysqli_connect_error());
}
echo "Connected successfully";
//this is a comment.
//Usually in localhost username is root and password is empty, so you must use
$username="root";
$password="";
3) Now you are connected to the database. This is how you get data from the database.
// $sql is just a variable
//$con is the variable that stores database connection. We declared it before.
$sql = mysqli_query($con, "SELECT * FROM album");
$count = mysqli_num_rows($sql); //mysqli_num_rows counts rows returned from database.
//now we check if database returned more than 0 rows
if($count>0){
//if returned rows >0 we fetch the data
while ($row = mysqli_fetch_array($sql)){
//Now we store each field in variables:
$id=$row['id'];
$name=$row['name'];
$number=$row['number'];
$year=$row['year'];
$artist=$row['artist'];
$description=$row['description'];
//Now we can create table
echo "<table><thead><tr> <td>id</td><td>name</td><td>number</td><td>year</td><td>artist</td><td>description</td></tr></thead>
<tbody>
<tr> <td>$id</td><td>$name</td><td>$number</td><td>$year</td><td>$artist</td><td>$description</td></tr>
</tbody>
</table>";
}
}
//Hope this helped you.
The process for read data from a database is: Presentation -> Language -> Driver -> Database.
Where:
Presentation-> The endpoint where you want show the data, it can be an app, webpage, console etc...
Language-> You need a programming language with an interface for the driver, generally this interface is a library.
Driver-> It's an abstraction layer that allow your library connect to a database.
Database-> your data here.
So you need to use programming to show data on a html page, but if you want only show the data you can use a viewer like this:
http://kripken.github.io/sql.js/GUI/

Error Inserting/Updating a row in a Database using SQL, Php and Ajax

UPDATE
The SQL error I'm receiving is:
Error: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'WHERE (fb_id) = ('1018762834552473') ON DUPLICATE KEY UPDATE score='69139'' at line 1
I’m creating a leaderboard table for a Javascript game and I’m currently trying to insert the player’s score into my database whenever a certain Javascript function runs.
I’m doing this with an Ajax Post using Php. I’ve put a console.log into the success area of the Ajax, and it’s appearing, which I think means that the php file is running correctly, but the score isn’t being updated in the database, so I think that maybe there’s a mistake in my SQL code.
This is the Ajax Post:
$.ajax({
url: 'scripts/sendscore.php',
data: {'userid' : userid, 'score' : totalscore},
type: "POST",
success: function(response){
if (response.error) {
console.log('Score input error - ' + response.error.message);
}
else {
console.log("Score should be inputted correctly.");
}
}});
The leaderboard is for a Facebook game, so I’m sending two things in the Post, they are: the score, and the user’s id.
I want the php code to enter the score into the database where the user’s id that is sent matches the user’s id in the database, to simplify, I want it to insert/update the player’s score with the new score (a player shouldn’t have multiple scores in the database, they should only have one score). This is the SQL I’m using to try to achieve this:
<?php
$servername = "myserver";
$username = "myusername";
$password = "mypassword";
$dbname = "mydbname";
try {
$conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
// set the PDO error mode to exception
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $conn->prepare("INSERT INTO scoretable (score) VALUES(:score) WHERE (fb_id) = (:userid) ON DUPLICATE KEY UPDATE score=:score");
$stmt->bindParam(':userid', $userid);
$userid = $_POST['userid'];
$stmt->bindParam(':score', $score);
$score = $_POST['score'];
$stmt->execute();
}
catch(PDOException $e)
{
echo "Error: " . $e->getMessage();
}
$conn = null;
?>
The database table is made up of two columns, like this:
scoretable
=========
fb_id
score
I’m getting the message “Score should be inputted correctly.” back in the console, so I think the problem might be with the line of SQL?
Any help with this would be really appreciated, thank you in advance!
Note that ON DUPLICATE KEY UPDATE checks every unique fields in table, not just PRIMARY key. You want ON DUPLICATE KEY to match a UNIQUE key for score, then your INSERT will work fine without the WHERE clause. The bad news is that Mysql does not allow where clause on duplicate key update, so a quick trick would be to use if statement:
Try this statement:
INSERT INTO `scoretable` (`score`) VALUES(:score)
ON DUPLICATE KEY UPDATE
`fb_id` = LAST_INSERT_ID(fb_id),
`score`= IF(VALUES(:score) >= score, VALUES(:score), score);
Here, fb_id is an auto-increment field that I do not want modified by the UPDATE; hence the LAST_INSERT_ID trick.
You are assigning values to variables $userid & $score after their binding.
Check the data type and size of the fb_id (may be it is not able to hold the value with the data type you have in the database 1018762834552473)

How can I update and insert into two different tables using php mysql database

How can I update a particular table using mysql database with an output message in the php script using echo and at the same time and insert into another with a redirection after a successfully insertion.
Here is what I have tried but not getting the result I wanted
<?php
$dbhost="xxxx";
$dbusr="xxxx";
$dbpass="xxxx";
$database="xxxxx";
mysql_connect($dbhost,$dbusr,$dbpass, $database);
mysql_select_db($database) or die("databse not connected");
$num = rand(98564654, 415231564);
If(isset($_POST['login'])){
$Pin=$_GET['pin'];
$ID =$_POST['ID'];
$date=date('Y-m-d H:i:s');
if($Pin!=''){
mysql_query("UPDATE pin SET appid ='$num', status='Activated' WHERE Pin= '$Pin'")
or die(mysql_error());
mysql_query("INSERT IGNORE INTO pinlog (TableName,pin,id,TIME_UPDATED) VALUES('Pin','$Pin','$num','$date')")
or die(mysql_error());
header("location:applicantlogin.php");
}
}
?>
Please Help
Perhaps this helps:
First, set PIN activated only when its not activated:
UPDATE pin SET appid ='$num', status='Activated'
WHERE Pin= '$Pin' AND status <> 'Activated'
Then, find out how many rows were affected (there's a function for that).
If 0 then already activated and bail out. Check your indexes as well.

Search mysql database before inserting data

I cant quite think about how to do this with mysql and php. Basically I want to be able to submit data into a mysql database but before it is inserted, it will check to see if that entry already exists.
$guid=$_POST['guid'];
$name=$_POST['name'];
//Username
$user="webhost";
//Password
$pass="*******";
//IP To Host
$ip="***********";
//Database
$db="dayz2";
//Table
$table="whitelist";
//Database Connection
$con=#mysql_connect("$ip", "$user", "$pass")
or die(mysql_error());
//Select Database
$dbcon=#mysql_select_db($db, $con)
or die(mysql_error());
$dupesql = "SELECT * FROM $table where (name = '$name' AND guid = '$guid')";
$duperaw = mysql_query($dupesql);
if (mysql_num_rows($duberaw) > 0) {
echo "Entry Already Exists";
}
else {
//Query Data Into Whitelist Table
$sql="INSERT INTO $table (name, guid) VALUES ('$name', '$guid')";
//Submit Data into Whitelist Table
$result=#mysql_query($sql, $con) or die(mysql_error());
}
?>
You can do it in another way, instead of:
submit data into a mysql database but before it is inserted, it will
check to see if that entry already exists.
You can do:
INSERT data into a mysql database if not existed, else ignore them
Something like :
INSERT IGNORE INTO table
INSERT IGNORE INTO yourtablename
SET fieldname = 'blah'
,..
It depends what you are trying to do - what is the exact criteria for your query?
You have several options:
use INSERT IGNORE ... if you only want to insert new rows that don't have a duplicate primary key. See http://dev.mysql.com/doc/refman/5.5/en/insert.html.
use INSERT ... ON DUPLICATE KEY UPDATE to insert new rows and update rows where there is a primary key match.
See http://dev.mysql.com/doc/refman/5.5/en/insert-on-duplicate.html.
use a normal SQL SELECT ... to pull the results first before performing business logic on the results before deciding which to INSERT ... or UPDATE ... depending on your requirements.
It depends how you want to handle case when the entry exists.
I you want to throw some error then you can create table trigger for insert event and put some checks there, but it will be slow because every insert will do this check.

Categories