Perl-скрипт, обращающийся к mysql, проверяет, существуют ли уже 3 поля вместе

0

У меня есть следующий Perl script, я бы хотел, чтобы он проверял, являются ли поля имени, уровня и области объединенными уникальными ссылками. Если уже есть вход, подходящий для этих полей, игнорируйте его и ничего не делайте. Если в этой спецификации нет записи, добавьте ее.

Это работает, но не проверяет, есть ли уже уникальная запись и добавляет без рассмотрения

#! /usr/bin/perl -w
use DBI;
use DBD::mysql;
use Data::Dumper;
# MySQL Variables

my ($username, $password, $db, $login_info);
$username=""; #omitted
$password=""; #omitted
$db=''; #omitted
$table=''; #omitted
$dbh=DBI->connect("dbi:mysql:$db", $username, $password) or die "Connection Error: $DBI::errstr\n";

    my $insert=$dbh->do("INSERT INTO $table (area, name, level, align, hp, maxhp, bash, pierce, slash, acid, air, cold, disease, earth, fire, holy, light, electric, magic, mental, negative, poison, shadow, sonic, water) VALUES ('$ARGV[0]', '$ARGV[1]', '$ARGV[2]', '$ARGV[3]', '$ARGV[4]', '$ARGV[5]', '$ARGV[6]', '$ARGV[7]', '$ARGV[8]', '$ARGV[9]', '$ARGV[10]', '$ARGV[11]', '$ARGV[12]', '$ARGV[13]', '$ARGV[14]', '$ARGV[15]', '$ARGV[16]', '$ARGV[17]', '$ARGV[18]', '$ARGV[19]', '$ARGV[20]', '$ARGV[21]', '$ARGV[22]', '$ARGV[23]', '$ARGV[24]');");

Следующей была моя попытка сделать проверку, которая потерпела неудачу. Любая помощь будет оценена.

#! /usr/bin/perl -w

use DBI;
#! /usr/bin/perl -w

use DBI;
use DBD::mysql;
use Data::Dumper;
# MySQL Variables

my ($username, $password, $db, $login_info);
$username=""; #omitted
$password=""; #omitted
$db=''; #omitted
$table=''; #omitted
$dbh=DBI->connect("dbi:mysql:$db", $username, $password) or die "Connection Error: $DBI::errstr\n";
my ($area, $name, $level) = ($ARGV[1], $ARGV[1], $ARGV[2]);

my $query=$dbh->prepare("SELECT name, area, level from Interrogate WHERE name=$name, area=$area, level=$level;");
$do=$query->execute(  );
if ($do) { 
    my $insert=$dbh->do("INSERT INTO $table (area, name, level, align, hp, maxhp, bash, pierce, slash, acid, air, cold, disease, earth, fire, holy, light, electric, magic, mental, negative, poison, shadow, sonic, water) VALUES ('$ARGV[0]', '$ARGV[1]', '$ARGV[2]', '$ARGV[3]', '$ARGV[4]', '$ARGV[5]', '$ARGV[6]', '$ARGV[7]', '$ARGV[8]', '$ARGV[9]', '$ARGV[10]', '$ARGV[11]', '$ARGV[12]', '$ARGV[13]', '$ARGV[14]', '$ARGV[15]', '$ARGV[16]', '$ARGV[17]', '$ARGV[18]', '$ARGV[19]', '$ARGV[20]', '$ARGV[21]', '$ARGV[22]', '$ARGV[23]', '$ARGV[24]');");
}

EDIT Удалена посторонняя фигурная скобка.

Теги:
database

2 ответа

0
Лучший ответ

Кажется, вы смущены тем, что возвращает execute, из точное руководство:

При ошибке возникает символ undef. Успешное выполнение всегда возвращает true независимо от количества затронутых строк, даже если оно равно нулю (см. Ниже).
[...]
Метод execute не возвращает количество строк, которое будет возвращено запросом (поскольку большинство баз данных не могут сказать заранее), он просто возвращает истинное значение.

Итак, вы хотите сделать что-то вроде этого:

my $query = $dbh->prepare("SELECT COUNT(*) FROM Interrogate WHERE name = ? AND area = ? AND level = ?");
$query->execute($name, $area, $level);
my $count = $query->fetchrow_arrayref();
if(!$count->[0]) {
   # do the insert
}

Я бросил заполнители (чтобы защитить от SQL-инъекций) и исправил синтаксис предложения WHERE бесплатно.

Еще лучше было бы поместить уникальный уникальный индекс в (имя, область, уровень) внутри базы данных. Тогда вы могли бы просто сделать INSERT и ловушку и игнорировать исключение "уникальное ограничение, нарушенное". Этот подход защищает вас от состояния гонки в вашем подходе: вы проверяете существующую строку, но не находите ее, другой процесс добавляет строку, вы добавляете строку, но в итоге дублируете, потому что кто-то другой вставил ее между вашей проверкой и вашим вставить. Нажатие проблем с целостностью данных в базу данных всегда является лучшим выбором, базы данных хороши в таких вещах.

  • 0
    Это не делает вставку независимо от того, существуют поля или нет
  • 0
    У меня была логика if задом наперед, извините за это. Имеет ли это смысл сейчас?
Показать ещё 10 комментариев
0

вместо if ($do) Вам не нужно проверять возвращаемый номер (что-то вроде this)? И попробуйте этот оператор sql вместо SELECT name, area, level from Interrogate WHERE name=$name AND area=$area AND level=$level; (используйте AND в предложении where)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню