Discussion:
Perl - DBI - use strict
(trop ancien pour répondre)
Eric BERTHOMIER
2011-03-15 13:12:04 UTC
Permalink
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;
Denis Dordoigne
2011-03-15 14:32:40 UTC
Permalink
Bonjour,
Post by Eric BERTHOMIER
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
Marc Espie
2011-03-15 19:04:07 UTC
Permalink
Post by 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
2011-03-16 10:00:17 UTC
Permalink
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
2011-03-17 10:31:44 UTC
Permalink
Post by luc2
tu veux donc inserer NULL dans la base. la requete que tu veux executer
INSERT INTO essai (idAuteur) VALUES (NULL)
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
2011-03-17 13:29:17 UTC
Permalink
Post by Eric BERTHOMIER
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
2011-03-17 15:10:49 UTC
Permalink
À (at) 17 Mar 2011 13:29:17 GMT,
Post by luc2
Post by Eric BERTHOMIER
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.
$dbh->do( 'INSERT INTO essai (idAuteur) VALUES (?)', undef, undef );
http://search.cpan.org/~timb/DBI-1.616/DBI.pm
Très bon conseil !
Post by luc2
autre methode (moins bonne), c'est d'affecter la chaine 'NULL' dans
$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 - <http://perso.mines-albi.fr/~gaborit/>
Perl en français - <http://perl.mines-albi.fr/>
Marc Espie
2011-03-17 16:46:42 UTC
Permalink
Post by 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
$dbh->do( "INSERT INTO essai (idAuteur) VALUES ('$idAuteur')" );
Non:
$dbh->do("INSERT INTO essai (idAuteur) VALUES (".$dbh->quote($idAuteur)).")");
Paul Gaborit
2011-03-18 06:45:53 UTC
Permalink
À (at) Thu, 17 Mar 2011 16:46:42 +0000 (UTC),
Post by Marc Espie
Post by 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
$dbh->do( "INSERT INTO essai (idAuteur) VALUES ('$idAuteur')" );
$dbh->do("INSERT INTO essai (idAuteur) VALUES (".$dbh->quote($idAuteur)).")");
C'est ce que j'expliquais (manifestement mal) ensuite... ;-)
--
Paul Gaborit - <http://perso.mines-albi.fr/~gaborit/>
Perl en français - <http://perl.mines-albi.fr/>
luc2
2011-03-18 09:16:36 UTC
Permalink
Post by Paul Gaborit
Post by luc2
autre methode (moins bonne), c'est d'affecter la chaine 'NULL' dans
$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.
Post by Paul Gaborit
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'";
Post by Paul Gaborit
Et
d'ailleurs il ne marche pas du tout à cause des ' à la place des ". Il
$dbh->do( "INSERT INTO essai (idAuteur) VALUES ('$idAuteur')" );
oui, j'ai oublie les guillemets.
Post by Paul Gaborit
INSERT INTO essai (idAuteur) VALUES ('NULL')
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...

Loading...