OVH Cloud OVH Cloud

retour erreur sur une requete perl sql ?

7 réponses
Avatar
Mylene Sigod
Bonjour,

J'utilise un simple:

@domains = split (/ /,$oridomains);
$domains = @domains[0];
$query = "INSERT INTO $categorie VALUES
(\'\',\'@domains[0]\',\'urls\');";
$sth = $dbh->prepare($query);
$sth->execute();

le $oridomains est lu a partir d'un fichier texte ..

Sur 1 000 000 de ligne environ j'ai quelques erreurs (une 20 ene)

ai je un moyen de dire a mon script que si la requete genere une erreur, il
me l'inscrive dans un fichier ? (qu'il me fasse un print OUTFILE
("$query\n"); par exemple

merci d'avance

7 réponses

Avatar
Yoann Wyffels
Salut,

$erreur=$sth->errstr;
if($erreur ne ""){ ..........}

Devrait te convenir.

++

"Mylene Sigod" a écrit dans le message de news:
417fa0dc$0$288$
Bonjour,

J'utilise un simple:

@domains = split (/ /,$oridomains);
$domains = @domains[0];
$query = "INSERT INTO $categorie VALUES
('','@domains[0]','urls');";
$sth = $dbh->prepare($query);
$sth->execute();

le $oridomains est lu a partir d'un fichier texte ..

Sur 1 000 000 de ligne environ j'ai quelques erreurs (une 20 ene)

ai je un moyen de dire a mon script que si la requete genere une erreur,
il
me l'inscrive dans un fichier ? (qu'il me fasse un print OUTFILE
("$queryn"); par exemple

merci d'avance





Avatar
Aurelien
print OUTFILE ("$queryn") if ($sth->err());

sera surement plus propre.
Il fait mieux éviter de tester une chaîne avec un
... ne ""

Faut vérifier aussi que DBI repositionne bien $sth->err() et
$sth->errstr à des valeurs correctes à chaque exécution de la execute().

Aurélien



Yoann Wyffels wrote:
Salut,

$erreur=$sth->errstr;
if($erreur ne ""){ ..........}

Devrait te convenir.

++

"Mylene Sigod" a écrit dans le message de news:
417fa0dc$0$288$

Bonjour,

J'utilise un simple:

@domains = split (/ /,$oridomains);
$domains = @domains[0];
$query = "INSERT INTO $categorie VALUES
('','@domains[0]','urls');";
$sth = $dbh->prepare($query);
$sth->execute();

le $oridomains est lu a partir d'un fichier texte ..

Sur 1 000 000 de ligne environ j'ai quelques erreurs (une 20 ene)

ai je un moyen de dire a mon script que si la requete genere une erreur,
il
me l'inscrive dans un fichier ? (qu'il me fasse un print OUTFILE
("$queryn"); par exemple

merci d'avance










Avatar
Patrick Mevzek
Faut vérifier aussi que DBI repositionne bien $sth->err() et
$sth->errstr à des valeurs correctes à chaque exécution de la execute().


Autant utiliser le formaliser RaiseError=>1
qui simplifie grandement la gestion d'erreurs.
Avec l'encapsulation dans des transactions, et l'usage des placeholders
et du $dbh->quote() si nécessaire.

--
Patrick Mevzek . . . . . . Dot and Co (Paris, France)
<http://www.dotandco.net/> <http://www.dotandco.com/>
Dépêches sur le nommage <news://news.dotandco.net/dotandco.info.news>

Avatar
Aurelien
Autant utiliser le formaliser RaiseError=>1
qui simplifie grandement la gestion d'erreurs.
Avec l'encapsulation dans des transactions, et l'usage des placeholders
et du $dbh->quote() si nécessaire.



Bon, là on commence à partir dans de l'utilisation poussée de DBI :) et
c'est vrai qu'il fournit plein de mécanismes très utiles. Mais pour
l'exemple en question, quelque chose de simple serait préférable je pense.
Je n'aime pas l'utilisation de RaiseError, qui oblige à encapsuler tout
dans des evals. Par contre, HandleError est assez pratique.
(voir perldoc DBI)

Sinon, il est vrai que utiliser des placeholders et quote() serait une
*très* bonne idée.

Ex :


_Utilisation_:
$ monscript.pl < listedomain.txt > erreurs.txt

__CODE__

my $categories = 'xxxx';
my $dbh = DBI->connect(...);

# On prepare une fois la requete (utilisation de place holders)
# Voir "perldoc DBI" et "Performance"
my $query = qq{ INSERT INTO $categories VALUES (?, ?, ?) };
my $sth = $dbh->prepare($query);

while (<>) {

# Supprime le retour à la ligne de fin de ligne
chomp;

# Coupe la ligne courante au niveau des espaces(voir perldoc -f split)
my($domain) = split;

# Inutile d'utiliser quote(), DBI le fait pour nous ici
# Comme la premier et la dernier valeur ne change jamais, elles
# peuvent être directement définies au niveau de la requête
$sth->execute('', $domain, 'url') or warn $query; # ou $sth->errstr()

}

$dbh->disconnect();

__END__

Avatar
Patrick Mevzek


Autant utiliser le formaliser RaiseError=>1 qui simplifie grandement
la gestion d'erreurs. Avec l'encapsulation dans des transactions, et
l'usage des placeholders et du $dbh->quote() si nécessaire.


Bon, là on commence à partir dans de l'utilisation poussée de DBI :) et



Les placeholders et $dbh->quote() c'est la base.
Quand on veut éviter l'injection SQL en tout cas, et avoir des
performances potables :-)

c'est vrai qu'il fournit plein de mécanismes très utiles. Mais pour
l'exemple en question, quelque chose de simple serait préférable je
pense. Je n'aime pas l'utilisation de RaiseError, qui oblige à


TIMTOWTDI of course.
Cependant ca se marrie parfaitement avec une gestion des exceptions via
une classe spécifique (dérivée de Exception ou autre, ou personnelle).
Ca permet de découpler les codes de retour d'une fonction des éventuelles
erreurs qui y apparaissent.

Et personnellement, je préfère:
eval
{
X
Y
Z
}
plutôt que:
X or error()
Y or error()
Z or error()

car dans le dernier cas, d'expèrience, au bout d'un moment on oublie la
partie droite du or...
Et ca ne passe pas bien à l'échelle (si X appelle A B C par exemple).

encapsuler tout dans des evals. Par contre, HandleError est assez
pratique. (voir perldoc DBI)


D'ailleurs, est proposé comme exemple:
$h->{HandleError} = sub { Exception->new('DBI')->raise($_[0]) };

Sinon, il est vrai que utiliser des placeholders et quote() serait une
*très* bonne idée.


Leur non utilisation fait perdre des guru points.

Ex :


Exemple qui n'est pas sans problèmes :-(
Si la transaction échoue (parce qu'on est implicitement dans une
transaction) ou si on perd la connexion à la base, le programme continue
de boucler et d'échouer à chaque execute.
Il n'y a pas de vérification sur $dbh non plus avant de s'en servir.
Et $dbh->prepare avec $dbh=undef, perl va gueuler...
De même, le prepare peut échouer.

--
Patrick Mevzek . . . . . . Dot and Co (Paris, France)
<http://www.dotandco.net/> <http://www.dotandco.com/>
Dépêches sur le nommage <news://news.dotandco.net/dotandco.info.news>


Avatar
Aurelien
Patrick Mevzek wrote:

Exemple qui n'est pas sans problèmes :-(
Si la transaction échoue (parce qu'on est implicitement dans une
transaction) ou si on perd la connexion à la base, le programme continue
de boucler et d'échouer à chaque execute.
Il n'y a pas de vérification sur $dbh non plus avant de s'en servir.
Et $dbh->prepare avec $dbh=undef, perl va gueuler...
De même, le prepare peut échouer.


Oui, c vrai.
J'ai surtout montrer ce qu'on pouvait faire avec la boucle, le prepare
et les placeholder.
Ne sachant comment ce bout de code était imbriqué dans d'autres, j'ai
mis le strict minimum avant et après. Evidement, c à corriger, le code
n'est pas parfait.

Avatar
Yoann Wyffels
"Aurelien" a écrit dans le message de news:
41891fc6$0$29220$
Patrick Mevzek wrote:

Exemple qui n'est pas sans problèmes :-(
Si la transaction échoue (parce qu'on est implicitement dans une
transaction) ou si on perd la connexion à la base, le programme continue
de boucler et d'échouer à chaque execute.
Il n'y a pas de vérification sur $dbh non plus avant de s'en servir.
Et $dbh->prepare avec $dbh=undef, perl va gueuler...
De même, le prepare peut échouer.


Oui, c vrai.
J'ai surtout montrer ce qu'on pouvait faire avec la boucle, le prepare et
les placeholder.
Ne sachant comment ce bout de code était imbriqué dans d'autres, j'ai mis
le strict minimum avant et après. Evidement, c à corriger, le code n'est
pas parfait.




Oui enfin si vous voulez mon avis, Mylene n'en a rien à faire vu son niveau
;)