GNT sans publicité, site mobile, fonctionnalitées exclusives...

Nombre variables de params dans une requete SQL

Le
Marc Nadeau
J'ai un script qui interroge une BD mysql (banal) et qui parfois ne doit
tenir compte que d'un champs de recherche, parfois doit faire une recherche
plus serrée en sélectionnant sur 2 ou 3 champs.

Actuellement, je dois faire effectuer la requête par des fonctions
différentes selons le nombre de champs utilisés.

--
# fonction1: un seul critère:
snip
my ($critere, $clef) = @_;
snip
$sth = $dbh->prepare ("SELECT COUNT(*) FROM bannieres WHERE $critere LIKE
\"$clef\" ");
snip
-
# fonction2: 2 critères
my ($critere01, $clef01, $critere02, $clef02) = @_;
$sth = $dbh->prepare ("SELECT COUNT(*) FROM bannieres WHERE $critere01 LIKE
\"$clef01\" AND $critere02 LIKE \"$clef02\" ");

--
# fonction3: Ainsi de suite


Je voudrais faire exécuter toutes ces requêtes par une seule et même
fonction qui créerait une requête différente selon le nombre de paramètres
envoyés à la dite fonction.

Ce n'est pas critique pcq le programme fonctionne bien, mais je veux éviter
la redondance dans le code.


Merci d'avance!

--
L'Amiral nous brouille l'écoute avec sa panne de micro
Lire les 10 réponses

Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses Page 1 / 2
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
root
Le #136601
On Sun, 23 Nov 2003 07:13:35 +0000, Marc Nadeau wrote:


J'ai un script qui interroge une BD mysql (banal) et qui parfois ne doit
tenir compte que d'un champs de recherche, parfois doit faire une recherche
plus serrée en sélectionnant sur 2 ou 3 champs.

Actuellement, je dois faire effectuer la requête par des fonctions
différentes selons le nombre de champs utilisés.

--------------
# fonction1: un seul critère:
snip...
my ($critere, $clef) = @_;
snip...
$sth = $dbh->prepare ("SELECT COUNT(*) FROM bannieres WHERE $critere LIKE
"$clef" ");
snip...
----------------
# fonction2: 2 critères
my ($critere01, $clef01, $critere02, $clef02) = @_;
$sth = $dbh->prepare ("SELECT COUNT(*) FROM bannieres WHERE $critere01 LIKE
"$clef01" AND $critere02 LIKE "$clef02" ");

--------------
# fonction3: Ainsi de suite...
---------------



--8<--
#!/usr/bin/perl

use strict;
use warnings;

print requete(
'A' => '1',
'B' => '2',
'C' => '3',
'D' => '4',
);

sub requete {
my %parms = @_;

my $requete = "SELECT COUNT(*) FROM bannieres WHERE ";

my @criteres_like;
foreach (keys %parms) {
push @criteres_like, "$_ LIKE $parms{$_}";
}

$requete .= join(" AND ", @criteres_like);

return $requete;
}

-->8--

SELECT COUNT(*) FROM bannieres WHERE A LIKE 1 AND D LIKE 4 AND C LIKE 3
AND B LIKE 2

Note: l'utilisation d'un hash fait que l'ordre des critères passés en
paramètre n'est pas conservé. Mais c'est tellement plus simple/élégant
avec un hash :)

Alex Marandon
Le #136600
In article

J'ai un script qui interroge une BD mysql (banal) et qui parfois ne doit
tenir compte que d'un champs de recherche, parfois doit faire une recherche
plus serrée en sélectionnant sur 2 ou 3 champs.

Actuellement, je dois faire effectuer la requête par des fonctions
différentes selons le nombre de champs utilisés.

--------------
# fonction1: un seul critère:
snip...
my ($critere, $clef) = @_;
snip...
$sth = $dbh->prepare ("SELECT COUNT(*) FROM bannieres WHERE $critere LIKE
"$clef" ");
snip...
----------------
# fonction2: 2 critères
my ($critere01, $clef01, $critere02, $clef02) = @_;
$sth = $dbh->prepare ("SELECT COUNT(*) FROM bannieres WHERE $critere01 LIKE
"$clef01" AND $critere02 LIKE "$clef02" ");


# Tu répupère les parametres dans un hash.
my %criteres = @_;

# Le WHERE TRUE fonctionne avec PostgreSQL. Avec MySQL, je crois me
# rappeler que la syntaxe est différente (WHERE 1, il me semble).
# L'important est d'avoir une première condition toujours vraie
# simplement pour pouvoir empiler les AND derrière.
my $sql = 'SELECT COUNT(*) FROM bannieres WHERE TRUE ';

# On crée les conditions de la clause WHERE
for ( keys %criteres ) {
$sql .= ' AND $_ LIKE ' . $criteres{$_} ;
}

# Et voila :-)
$sth = $dbh->prepare($sql);

__END__

Voila, à tester, adapter selon tes besoins, mais le principe est là. Il
faut caculer ta chaine SQL dynamiquement.

Alex Marandon
Le #136599
In article
my @criteres_like;
foreach (keys %parms) {
push @criteres_like, "$_ LIKE $parms{$_}";
}

$requete .= join(" AND ", @criteres_like);


Ah bah oui, c'est encore mieux comme ça tiens :)

Nicolas Chuche
Le #136598
root
my @criteres_like;
foreach (keys %parms) {
push @criteres_like, "$_ LIKE $parms{$_}";
}


"map" est tout indiqué dans ce cas là :

my @criteres_like = map { "$_ LIKE $parms{$_}" } keys %parms;

jeanpierre.vidal
Le #136491
Marc Nadeau
J'ai un script qui interroge une BD mysql (banal) et qui parfois ne doit
tenir compte que d'un champs de recherche, parfois doit faire une recherche
plus serrée en sélectionnant sur 2 ou 3 champs.

Actuellement, je dois faire effectuer la requête par des fonctions
différentes selons le nombre de champs utilisés.

--------------
# fonction1: un seul critère:
snip...
my ($critere, $clef) = @_;
snip...
$sth = $dbh->prepare ("SELECT COUNT(*) FROM bannieres WHERE $critere LIKE
"$clef" ");
snip...
----------------
# fonction2: 2 critères
my ($critere01, $clef01, $critere02, $clef02) = @_;
$sth = $dbh->prepare ("SELECT COUNT(*) FROM bannieres WHERE $critere01 LIKE
"$clef01" AND $critere02 LIKE "$clef02" ");

--------------
# fonction3: Ainsi de suite...
---------------

Je voudrais faire exécuter toutes ces requêtes par une seule et même
fonction qui créerait une requête différente selon le nombre de paramètres
envoyés à la dite fonction.

Ce n'est pas critique pcq le programme fonctionne bien, mais je veux éviter
la redondance dans le code.


Merci d'avance!


splice ? ou shift ? quelque chose comme ceci (non testé) :

my $query;
my $first = 1;
my $critere;
my $clef;

while (@_) {
...
($critere, $clef) = splice(@_, 0, 2);

<ou encore>
$critere = shift; $clef = shift;
</ou encore>

...
if (first) {
$query = "SELECT COUNT(*) FROM bannieres WHERE $critere LIKE "$clef";
} else {
$query .= " AND $critere LIKE "$clef";
}
...
$first = 0;
}
$sth = $dbh->prepare ($query);

Jean-Pierre

Publicité
Suivre les réponses
Poster une réponse
Anonyme