В приведенном ниже коде есть хэш, содержащий записи с полями, такими как name
, pid
, type
и time1
.
pid
и name
являются повторяющимися полями, которые содержат дубликаты.
Я дублирую найденное обновление полей, которые нуждаются в модификации
else insert, здесь 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";
}
Вы хотите вставить некоторые данные, но если они существуют, обновите существующую строку?
Как вы проверяете, что данные уже существуют в базе данных? Используете ли вы имя пользователя и 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();
Я думаю, что вы пытаетесь сказать, что вы не хотите пытаться вставить некоторые данные, если у вас уже есть эта комбинация имени /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";
}
Это не совсем так, как я бы это написал, но это довольно ясно. Я подозреваю, что это не совсем то, что вы хотите, но я надеюсь, что это приблизит вас к решению.
Какая база данных?
Я чувствую, что вам нужен запрос UPDATE
или INSERT
, более известный как запрос UPSERT
.
Если это PostgreSQL, вы можете создать функцию UPSERT
для обработки того, что вам нужно. См. комментарии для достойного примера. В противном случае найдите "Переполнение стека" для "upsert", и вы должны найти то, что вам нужно.