2010-07-27 14 views
0

Dans le code ci-dessous, il y a un hachage qui contient des enregistrements avec des champs tels que name, pid, type et time1. pid et name sont des champs répétitifs qui contiennent des doublons.Comment mettre à jour des enregistrements uniquement si je trouve un doublon ou si j'insère des données?

Je duplique trouvé mise à jour les champs qui ont besoin de modification else insert, ici name et pid ont des doublons (champs répétitifs).

Les autres sont uniques. Aussi j'ai un champ unique en créant la table Serial no. Comment dois-je continuer? Je n'ai fait qu'une insertion dans ce code. Je ne sais pas comment stocker l'enregistrement récupéré dans un tableau en utilisant Perl. Guidez-moi s'il-vous-plaît.

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"; 
} 
+0

Je suis désolé, vous devez être plus clair ce que vous demandez. Votre exemple de code semble faire une boucle sur tous les enregistrements dans% seen, et pour _each record_ obtenir la table entière à partir de la base de données, puis ajouter un autre enregistrement. Cela n'a aucun sens pour moi. Je comprends que vous voulez attraper des doublons et faire quelque chose de différent avec eux, ce qui est mieux fait par un autre hachage ont les valeurs éventuellement dupliquées comme clé; mais je ne vois pas assez clairement ce que vous voulez faire pour vous donner une réponse. –

+0

$ db_hanlde == $ dbh? – vol7ron

+0

Voir aussi les questions précédentes http://stackoverflow.com/questions/3341145 et http://stackoverflow.com/questions/3334644 – daxim

Répondre

2

Je pense ce que vous essayez de dire est que vous ne voulez pas essayer d'insérer des données si vous avez déjà ce nom/combinaison pid dans la base de données, mais je ne peux pas dire , donc je ne peux pas t'aider là-bas.

Cependant, voici quelques éléments qui peuvent éclaircir votre code. D'abord, choisissez des noms de variables sensibles. En second lieu, toujours, toujours, toujours utiliser des espaces réservés dans vos instructions SQL pour les protéger:

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"; 
} 

En supposant que vous voulez pas insérer quelque chose dans la base de données si « $ name » et « $ pid » sont là (et quelques-uns nettoyage pour éviter la préparation de la même SQL sur et plus):

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"; 
} 

ce n'est pas tout à fait la façon dont je voulais écrire, mais il est assez clair. Je suppose que ce n'est pas vraiment ce que vous voulez, mais j'espère que cela vous rapproche d'une solution.

1

Quelle base de données est-ce? Je pense que vous voulez une requête UPDATE ou INSERT, plus communément appelée requête UPSERT.

Si c'est PostgreSQL, vous pouvez créer une fonction upsert pour gérer ce dont vous avez besoin. Voir le comments pour un exemple décent. Sinon, recherchez Stack Overflow pour "upsert" et vous devriez trouver ce dont vous avez besoin.

+0

C'est MySQL; voir les questions précédentes. – daxim

2

Vous souhaitez insérer des données, mais si elles existent, mettez à jour la ligne existante?

Comment vérifiez-vous que les données existent déjà dans la base de données? Utilisez-vous le nom d'utilisateur et le pid?

Si oui, vous pouvez aimer le changement de la structure de votre base de données: ALTER TABLE svn_log1 ADD UNIQUE (username, pid);

Ce créer un index composite et unique sur username et pid. Cela signifie que chaque combinaison nom d'utilisateur/pid doit être unique.

Cela vous permet d'effectuer les opérations suivantes:

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

+0

DBD :: mysql :: st execute a échoué: Vous avez une erreur dans votre syntaxe SQL; consultez le manuel qui correspond à votre version du serveur MySQL pour la bonne syntaxe à utiliser près de '13: 00: 44 (lun, 12 avr 2010), 21534, page d'information Loc) SUR DUPLICATE KEY UP 'à la ligne 1 de la ligne task_last.pl 60, ligne 17. – Sreeja

+0

Pouvez-vous publier la requête finale que vous essayez d'exécuter, et la structure de la table? – aidan

+0

Hey merci .. Son fonctionnement parfait maintenantwwwwwwwwww – Sreeja