0

一連のレコードをインポートする必要があるデータベース テーブルがあります。既存のレコードが既にデータベースにある場合は上書きしたくないので、最初に選択クエリを実行して値があるかどうかを確認するように設定しましたが、明らかに行のインポートが速すぎてインデックスが挿入する行ごとに重複が作成されるので、追いついてください。

CSVファイルをインポートしています。

これが私がやっていることです(これはJoomlaシステム内にあるため、コードとオブジェクトの一部はjoomla固有です):

$fp = fopen(JPATH_ROOT.DS."tmp".DS.$filename, 'r');
//run insert query on each line of file
if(JRequest::getVar('importType')=="activated") {
  while(!feof($fp)) {
       while (($data = fgetcsv($fp, 1000, ",")) !== FALSE) {
             if($this->checkUnique($data[0])) {
                    $this->runInsert2($data[0], $data[1], $data[2], $data[3]);
                    error_log("there is not already a code for ".$data[0]);
             }
             else {
                    error_log("there is already a code for ".$data[0]);
             }
       $row++;
       }
 }
}

fclose($fp);

ここにcheckUniqueがあります:

function checkUnique($vouchNum) {

        $db =& JFactory::getDBO();

        $query = "select COUNT(*)  from arrc_Voucher where VoucherNbr=".$db->quote($vouchNum);

        if(!$db->query()) error_log("error running unique check on ".$vouchNum." - " . $db->stderr());

        $db->setQuery($query);

        $count = $db->loadResult();

        if($count>0) {

            return false;

        }

        else {

            return true;

        }

    }

そして、ここにrunInsert2があります:

 function runInsert2($vouchNum,$BalanceInit,$BalanceCurrent,$ActivatedDT) {

    $rightNow = date('Y-m-d H:i:s');

    $db =& JFactory::getDBO();



            if($ActivatedDT <> "NULL") {

                $activatedDTtmp = strtotime($ActivatedDT);

                $activatedDT = date('Y-m-d H:i:s',$activatedDTtmp);

            }

            else {

                $activatedDT = $rightNow;

            }


    $query = "insert into arrc_Voucher (VoucherNbr,BalanceInit, BalanceCurrent, ActivatedDT) 
              values (". $db->quote($vouchNum). ", ".$db->quote($BalanceInit).",".$db->quote($BalanceCurrent).",".$db->quote($activatedDT).")";
    error_log("query: ".$query);

    $db->setQuery($query);

    if (!$db->query()) error_log("error inserting voucher number ". $vouchNum . "-" . $db->stderr());

}

ここでどこが間違っているのかわかりませんが、誰かが私を助けてくれれば (または、重複を避けるためのより良い方向に向けてくれれば)、とても感謝しています。参考までに、「一意」であると見なしているフィールド (VoucherNbr) は、実際には主キーではなく、テーブル構造で一意としてマークされているものでもありません。これは、コーディング側で今すぐ回避する必要があるものです。

4

2 に答える 2

2

一意の制約を設定して使用しinsert ignoreます。これにより、重複が発生することはありません。これは、重複する行を無視しても問題がない場合です。

一意の値を保持する必要があるよりも、列に一意のキーを設定できない理由は何ですか?

別の解決策は、同じ構造の別のテーブルにデータをインポートすることです。

create table arrc_buffer like arrc_Voucher

各インポートの前に、このテーブルを切り捨てます。

次に、このバッファからarrc_Voucherテーブルに挿入できます。

1.すでにarrc_Voucherにあるすべての行をバッファーから削除します。

delete arrc_buffer b
from arrc_buffer b
inner join arrc_Voucher v on b.VoucherNbr = v.VoucherNbr;

次に、残りをarrc_Voucherに挿入します。

insert into arrc_Voucher
select * from arrc_buffer

これらのインポートの他に、arrc_Voucherにデータを挿入するルーチンはありますか?

于 2010-10-20T09:03:43.227 に答える
0

本当にテーブルを変更できない場合は、重複をチェックしてINSERT後に削除するか、既存の行をチェックする前にテーブルをロックする必要があります。SELECTステートメントとINSERTステートメントの間にINSERTが発生しないことを保証することはできません。

于 2010-10-20T02:27:58.243 に答える