2017-09-20 6 views
0

それぞれ異なるサーバ上にある2つのデータベースに接続し、アップデートを実行するスクリプトを完成しようとしています。基本的に、テーブルの選択と挿入は同じです。先日、ダンプ/インポートを行いました。スクリプトは、ローカルのテーブルを遠隔から最新の状態に保つ必要があります。遠隔のレコードが毎日挿入され、ローカルに最新の状態に保つ必要があるからです。Refactor 2つのデータベースサーバ間でmysqlアップデートを行うPHPスクリプト

ここで重要な点は、テーブルが共有する自動インクリメントプライマリキーであるSESSIONIDを調べることで、リモートサーバー上の新しい行を決定することです。私はIDがローカルサーバーではなく、ローカルサーバーに存在する場合、これらのレコードをローカルサーバーに挿入すると、私のループは以下のようになります。

次のスクリプトをpowershellでphp 'filename'と入力して実行すると、正常な接続メッセージが得られますが、ハングアップします。約10分後にメモリエラーが発生したので、ini_set('memory_limit', '256M');を追加しました。その後、約10分間はハングしてしまい、MySQLサーバがなくなって結果のヘッダが見つからないとします。両方のエラーは、$rowCountが失敗したかどうかを確認する行で発生します。

注:この状況では、レプリケーションと大量のダンプ/インポート/テーブルの再作成はオプションではありません。この実行にはいくつかの同様のスクリプトがあり、ここでは同じプロセスを維持したいと考えています。私は単にこれらのエラーを解決するか、誰かに私がこのスクリプトをより効率的にコーディングする方法を教えてもらいたいと思っています。

がここにスクリプトです:

 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']."')"); 
        } 
     } 
+0

あなたはどこのSESSIONID> "$ Last_update_Record_sessionID"?のようなwhere節を試してから、更新のシングルショットクエリを使用してください(複数値の単一クエリ) –

+0

私は現在のルートを開始して行きました残念ながら、私はPHPがMySQLの領域を満たすのが初めてです。私は通常、これをSQLエディタ内で行います。 –

+0

どのように構造化すればよいでしょうか? –

答えて

3
// 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){ 

これは間違っています:クエリがfalseを返す場合、クエリが実行に失敗しました。代わりにif ($row_exists->num_rows == 0)をチェックする必要があります。あなたのコードは今や、すべてのレコードを繰り返し挿入します。 INSERTクエリでエラーをチェックしていないので、あなたはSESSIONID列の重複したエントリに遭遇している失敗に気づいていません(私はあなたのローカルデータベースのプライマリキー列であるとみなします)。

また、まだ持っていないセッションだけを選択すると、おそらくもっと速くなります。あなたは、自動増分列を操作しているので、あなたはかなりのローカル・データベースから最新のSESSIONID後に来たSESSIONIDと、リモート・データベースに何かが新規であると仮定することができます:MySQLで

//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"); 

テーブルは通常、何らかの理由でスクリプトが中断した場合のためにローカルデータベースにデータを挿入する順序が気になる場合は、明示的にORDER BY `SESSIONID` ASCをクエリに追加することができます。

+0

私はこれを実行して、私の質問でコードを更新しましたが、(変数名を修正した後で)さらにもう一つのエラーが発生します。私は ''あなたはあなたのSQL構文に誤りがあります。あなたのMySQLサーバのバージョンに対応するマニュアルをチェックしてください。正しい構文は、 '' at 60ps'''の近くで使用してください。どのように60PSのラインが分かっていますか? –

+0

"PS"がどこから来ているのか分かりませんが、おそらく60行目です。値をエスケープしていないので、おそらく、その列の1つに '' 'を持つセッションを挿入しようとしています。変数をクエリにドロップするのではなく、準備されたステートメントを使用してみてください。 – rickdenhaan

+0

私はそれを正確に行う方法を知らない。ここでも、PHPのほんの一部ではなく、もっとSQL側から来ています。しかし、代わりに値をエスケープする何かを実装できますか?行60は、クエリの挿入部分で、 '' 'VALUES''行の直前のカラム名の最後までです。 –

関連する問題