Как мне обновить записи, только если я найду дубликат или иным образом вставлю данные? - PullRequest
0 голосов
/ 27 июля 2010

В приведенном ниже коде есть хеш, содержащий записи с полями, такими как name, pid, type и time1.pid и name являются повторяющимися полями, которые содержат дубликаты.

Я обнаружил дубликат, обновите поля, которые необходимо изменить, иначе вставьте, здесь name и pid имеют дубликаты (повторяющиеся поля).

Остальные уникальны.Также у меня есть уникальное поле при создании таблицы Serial no.Как мне идти дальше?Я сделал только вставку в этот код.Я не знаю, как сохранить извлеченную запись в массив с помощью Perl.Пожалуйста, ведите меня.

for my $test11 (sort keys %seen) {
    my $test1 = $seen{$test11}{'name'};
    my $test2 = $seen{$test11}{'pid'};
    my $test3 = $seen{$test11}{'type'};
    my $test4 = $seen{$test11}{'time1'};

    print "$test11\t$test1$test2$test3$test4\n";

    $db_handle = &getdb_handle;
    $sth       = $dbh->prepare("Select username,pid,sno from svn_log1");
    $sth->execute() or die "SQL Error: $DBI::errstr\n";
    my $ref = $sth->fetchall_arrayref();
    print "hai";
    print "****$ref";
    $sth = $dbh->prepare("INSERT INTO svn_log1 values('$sno','$test11','$test1','$test4','$test2','$test3')");
    $sth->execute() or die "SQL Error: $DBI::errstr\n";
}

Ответы [ 3 ]

2 голосов
/ 27 июля 2010

Вы хотите вставить некоторые данные, но если они существуют, то обновить существующую строку?

Как вы проверяете, что данные уже существуют в базе данных? Вы используете имя пользователя и pid?

Если это так, вам может понравиться изменение структуры вашей базы данных: ALTER TABLE svn_log1 ADD UNIQUE (username, pid);

Это создает составной и уникальный индекс для username и pid. Это означает, что каждая комбинация имя пользователя / pid должна быть уникальной.

Это позволяет вам делать следующее:

INSERT INTO svn_log1 (username, pid, ...) VALUES (?, ?, ...) ON DUPLICATE KEY UPDATE time = NOW();

2 голосов
/ 27 июля 2010

Я думаю , что вы пытаетесь сказать, что вы не хотите пытаться вставить некоторые данные, если у вас уже есть эта комбинация имя / pid в базе данных, но я не могу сказать,Поэтому я не могу вам помочь.

Однако, вот несколько вещей, которые могут прояснить ваш код.Сначала выберите разумные имена переменных.Во-вторых, всегда, всегда, всегда используйте заполнители в ваших операторах SQL для их защиты:

for my $test11 ( sort keys %seen ) {
    my $name  = $seen{$test11}{'name'};
    my $pid   = $seen{$test11}{'pid'};
    my $type  = $seen{$test11}{'type'};
    my $time1 = $seen{$test11}{'time1'};

    my $dbh = getdb_handle();
    my $sth = $dbh->prepare("Select username,pid,sno from svn_log1");
    $sth->execute() or die "SQL Error: $DBI::errstr\n";
    my $ref = $sth->fetchall_arrayref();
    # XXX why are we fetching this data and throwing it away?

    $sth = $dbh->prepare("INSERT INTO svn_log1 values(?,?,?,?,?,?)");
    $sth->execute( $sno, $test11, $name, $time1, $pid, $type )
      or die "SQL Error: $DBI::errstr\n";
}

Предполагая, что вы не хотите что-то вставлять в базу данных, если есть "$ name" и "$ pid"и некоторая очистка, чтобы избежать подготовки одного и того же SQL снова и снова):

my $dbh = getdb_handle();
my $seen_sth   = $dbh->prepare( "Select 1 from svn_log1 where username = ? and pid = ?");

# This really needs to be "INSERT INTO svnlog1 (@columns) VALUES (@placeholders)
my $insert_sth = $dbh->prepare("INSERT INTO svn_log1 values(?,?,?,?,?,?)");
for my $test11 ( sort keys %seen ) {
    my $name  = $seen{$test11}{'name'};
    my $pid   = $seen{$test11}{'pid'};
    my $type  = $seen{$test11}{'type'};
    my $time1 = $seen{$test11}{'time1'};

    $seen_sth->execute($name, $pid) or die "SQL Error: $DBI::errstr\n";
    my @seen = $seen_sth->fetchrow_array;
    next if $seen[0];

    $insert_sth->execute( $sno, $test11, $name, $time1, $pid, $type )
      or die "SQL Error: $DBI::errstr\n";
}

Это не совсем так, как я бы написал, но это довольно ясно.Я подозреваю, что это не совсем то, что вы хотите, но я надеюсь, что это приблизит вас к решению.

1 голос
/ 27 июля 2010

Что это за база данных?

Мне кажется, что вы хотите запрос UPDATE или INSERT, более известный как запрос UPSERT.

Если это PostgreSQL, вы можете создать upsert функцию для обработки того, что вам нужно.См. комментарии для достойного примера.В противном случае, поиск переполнения стека для «upsert», и вы должны найти то, что вам нужно.

...