У меня есть код, который извлекает данные с сервера MSSQL и сохраняется в моей базе данных MySQL.Прежде чем разрешить сохранение в MySQL, данные MSSQL будут сопоставлены с ними, и, если они уже существуют, они будут удалены из массива.Последние оставшиеся данные в массиве - это те, которые будут сохранены в MySQL.
Вот одна функция, которая делает это: эта функция получает данные MSSQL и подготавливает окончательный массив для сохранения.Затем я верну массив в контроллер и сохраню его в другой функции модели.
function get_international_manifests(){
$query = "SELECT CAST(a.TransDate as DATE) AS TransDate, b.InvoiceNumber, b.OfficeCode, o.CountryCode, b.CustCountry, b.CustFName + ' ' + b.CustLName AS Sender,
b.BeneFName + ' ' + b.BeneLName AS Consignee, a.RecordID, CASE WHEN b.CustEmail1 IS NULL THEN b.CustEmail2 ELSE b.CustEmail1 END AS Email,
CASE WHEN b.CustPhone1 IS NULL THEN b.CustPhone2 ELSE b.CustPhone1 END AS Phone, a.StageID, b.ShippingType
FROM BoxesUpdateLog a JOIN Cargo_Transactions b ON a.InvoiceNumber=b.InvoiceNumber
LEFT JOIN [CARGODB].[dbo].[Cargo_Offices] o ON b.OfficeCode = o.OfficeCode
WHERE NOT EXISTS (SELECT InvoiceNumber, StageID, RecordID FROM [CARGODB].[dbo].[CQ_SMS_API] sms WHERE a.InvoiceNumber = sms.InvoiceNumber AND sms.StageID = 'LOADCNTNR' AND sms.RecordID = a.RecordID) AND a.StageID = 'LOADCNTNR' AND a.Deleted = 0
AND CAST(a.TransDate AS DATE) = CAST(GETDATE() as DATE) AND CASE WHEN b.CustPhone1 IS NULL THEN b.CustPhone2 ELSE b.CustPhone1 END IS NOT NULL
AND b.ShippingType = 'SEA'
AND o.CountryCode = 'US' AND CASE WHEN b.CustPhone1 IS NULL THEN b.CustPhone2 ELSE b.CustPhone1 END NOT LIKE '%[A-Z,a-z]%' AND LEN(CASE WHEN b.CustPhone1 IS NULL THEN b.CustPhone2 ELSE b.CustPhone1 END) >= 10 ORDER BY TransDate DESC";
$conn = $this->delphi_connect();
$rs = sqlsrv_query($conn,$query);
if (!$rs) { throw new Exception('Unable to connect to delphi');}
$row_count = sqlsrv_has_rows($rs);
if($row_count === true){
if ($rs) {
while ($row = sqlsrv_fetch_array($rs, SQLSRV_FETCH_ASSOC)) {
$ret[] = $row;
}
}
foreach($ret AS $ret_data){
$record_ids[] = $ret_data['RecordID'];
}
$imploded_record_ids = "'".implode("','", $record_ids)."'";
$check_query = "SELECT `record_id` FROM `cq_message_queue` WHERE `record_id` IN (".$imploded_record_ids.")"; // AND `Remarks` = 'LOADCNTNR'
$existing_record_id = $this->eli_db->query($check_query)->result_array();
$count_existing_record_id = count($existing_record_id);
if($existing_record_id && $count_existing_record_id > 0){
$rec_id_arr = array();
foreach($existing_record_id AS $existing_record_id_data){
$rec_id_arr[] = $existing_record_id_data['record_id'];
}
foreach($ret as $key => $record) {
if(in_array($record['RecordID'], $rec_id_arr)) {
unset($ret[$key]);
}
}
$ret = array_values($ret);
}
if(count($ret) > 0){
$ret['result'] = 'with_data';
} else if(count($ret) == 0){
$ret['result'] = 'no_data';
}
} else {
$ret['result'] = 'no_data';
}
sqlsrv_free_stmt($rs);
sqlsrv_close($conn);
return $ret;
}
Это функция, которая сохраняет массив в MySQL:
function save_to_queue($ret, $remarks){
set_time_limit(0); // Disable time limit to allow enough time to process a large dataset
$this->eli_db->select('record_id');
$this->eli_db->where('Remarks', $remarks);
$existing_record_id = $this->eli_db->get('cq_message_queue')->result_array();
if($existing_record_id){
$record_id_arr = array();
foreach($existing_record_id AS $existing_data){
$record_id_arr[] = $existing_data['record_id'];
}
//remove all data with equal record id's above
$start_count = 0;
$ret_count = count($ret);
if($record_id_arr){
$filtered = array_filter($ret, function($sql_data) use ($record_id_arr){
return !in_array($sql_data['RecordID'], $record_id_arr);
});
} else {
$filtered = 0;
}
} else {
$filtered = '';
}
if($filtered != '' && $filtered != 0){
$ret = array_values($filtered);
} else {
$ret = $ret;
}
$us_arr = array();
$us_arr_record_id = array();
if($ret){
foreach($ret AS $us_customers_data){
//check in order table if exists
$this->eli_db->select('u.sms_optin');
$this->eli_db->from('orders o');
$this->eli_db->where('o.BoxNumber', $us_customers_data['InvoiceNumber']);
$this->eli_db->join('users u','o.CustomerID = u.id','left');
$get_sms_optin = $this->eli_db->get()->row();
if(!$get_sms_optin){
//check in cq_order_items if exists
// /SELECT o.`CustomerID`,CASE WHEN o.`CustomerID` > 0 THEN 2 ELSE o.`sms_optin` END AS sms_optin FROM `cq_order_items` i LEFT JOIN `cq_orders` o ON i.`OrderID` = o.`ID` WHERE i.`BoxNumber` = 'WSX256480'
$this->eli_db->select('`o`.`CustomerID`,(CASE WHEN `o`.`CustomerID` > 0 THEN 2 ELSE `o`.`sms_optin` END) AS `sms_optin`');
$this->eli_db->from('cq_order_items i');
$this->eli_db->where('i.BoxNumber', $us_customers_data['InvoiceNumber']);
$this->eli_db->join('cq_orders o','i.OrderID = o.ID','left');
$cq_get_sms_optin = $this->eli_db->get()->row();
//if logged in
if($cq_get_sms_optin){
if($cq_get_sms_optin->CustomerID > 0 && $cq_get_sms_optin->sms_optin == 2){
$this->eli_db->select('sms_optin');
$this->eli_db->where('id', $cq_get_sms_optin->CustomerID);
$user_sms_optin = $this->eli_db->get('users')->row();
$sms_optin = intval($user_sms_optin->sms_optin);
//if guest
} else {
$sms_optin = intval($cq_get_sms_optin->sms_optin);
}
} else {
$sms_optin = intval(1);
}
} else {
$sms_optin = intval($get_sms_optin->sms_optin);
}
$mobile = preg_replace('/\D+/', '', $us_customers_data['Phone']);
if($us_customers_data['CustCountry'] != ''){
if(preg_match('/^(09|\+639)\d{9}$/', $us_customers_data['Phone']) || strtoupper($us_customers_data['CustCountry']) == 'PH')
{
$mobile = $this->format_ph_number($mobile);
$app = 'globe_api';
} else {
if(strtoupper($us_customers_data['CustCountry']) == 'US'){
$mobile = preg_replace('/\D+/', '', $us_customers_data['Phone']);
$mobile = $this->format_us_number($mobile);
}
$app = 'ringcentral_api';
}
} else {
if(preg_match('/^(09|\+639)\d{9}$/', $us_customers_data['Phone']))
{
$mobile = $this->format_ph_number($mobile);
$app = 'globe_api';
} else {
$mobile = preg_replace('/\D+/', '', $us_customers_data['Phone']);
$mobile = $this->format_us_number($mobile);
$app = 'ringcentral_api';
}
}
$date_to_use = date_create('now Etc/UTC');
$date_to_use_formatted = $date_to_use->format('Y-m-d H:i:s');
if($us_customers_data['StageID'] == 'TRANSITRCV' || $us_customers_data['StageID'] == 'ORGNSCN'){
$action = 'received';
$message = 'received in our Forex US warehouse. You may check the status here: http://forexcargo.us/trackmybox/';
} elseif ($us_customers_data['StageID'] == 'UNLOADED') {
$action = 'unloaded';
$message = "Your package ".html_escape($us_customers_data['InvoiceNumber'])." has arrived at our Manila warehouse for processing.\n\nFollow us on Facebook: https://www.facebook.com/forexcargoinc/";
} elseif ($us_customers_data['StageID'] == 'LOADCNTNR') {
$action = 'loaded international';
$message = "Your package ".html_escape($us_customers_data['InvoiceNumber'])." has been loaded for ocean transit.\n\nVisit forexcargo.us. Download our box pick-up/tracking app at forexcargo.us/upgrades";
}
/*
elseif ($us_customers_data['StageID'] == 'LOADEDLOCM') {
$action = 'loaded local';
$message = 'loaded for transit to the Philippines. You may check the status here: http://forexcargo.us/trackmybox/';
}
*/
elseif ($us_customers_data['StageID'] == 'D') {
$action = 'delivered';
$message = "Your package ".html_escape($us_customers_data['InvoiceNumber'])." has been delivered. Thank you for choosing Forex/eShip.\n\nFor future pickups, download our box pick-up/tracking app at forexcargo.us/upgrades";
}
if($app == 'ringcentral_api'){
if($mobile != '10000000000'){
$us_arr[]= array(
'FromApps' => $app,
'InvoicecNumber' => $us_customers_data['InvoiceNumber'],
'sender_name' => $us_customers_data['Sender'],
'sender_phone_number' => $mobile,
'sender_original_number' => $us_customers_data['Phone'],
/*
'consignee_name' => $us_customers_data['Consignee'],
'consignee_phone_number' => $mobile,
'consignee_original_number' => $us_customers_data['Phone'],
'To_' => $us_customers_data['Email'],
*/
'country_code' => $us_customers_data['CustCountry'],
'Subject' => 'Your Forex Box#'.html_escape($us_customers_data['InvoiceNumber']).' has been '.html_escape($action).'.',
'Message' => html_escape($message),
'DateCreated' => $date_to_use_formatted,
'CreatedBy' => 15,
'status' => 'queue',
'Remarks' => $us_customers_data['StageID'],
'record_id' => $us_customers_data['RecordID'],
'sms_optin' => html_escape($sms_optin)
);
$us_arr_record_id[] = $us_customers_data['RecordID'];
}
}
if($app == 'globe_api'){
if($mobile != '+630000000000'){
$us_arr[]= array(
'FromApps' => $app,
'InvoicecNumber' => $us_customers_data['InvoiceNumber'],
'sender_name' => $us_customers_data['Sender'],
'sender_phone_number' => $mobile,
'sender_original_number' => $us_customers_data['Phone'],
/*
'consignee_name' => $us_customers_data['Consignee'],
'consignee_phone_number' => $mobile,
'consignee_original_number' => $us_customers_data['Phone'],
'To_' => $us_customers_data['Email'],
*/
'country_code' => $us_customers_data['CustCountry'],
'Subject' => 'Your Forex Box#'.html_escape($us_customers_data['InvoiceNumber']).' has been '.html_escape($action).'.',
'Message' => html_escape($message),
'DateCreated' => $date_to_use_formatted,
'CreatedBy' => 15,
'status' => 'queue',
'Remarks' => $us_customers_data['StageID'],
'record_id' => $us_customers_data['RecordID'],
'sms_optin' => html_escape($sms_optin)
);
$us_arr_record_id[] = $us_customers_data['RecordID'];
}
}
}
У меня также есть этоСобытие, которое запускается каждую минуту в MySQL, чтобы убедиться, что дубликаты не сохраняются:
DELETE FROM cq_message_queue
WHERE record_id IN (SELECT * FROM (SELECT MIN(q.id) FROM cq_message_queue q WHERE q.FromApps IN('ringcentral_api','globe_api') GROUP BY q.record_id, q.sent_to, q.InvoicecNumber, q.Remarks) x)
Я несколько раз тестировал свой код в локальной системе, и он отлично работает.Но когда я установил его в cron, даже с событием MySQL, дубликаты все еще существуют.В чем может быть проблема для этого?