Access to Access Transfer - php

I have asked a couple of questions on here in a rush, and I am getting nowhere fast, I keep changing things and just ending up with a different problem, and no closer to having a clue what is causing it. I am a PHP MYSQL man, and I am having to work with Access via the COM class.
Basically the client has multiple servers, each with an access database, and each with a CMS, the tables should contain the same data and have slipped out of Sync. It is my job to come up with a way of resyncing them.
I have came to bringing the data out into an Array, serializing it and saving it to a file on the main server (the one all should sync to) and then on the other servers, downloading the file, unserializing it and item by item, checking if it is in the DB, and if not inserting it. The insert is failing. I have tried building an sql query for each item and doing $this->conn->Execute(); and that is failing row by row on silly things, so I am now trying this:
function syncCMS()
{
$this->output['msg'] .= "<p><b>The following properties were added to the database on ." . $this->hsite . "</b></p>";
$this->get_field_names();
$this->make_connection(); //assigns connection to $this->conn
$rs = new COM('ADODB.Recordset');
$rs->CursorType = 2;
$rs->CursorLocation = 1;
$rs->LockType = 4;
$rs->Open($this->table_name,$this->conn);
foreach ($this->awayPropertyDetails as $key => $property)
{
$this->check_for_property($property['pname']);
if (!$this->property_exists || $this->mode == "fullSync")
{
unset($values);
$bfields = array("pshow","rent","best", "oda1", "oda2", "oda3", "oda4", "oda5", "oda6", "odap", "topool","tomountain","tofitness","tosauna"); //stores the yes/no values
$q = "INSERT INTO " . $this->table_name . " (" . $this->dbfields . ") VALUES (";
foreach ($property as $k => $value)
{
if ($k == "Kimlik") {
$value = null;
}
if ($k == "tarih")
{
$value = date("d/m/Y");
$value = "'" . $value . "'";
}
if (in_array($k,$bfields))
{
if ($value == "")
{
$value = 'FALSE';
}
else
{
$value = 'TRUE';
}
}
$rs->fields->$k = $value;
$this->output['msg'] .= $property['pname'] . " added";
}
$rs->BatchUpdate();
$rs->Close();
$this->conn->Close();
//$this->download_images($property['OBJECT_NR'],$k);
//$this->output['msg'] .= "<p>Images added</p>";
}
}
$message .= "</ul>";
$this->output['msg'] .= $message;
$this->sendOutput();
//print_r($property);*/
}
And getting this:
Fatal error: Uncaught exception 'com_exception' with message 'Unable to lookup `Kimlik': Unknown name. ' in D:\inetpub...
Kimlik is the name of the first field, the Auto Number field, I took it out and the problem shifted to the second field.

I got there with:
$sql = "SELECT * FROM " . $this->table_name;
if (!$this->property_exists || $this->mode == "fullSync")
{
$this->make_connection();
$rs->Open($sql,$this->conn);
$rs->addnew();
foreach($rs->Fields as $field)
{
if ($field->name != "Kimlik")
{
$rs->Fields[$field->name] = $property[$field->name];
}
}
$rs->Update();
$rs->Close();
$this->conn->Close();
$msg = $this->download_images($property['OBJECT_NR'],$k);
$this->output['msg'] .= $property['pname'] . " added<br/>" . $msg . "<br/><br/>";
}

Related

How to compare data from two tables

I have two database (mysql) with the same structure. I want to:
compare data in two table. Table one - home and the second work,
send email with results,
update data in table work.
My query:
select id, code, quantity from wpx_products
I run this query in table home and work (two databases). And this is output:
"3";"home 005-07";"2"
"63";"home 033-12";"2"
"15";"home 005-19";"2"
and from work:
"1";"work 005-07";"2"
"2";"work 033-12";"5"
"3";"work 005-19";"2"
What I want to do ? What I mean by "compare" ? I want find record with excluding tag work or home in column 'code'. For example I want to find 033-12 and check quantity. If the difference copy value from home to work.
In first second I want to use trigger in mysql. But this is not solution for me because I cant run it by myself and I can't send email with results. What is the best way to achieve this functionality ? Thanks for help.
Kind regards
---------------------edit----------------------------
I check this code below (thanks #AntG). And I have one problem. When I print
foreach ($result_target AS $target) {
$code_target = substr($target['code'], 4);
if ($code_source === $code_target) {
if ($source['quantity'] !== $target['quantity']) {
print $source['quantity'] .' -> ' . $target['quantity']."<br /><br />";
$match[] = array('code' => $source['code'], 'quantity' => $source['quantity'], 'targetid' => $target['id'], 'sourceid' => $source['id']);
}
$found = true;
break;
}
}
I have this results: http://suszek.info/projekt1/ Like You see there is 50 values. When I print $match there is much more, duplicated value and I don't know why ?
$msg = '';
foreach ($match AS $entry) {
$msg .= 'Change identified: Home_ID=' . $entry['sourceid'] . ' code: ' . $entry['code'] . ' quantity:' . $entry['quantity'] . PHP_EOL . '<br />';
print $msg;
/* Perform DB updates using $entry['targetid'] and $entry['quantity'] */
}
I have this results: http://suszek.info/projekt1/index_1.php And all code:
$match = array(); $new = array();
foreach ($result_source AS $source) {
$found = false;
$code_source = substr($source['code'], 4);
foreach ($result_target AS $target) {
$code_target = substr($target['code'], 4);
if ($code_source === $code_target) {
if ($source['quantity'] !== $target['quantity']) {
print $source['quantity'] .' -> ' . $target['quantity']."<br /><br />";
$match[] = array('code' => $source['code'], 'quantity' => $source['quantity'], 'targetid' => $target['id'], 'sourceid' => $source['id']);
}
$found = true;
break;
}
}
if (!$found) {
$new[] = array('code' => $source['code'], 'quantity' => $source['quantity'], 'sourceid' => $source['id']);
} } $msg = ''; foreach ($match AS $entry) {
$msg .= 'Change identified: Home_ID=' . $entry['sourceid'] . ' code: ' . $entry['code'] . ' quantity:' . $entry['quantity'] . PHP_EOL
. '<br />';
print $msg;
/* Perform DB updates using $entry['targetid'] and $entry['quantity'] */ }
foreach ($new AS $entry) {
$msg .= 'New Entry: Home_ID=' . $entry['sourceid'] . ' code: ' . $entry['code'] . ' quantity:' . $entry['quantity'] . PHP_EOL . '<br
/>';
#print $msg;
/* Perform DB inserts using $entry['code'] and $entry['quantity'] if this is desired behaviour */ }
/* Send email with $msg */
If you are capturing both query results in a $results array, then I think substr() is the PHP function that you are after here:
$match=array();
$new=array();
foreach($results_home AS $home)
{
$found=false;
$code=substr($home['code'],5);
foreach($results_work AS $work)
{
if($code===substr($work,5))
{
if($home['quantity']!==$work['quantity'])
{
$match[]=array('code'=>$home['code'],'quantity'=>$home['quantity'],'workid'=>$work['id'],'homeid'=>$home['id']);
}
$found=true;
break;
}
}
if(!$found)
{
$new[]=array('code'=>$home['code'],'quantity'=>$home['quantity'],'homeid'=>$home['id']);
}
}
$msg='';
foreach($match AS $entry)
{
$msg.='Change identified: Home_ID='.$entry['homeid'].' code: '.$entry['code'].' quantity:'.$entry['quantity'].PHP_EOL;
/* Perform DB updates using $entry['workid'] and $entry['quantity'] */
}
foreach($new AS $entry)
{
$msg.='New Entry: Home_ID='.$entry['homeid'].' code: '.$entry['code'].' quantity:'.$entry['quantity'].PHP_EOL;
/* Perform DB inserts using $entry['code'] and $entry['quantity'] if this is desired behaviour */
}
/* Send email with $msg */

Uncaught exception 'PDOException' with message 'SQLSTATE[HY093]: Invalid parameter number'

I'm receiving an error whenever I attempt to insert into my database using PDO.
public function save($primaryKey = "") {
$validate = $this->rules();
if ($validate === true) {
$properties = '';
$values = '';
$bindings = array();
$update = '';
foreach ($this as $property => $value){
if ($property === "conn") {
continue;
}
$properties .= $property . ',';
$values .= ':' . $property . ',';
$update .= $property . ' = :' . $property . ',';
$bindings[':'.$property] = $value;
}
$sql_string = 'INSERT INTO ' . get_class($this) . ' (' . rtrim($properties, ',') . ') ';
$sql_string .= 'VALUES (' . rtrim($values, ',') . ') ON DUPLICATE KEY UPDATE ' . rtrim($update, ',') . ';';
$result = $this->executeQuery(NULL, $sql_string, $bindings);
$this->buildObject($result);
if (!empty($primaryKey)) {
$this->$primaryKey = $this->conn->lastInsertId();
}
return $result;
} else {
return $validate;
}
}
public function executeQuery($object, $sql_string, $bindings = null) {
$stmt = $this->conn->prepare($sql_string);
if (!empty($bindings)) {
if (!$stmt->execute($bindings)) {return false;}
} else {
if (!$stmt->execute()) {return false;}
}
$result = (!empty($object) ? $stmt->fetchAll(PDO::FETCH_CLASS, $object) : $stmt->fetchAll());
return (($stmt->rowCount() > 0) ? $result : false);
}
The save function generates both the query string and the bindings which both seem correct.
query = INSERT INTO am_administrator (firstName,lastName,username,password,email,isSuperUser,dateCreated,dateLastModified) VALUES (:firstName,:lastName,:username,:password,:email,:isSuperUser,:dateCreated,:dateLastModified) ON DUPLICATE KEY UPDATE firstName = :firstName,lastName = :lastName,username = :username,password = :password,email = :email,isSuperUser = :isSuperUser,dateCreated = :dateCreated,dateLastModified = :dateLastModified;
bindings = array(8) {
[":firstName"]=> string(5) "First"
[":lastName"]=> string(4) "Last"
[":username"]=> string(7) "cova-fl"
[":password"]=> string(8) "password"
[":email"]=> string(16) "test#testing.com"
[":isSuperUser"]=> int(1) "1"
[":dateCreated"]=> string(19) "2016-05-11 02:40:15"
[":dateLastModified"]=> string(19) "2016-05-11 02:40:15"
}
Whenever I put the query into workbench I have no problems, but when trying to run it in code I get Fatal Error: Uncaught exception 'PDOException' with message 'SQLSTATE[HY093]: Invalid parameter number' which confuses me since the number of bindings params matches the bindings keys and nummbers. Can anyone enlighten me on this issue?
I think this might be because you have decared each binding twice in the statement e.g. :firstname appears in the VALUES clause as well as the ON DUPLICATE KEY UPDATE clause.
You only pass 8 bindings to the $stmt->execute but PDO is looking for 16.
You could try naming them slightly different in the ON DUPLICATE KEY UPDATE clause giving you a query such as e.g.
INSERT INTO am_administrator (firstName,lastName,username,password,email,isSuperUser,dateCreated,dateLastModified) VALUES (:firstName,:lastName,:username,:password,:email,:isSuperUser,:dateCreated,:dateLastModified) ON DUPLICATE KEY UPDATE firstName = :update_firstName,lastName = :update_lastName,username = :update_username,password = :update_password,email = :update_email,isSuperUser = :update_isSuperUser,dateCreated = :update_dateCreated,dateLastModified = :update_dateLastModified;

How to get attribute values of an object stored in $_SESSION?

I have this code that store a "student" object in $_SESSION:
if(isset($_POST["name"]) && isset($_POST["note"]) && isset($_POST["year"]))
{
$nom = $_POST["name"];
$note = $_POST["note"];
$session = $_POST["year"];
$vec = array("name" => $name, "note" => $note, "year" => $year);
$_SESSION["students"][] = $vec;
echo "The student has been added.<br><br>";
}
Then I have this code in another page:
function calculateAverage()
{
$av = 0;
$count = 0;
foreach($_SESSION['students'] as $student)
{
$av = $av + $student["note"];
$count = $count + 1;
}
return $av / $count;
}
function bestNote()
{
//$best = array_search(max())
return $best;
}
function worstNote()
{
$worst = min(array_search(["note"], $_SESSION['students']));
return $worst;
}
if(isset($_SESSION['students']))
{
echo "The average note of the group is = " . calculateAverage() . "\n";
echo "The one with the best note is " . bestNote()["name"] . " is " . hauteNote()["note"] . " points.\n";
echo "The one with the worst note is " . worstNote()["name"] . " with " . basseNote()["note"] . " points.\n";
}
As you can see, it is not finished. What I want to do is to be able to get the note of a student that is stored in $_SESSION["students"]. How can I do this?
Thanks for answers.
you can access the stored values within a nested array like so:
$studentNote = $_SESSION["students"][YourActiveStudent]["note"];
However, you are currently not adding but overwriting data. Use array_push() to add data to an array (your students).
And when adding a student to the array, make sure to give it a name to make it associative so you can simply "call a student":
$_SESSION["students"][$nom] = $vec;
this way, if the $nom was "Max", you could say
$_SESSION["students"]["Max"]["note"]
to get Max's note (BTW, I assume you are talking about grades or marks, rather than notes?)

ADOdb and null fields

I'm using the last version of ADOdb PHP (5.18) to make some queries in a SQL Server database.
I select data in this way:
$rS = $localDb->Execute($sql);
if (!$rS) {
echo "Error: " . $localDb->ErrorMsg() . "\n";
}
else {
$tot = $rS->RecordCount();
echo " " . $tot . " record da inserire...\n";
while (!$rS->EOF) {
$id = $rS->fields['id'];
$field1 = $rS->fields['field1'];
$field2 = $rS->fields['field2'];
$rS->MoveNext();
}
}
All works, and I fetch data, but when a field in the database's current row is NULL, the relative element in $rS->fields has the value of the value of the last not-NULL row for the same field.
This is a big problem because I don't have correct data in the current row.
I tried search for this problem but I did not find any solution.
Coud you help me, please?
Look into adodb5/adodb.inc.php and find the GetRowAssoc function. It should be the following defintion:
function GetRowAssoc($upper=ADODB_ASSOC_CASE_UPPER)
{
$record = array();
if (!$this->bind) {
$this->GetAssocKeys($upper);
}
foreach($this->bind as $k => $v) {
if( array_key_exists( $v, $this->fields ) ) {
$record[$k] = $this->fields[$v];
} elseif( array_key_exists( $k, $this->fields ) ) {
$record[$k] = $this->fields[$k];
} else {
# This should not happen... trigger error ?
$record[$k] = null;
}
}
return $record;
}

php script executes but no output

I have gone through all the similar questions and nothing fits the bill.
I am running a big script, which ran on chron on an old server but failed on the new so I am working on and testing in browser.
I have two functions, one pulls properties from the database, and then runs them through another which converts the price into 4 currencies, and if the value is different updates the row. The functions are as follows:
<?php
function convert_price($fore_currency, $aft_currency, $amount)
{
echo "going into convert<br/>";
$url = "http://www.currency.me.uk/remote/ER-ERC-AJAX.php?ConvertFrom=" . $fore_currency .
"&ConvertTo=" . $aft_currency . "&amount=" . $amount;
if (!is_int((int)file_get_contents($url))) {
//echo "Failed on convert<br/>";
return false;
} else {
//echo "Conversion done";
return (int)file_get_contents($url);
}
}
function run_conversion($refno = '', $output = false)
{
global $wpdb;
$currencies = array("GBP", "EUR", "TRY", "USD");
$q = "SELECT * FROM Properties ";
$q .= (!empty($refno)) ? " WHERE Refno='" . $refno . "'" : "";
$rows = $wpdb->get_results($wpdb->prepare($q), ARRAY_A);
$currencies = array("USD", "GBP", "TRY", "EUR");
//$wpdb->show_errors();
echo "in Run Conversion " . "<br/>";
foreach ($rows as $row) {
echo "In ROw <br/>";
foreach ($currencies as $currency) {
if ($currency != $row['Currency'] && $row['Price'] != 0) {
$currfield = $currency . "_Price";
$newprice = convert_price($row['Currency'], $currency, $row['Price']);
echo "Old Price Was " . $row['Price'] . " New Price Is " . $newprice . "<br/>";
if ($newprice) {
if ($row[$currfield] != $newprice) {
$newq = "UPDATE Properties SET DateUpdated = '" . date("Y-m-d h:i:s") . "', " .
$currfield . "=" . $newprice . " WHERE Refno='" . $row['Refno'] . "'";
$newr = $wpdb->query($newq);
if ($output) {
echo $newq . " executed <br/>";
} else {
echo "query failed " . $wpdb->print_error();
}
} else {
if ($output) {
echo "No need to update " . $row['Refno'] . " with " . $newprice . "<br/>";
}
}
} else {
echo "Currency conversion failed";
}
}
}
}
}
?>
I then run the process from a seperate file for the sake of chron like so:
require($_SERVER['DOCUMENT_ROOT'] . "/functions.php"); // page containing functions
run_conversion('',true);
If I limit the mysql query to 100 properties it runs fine and I get all the output in a nice stream. But when I try to run it in full the script completes (I can see from rows updated in db) but no output. I have tried upping the memory allowance but no joy. Any ideas gratefully received. Also, I get a 500 error when changing from Apache Module to CGI. Any ideas on that also well received as ideally I would like to turn site onto fastCGI.
You're running out of memory most likely. Probably in your DB layer. Your best bet is to unset your iterative values at the end of each loop:
foreach ( $rows as $row ) {
...
foreach ( $currencies as $currency ) {
...
unset( $currency, $newr, $currfield, $newprice );
}
unset( $row );
}
This will definitely help.
As another answer suggests you may be running out of memory, but if you make an HTTP call everytime the loop is running, and you have 100+ currencies, this may also cause the problem. Try limit it to 5 currencies for example.
If this is indeed the problem I would split the process, so a chunk of currencies have their respective value updated per cron job, instead of everything.

Categories