Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Perl - DBI - use strict

9 réponses
Avatar
Eric BERTHOMIER
Bonjour,

voici un petit programme qui me permet (pour test) d'ins=E9rer des
=E9l=E9ments dans une base de donn=E9es. Un de ces =E9l=E9ments est NULL /
undef.

Mon probl=E8me est qu'avec DBI / prepare et DBI / exec, j'arrive =E0
r=E9aliser ma requ=EAte tandis qu'avec DBI / do strict me refuse la
commande.

Merci d'avance.

#!/usr/bin/perl -w

use strict;
use DBI;

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

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

my $sth =3D $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;

9 réponses

Avatar
Denis Dordoigne
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
Avatar
espie
In article ,
Eric BERTHOMIER wrote:
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.
Avatar
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.
Avatar
Eric BERTHOMIER
On 16 mar, 06:00, luc2 wrote:
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.
Avatar
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

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.
Avatar
Paul Gaborit
À (at) 17 Mar 2011 13:29:17 GMT,
luc2 écrivait (wrote):

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 - <http://perso.mines-albi.fr/~gaborit/>
Perl en français - <http://perl.mines-albi.fr/>
Avatar
espie
In article ,
Paul Gaborit <Paul.Gaborit+ wrote:

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)).")");
Avatar
Paul Gaborit
À (at) Thu, 17 Mar 2011 16:46:42 +0000 (UTC),
(Marc Espie) écrivait (wrote):

In article ,
Paul Gaborit <Paul.Gaborit+ wrote:

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 - <http://perso.mines-albi.fr/~gaborit/>
Perl en français - <http://perl.mines-albi.fr/>
Avatar
luc2
Le 17-03-2011, Paul Gaborit a écrit :

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...