Perl - DBI - use strict

Le
Eric BERTHOMIER
Bonjour,

voici un petit programme qui me permet (pour test) d'insrer des
lments dans une base de donnes. Un de ces lments est NULL /
undef.

Mon problme est qu'avec DBI / prepare et DBI / exec, j'arrive
raliser ma requte tandis qu'avec DBI / do strict me refuse la
commande.

Merci d'avance.

#!/usr/bin/perl -w

use strict;
use DBI;

my $database="essai";
my $login="essai";
my $mdp="essai";
my$hostname="localhost";

my $id_auteur=undef;
my $dbh_sql = DBI->connect("DBI:mysql:database=$database;host=
$hostname", $login, $mdp) or die "Echec connexion base mysql";

my $sth = $dbh_sql->prepare(qq{
INSERT INTO essai (idAuteur) VALUES (?)
});
$sth->execute($id_auteur);

$dbh_sql->do (qq {
INSERT INTO essai (idAuteur) VALUES ($id_auteur)
}) or die $dbh_sql->errstr();

$dbh_sql->disconnect;
Vos réponses
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Denis Dordoigne
Le #23206641
Bonjour,

my $id_auteur=undef;
(...)
$dbh_sql->do (qq {
INSERT INTO essai (idAuteur) VALUES ($id_auteur)



Le message d'erreur est explicite je pense, il doit indiquer qu'on chercher à concaténer
une variable indéfinie. Il faudrait utiliser $id_auteur à la chaîne vide ('') par exemple
pour pouvoir le concaténer.


--
Denis Dordoigne
Membre de l'April - promouvoir et défendre le logiciel libre - april.org
Rejoignez maintenant plus de 5 000 personnes, associations,
entreprises et collectivités qui soutiennent notre action
espie
Le #23207221
In article Eric BERTHOMIER
Bonjour,

voici un petit programme qui me permet (pour test) d'insérer des
éléments dans une base de données. Un de ces éléments est NULL /
undef.

Mon problème est qu'avec DBI / prepare et DBI / exec, j'arrive à
réaliser ma requête tandis qu'avec DBI / do strict me refuse la
commande.

Merci d'avance.

#!/usr/bin/perl -w

use strict;
use DBI;

my $database="essai";
my $login="essai";
my $mdp="essai";
my$hostname="localhost";

my $id_auteur=undef;
my $dbh_sql = DBI->connect("DBI:mysql:database=$database;host >$hostname", $login, $mdp) or die "Echec connexion base mysql";

my $sth = $dbh_sql->prepare(qq{
INSERT INTO essai (idAuteur) VALUES (?)
});
$sth->execute($id_auteur);

$dbh_sql->do (qq {
INSERT INTO essai (idAuteur) VALUES ($id_auteur)
}) or die $dbh_sql->errstr();

$dbh_sql->disconnect;



Qu'est-ce qui te pose probleme, que ca marche, ou que ca ne marche pas ?

prepare/execute est toujours une excellente idee (proscrire do quand on
peut, SURTOUT avec une chaine variable).

Apres, si ca ne devrait pas marcher, il faudrait sans doute avoir les
contraintes qui vont bien dans le schema de la base. C'est un bout qui
varie pas mal selon les bases, mais specifier un NOT NULL lors de la
definition d'une cle n'a jamais fait de mal (a ma connaissance) meme si c'est
redondant sur certaines DB.
luc2
Le #23208361
tu veux donc inserer NULL dans la base. la requete que tu veux executer
est donc :

INSERT INTO essai (idAuteur) VALUES (NULL)

or, comme $id_auteur est undef, la requete qui est executee sera donc :

INSERT INTO essai (idAuteur) VALUES ()

le serveur mysql va donc t'envoyer un message d'insulte.

dans le cas de prepare + execute, ca marche, parce que la fonction
execute "convertit" la valeur perl undef en valeur mysql NULL pour
executer la requete.
Eric BERTHOMIER
Le #23211051
On 16 mar, 06:00, luc2
tu veux donc inserer NULL dans la base. la requete que tu veux executer
est donc :

INSERT INTO essai (idAuteur) VALUES (NULL)

or, comme $id_auteur est undef, la requete qui est executee sera donc :

INSERT INTO essai (idAuteur) VALUES ()

le serveur mysql va donc t'envoyer un message d'insulte.

dans le cas de prepare + execute, ca marche, parce que la fonction
execute "convertit" la valeur perl undef en valeur mysql NULL pour
executer la requete.



C'est bien ça. Ma problématique c'est que je ne peux pas écrire
$idAuteur = NULL avec l'option use strict;
Après il est vrai que je peux passer par prepare et execute mais
j'aurai aimé comprendre le fond du problème, c'est à dire, dans la
fonction do, convertir undef en NULL.
luc2
Le #23211411
C'est bien ça. Ma problématique c'est que je ne peux pas écrire
$idAuteur = NULL avec l'option use strict;
Après il est vrai que je peux passer par prepare et execute mais
j'aurai aimé comprendre le fond du problème, c'est à dire, dans la
fonction do, convertir undef en NULL.



tu peux faire pareil avec la fonction do() :

$dbh->do( 'INSERT INTO essai (idAuteur) VALUES (?)', undef, undef );

lis la doc pour connaitre les parametres de la fonction :

http://search.cpan.org/~timb/DBI-1.616/DBI.pm

autre methode (moins bonne), c'est d'affecter la chaine 'NULL' dans
$idAuteur :

$idAuteur = 'NULL';
$dbh->do( 'INSERT INTO essai (idAuteur) VALUES ($idAuteur)' );

c'est d'ailleurs ce qui se produit quand tu ecris $idAuteur = NULL sans
use strict; comme perl n'a aucune idee de ce que signifie NULL, il
affecte la chaine 'NULL' a $idAuteur. les experts perl me corrigeront.
Paul Gaborit
Le #23211641
À (at) 17 Mar 2011 13:29:17 GMT,
luc2
C'est bien ça. Ma problématique c'est que je ne peux pas écrire
$idAuteur = NULL avec l'option use strict;
Après il est vrai que je peux passer par prepare et execute mais
j'aurai aimé comprendre le fond du problème, c'est à dire, dans la
fonction do, convertir undef en NULL.



tu peux faire pareil avec la fonction do() :

$dbh->do( 'INSERT INTO essai (idAuteur) VALUES (?)', undef, undef );

lis la doc pour connaitre les parametres de la fonction :

http://search.cpan.org/~timb/DBI-1.616/DBI.pm



Très bon conseil !

autre methode (moins bonne), c'est d'affecter la chaine 'NULL' dans
$idAuteur :

$idAuteur = 'NULL';
$dbh->do( 'INSERT INTO essai (idAuteur) VALUES ($idAuteur)' );

c'est d'ailleurs ce qui se produit quand tu ecris $idAuteur = NULL sans
use strict; comme perl n'a aucune idee de ce que signifie NULL, il
affecte la chaine 'NULL' a $idAuteur. les experts perl me corrigeront.



Là par contrem c'est un très mauvais conseil. Le 'do' tel qu'il est
écrit ne supporte pas des valeurs avec des espaces dans $idAuteur. Et
d'ailleurs il ne marche pas du tout à cause des ' à la place des ". Il
faudrait l'écrire :

$dbh->do( "INSERT INTO essai (idAuteur) VALUES ('$idAuteur')" );

Mais la requête SQL :

INSERT INTO essai (idAuteur) VALUES ('NULL')

n'a pas le même sens que :

INSERT INTO essai (idAuteur) VALUES (NULL)

Et puis, si la valeur de $idAuteur contient des ', c'est encore plus
compliqué.

Conclusion : sauf à parfaitement maîtriser à la fois Perl et SQL, ne
jamais écrire soi-même du code Perl qui génère du code SQL ! Toujours
passer par un surcouche comme DBI qui fait très bien le boulot.

--
Paul Gaborit - Perl en français -
espie
Le #23211981
In article Paul Gaborit

Là par contrem c'est un très mauvais conseil. Le 'do' tel qu'il est
écrit ne supporte pas des valeurs avec des espaces dans $idAuteur. Et
d'ailleurs il ne marche pas du tout à cause des ' à la place des ". Il
faudrait l'écrire :

$dbh->do( "INSERT INTO essai (idAuteur) VALUES ('$idAuteur')" );



Non:
$dbh->do("INSERT INTO essai (idAuteur) VALUES (".$dbh->quote($idAuteur)).")");
Paul Gaborit
Le #23213321
À (at) Thu, 17 Mar 2011 16:46:42 +0000 (UTC),
(Marc Espie) écrivait (wrote):

In article Paul Gaborit

Là par contrem c'est un très mauvais conseil. Le 'do' tel qu'il est
écrit ne supporte pas des valeurs avec des espaces dans $idAuteur. Et
d'ailleurs il ne marche pas du tout à cause des ' à la place des ". Il
faudrait l'écrire :

$dbh->do( "INSERT INTO essai (idAuteur) VALUES ('$idAuteur')" );



Non:
$dbh->do("INSERT INTO essai (idAuteur) VALUES (".$dbh->quote($idAuteur)).")");



C'est ce que j'expliquais (manifestement mal) ensuite... ;-)

--
Paul Gaborit - Perl en français -
luc2
Le #23213671
Le 17-03-2011, Paul Gaborit
autre methode (moins bonne), c'est d'affecter la chaine 'NULL' dans
$idAuteur :

$idAuteur = 'NULL';
$dbh->do( 'INSERT INTO essai (idAuteur) VALUES ($idAuteur)' );

c'est d'ailleurs ce qui se produit quand tu ecris $idAuteur = NULL sans
use strict; comme perl n'a aucune idee de ce que signifie NULL, il
affecte la chaine 'NULL' a $idAuteur. les experts perl me corrigeront.



Là par contrem c'est un très mauvais conseil.



non, ce n'etait pas un conseil. j'ai ecrit que c'etait une methode
"moins bonne", donc, deconseillee. or, d'apres ce que j'ai compris de la
demande de mon interlocuteur, il ne cherchait pas la methode parfaite;
ce qu'il voulait, c'etait comprendre le pourquoi du comment (voir la
derniere phrase de son post). dans le contexte de sa question, il genere
lui-meme le code sql. pour lui dire comment faire marcher son code, j'ai
ete oblige de reprendre le meme contexte, meme si, comme vous tous, ca
me dechire le coeur de generer moi-meme la requete entiere.

Le 'do' tel qu'il est
écrit ne supporte pas des valeurs avec des espaces dans $idAuteur.



si. on peut faire $idAuteur = "'message avec espaces'";

Et
d'ailleurs il ne marche pas du tout à cause des ' à la place des ". Il
faudrait l'écrire :

$dbh->do( "INSERT INTO essai (idAuteur) VALUES ('$idAuteur')" );



oui, j'ai oublie les guillemets.

Mais la requête SQL :

INSERT INTO essai (idAuteur) VALUES ('NULL')

n'a pas le même sens que :

INSERT INTO essai (idAuteur) VALUES (NULL)

Et puis, si la valeur de $idAuteur contient des ', c'est encore plus
compliqué.

Conclusion : sauf à parfaitement maîtriser à la fois Perl et SQL, ne
jamais écrire soi-même du code Perl qui génère du code SQL ! Toujours
passer par un surcouche comme DBI qui fait très bien le boulot.



vous allez vous epuiser et l'embrouiller...
Publicité
Poster une réponse
Anonyme