当存在唯一约束错误时如何继续插入

时间:2015-10-29 02:13:00

标签: sql perl

create table abc
(
  IMSI   VARCHAR2(20) not null,
  STATUS number(5),
  dateval number
)
ALTER TABLE abc
ADD CONSTRAINT abc_pk PRIMARY KEY (IMSI, STATUS)

select * from abc

IMSI    STATUS  DATEVAL

123 2   20151001

234 0   20151001

1234    2   20151001

我有一个csv文件,数据是:

789,2
1234,0
234,0

输出应该是:

IMSI    STATUS  DATEVAL

123 2   20151001

234 0   20151001

1234    2   20151001

789     2   20151001

1234   0    20151001

在perl中,我写了一段代码:

my %$hash;
my $startDate = "20151001";

my $sql = qq{select IMSI,status from abc};
    my $sqlHLD = $DB->prepare($sql);

    $sqlHLD->execute();
#storing the values already exist in the table
   while(my ($IMSIvalue,$status) = $sqlHLD->fetchrow_array())
    {
       $hash{$IMSIvalue}{IMSI} = $IMSIvalue;
       $hash{$IMSIvalue}{status} = $status;

    }
    ##Insert fresh list into table.and checks whether IMSI exists in table
    my $skip =0;

    my $Loaddatainsertsql = $DB->prepare("INSERT INTO abc VALUES (?,?,?)");

    while (<CSVFILE>)
    {

        $line = $_;
        ($field1,$field2)=split(/,/,trim($line));
        if(($hash{$field1}{IMSI} ne $field1) and ($hash{$field1}{status} ne $field2))
        {
            $Loaddatainsertsql->execute ($field1,$field2,$startDate);
        }
        elsif(($hash{$field1}{IMSI} eq $field1) and ($hash{$field1}{status} eq $field2))
        {
            $skip =1;##Failing condition

        }
        elsif(($hash{$field1}{IMSI} eq $field1) and ($hash{$field1}{status} ne $field2))
        {
            $Loaddatainsertsql->execute ($field1,$field2,$startDate);
        }
    }
}
if ($DBI::errstr)
{
    $DB->rollback();
}
else
{
    $DB->commit();
}

任何人都可以帮我如何插入其他行

2 个答案:

答案 0 :(得分:1)

use strict;
use warnings;

# assuming DBI->connect() and open(CSVFILE) happens up here...

my $startDate = '20151001';
my %unique;

my $sth = $DB->prepare(q{select imsi, status from abc});
$sth->execute;

while (my $row = $sth->fetch) {
    my $key = join('~', @$row);
    $unique{$key} = 1;
}

$DB->{AutoCommit} = 0;
$DB->{RaiseError} = 1;

eval {
    $sth = $DB->prepare(q{insert into abc (imsi, status, dateval) values (?, ?, ?)});

    while (<CSVFILE>) {
        my ($imsi, $status) = split(/,/, trim($_));
        my $key = join('~', $imsi, $status);
        next if $unique{$key};

        $sth->execute($imsi, $status, $startDate);
    }

    $DB->commit;
};

if ($@) {
    eval { $DB->rollback; };
}

答案 1 :(得分:1)

您可以更改SQL。例如,如果您使用的是MySQL,那么查询应如下所示:

INSERT INTO abc VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE dateval = values(dateval)