即使有条件和事件,数据也始终保持重复

时间:2018-09-25 10:21:44

标签: php mysql sql-server codeigniter cron

我有一个代码,可从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事件,也仍然存在重复项。这可能是什么问题?

0 个答案:

没有答案