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. 从缓冲区中删除所有已经在 arc_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 回答