如何在将行导入mySQL之前检查某个值是否唯一?

时间:2010-10-19 22:34:43

标签: mysql joomla-extensions

我有一个数据库表,我需要将一堆记录导入。如果现有记录已经在数据库中,我不想覆盖现有记录,所以我先设置一个选择查询来检查是否有值,但显然行的导入速度太快跟上,因为我正在为我插入的每一行创建重复项。

我正在导入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)的字段实际上并不是主键,或者在表结构中以任何方式标记为唯一,并且不可能。这是我们现在需要在编码端解决的问题。

2 个答案:

答案 0 :(得分: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中插入数据吗?

答案 1 :(得分:0)

如果您确实无法更改表,则可能必须检查重复项并在INSERT后删除它们,或者在检查现有行之前锁定表。您无法保证SELECT和INSERT语句之间不会发生INSERT。