Количество затронутых строк после вставки или игнорирования в

Код perl дает мне количество строк, затронутых как 1, хотя запись игнорируется оператором sql из-за PRIMARY KEY CONSTRAINT при вставке в базу данных sqlite с использованием модуля DBI.

my $stmt = 'INSERT OR IGNORE INTO table1 (ID, Name) VALUES (?,?)';
my $sth = $dbh->prepare($stmt);

$sth->bind_param( 1, $id, SQL_VARCHAR );
$sth->bind_param( 2, $name, SQL_VARCHAR );

my $row =  $sth->execute() or die $DBI::errstr;
print "Row affected for id[$id]- $row\n";

Он всегда дает мне $row как 1 для набора данных ниже, где ID & NAME являются составным первичным ключом.

ID   NAME
1    AAA
1    BBB
1    AAA
2    BBB
2    BBB

что-то не так я делаю здесь. Мне нужно выполнить другой раздел кода на основе значения 0f $row, которое равно 0 в случае IGNORE и 1 в случае INSERTION.

Есть ли другой способ справиться с этим?


person Preeti P    schedule 24.06.2014    source источник
comment
Связано: stackoverflow.com/questions/12105198/   -  person mob    schedule 24.06.2014
comment
Я поддержу рекомендацию @mob. Звучит глупо, но вам придется использовать вторую (временную) таблицу для хранения результатов из вашего INSERT OR IGNORE. Затем вы можете select * во 2-й таблице, и тогда вы сможете подсчитать строки, затронутые INSERT OR IGNORE.   -  person jimtut    schedule 24.06.2014
comment
Я не знаю о Perl, но везде, где я пробовал, SQLite правильно считает изменения. Покажите определение таблицы.   -  person CL.    schedule 25.06.2014
comment
@CL ты прав. Это больше связано с Perl, и SQL-запрос хорошо работает с базой данных.   -  person Preeti P    schedule 30.06.2014


Ответы (1)


use strict;
use warnings;
use 5.016;
use DBI;

my $h = DBI->connect("dbi:SQLite:db=x.db");
eval {
    $h->do(q/drop table test/);
};

$h->do(q/create table test (id integer, name varchar(10), constraint xx unique(id,name))/);

my $s = $h->prepare(q/insert or ignore into test values(?,?)/);
my @values = ([1, 'AAA'], [1, 'BBB'], [1, 'AAA'], [2, 'BBB'], [2, 'BBB']);
foreach (@values) {
    my $affected = $s->execute(@{$_});
    say join(",", @{$_}) . " = $affected";
}
$h->disconnect;

выходы

1,AAA = 1
1,BBB = 1
1,AAA = 0E0
2,BBB = 1
2,BBB = 0E0

для меня это выглядит правильно. Я использую DBI 1.631 и DBD::SQLite 1.42.

person bohica    schedule 25.06.2014
comment
Спасибо бохика. Этот код также работал для меня. Я не уверен, сделал ли я какой-либо беспорядок с обработкой ошибок. Я думаю, мне нужно снова проверить мой код. - person Preeti P; 30.06.2014