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

Requête renvoyant à une autre ?

2 réponses
Avatar
Gloops
Bonjour tout le monde,

Il me semble bien avoir vu quelque part dans un bouquin SQL qu'on
pouvait enregistrer une requête avec une clause renvoyant à une autre
requête enregistrée, du style
WHERE nomchamp IN (reqReference)

étant entendu que reqReference doit contenir le champ nomchamp (et de
préférence seulement celui-là, ça je ne me rappelle plus très bien).

Est-ce que ce genre de pirouette est envisageable avec une requête
Access 2000 appelée depuis VB6 ?

ça pourrait m'intéresser, vu que dans l'exemple auquel je pense
reqReference ne tarderait pas à être une requête UNION, donc plus facile
à gérer à part.

Pour le moment, si je veux faire ça, il faut que je me livre à une autre
gymnastique lors de l'appel :

With Data1.Database.QueryDefs("reqPurgeAdresses")
.Parameters(0) = _
RetourRequete(Data1.Database.QueryDefs("reqAPurger"))
Data1.Database.Execute Replace(.SQL, "reqAPurger", .Parameters(0))
End With

Public Function RetourRequete(ByVal qry As QueryDef)
Dim Rs As Recordset
Set Rs = qry.OpenRecordset
Dim strTemp As String
If Rs.RecordCount = 0 Then
RetourRequete = ""
Else
strTemp = ""
While Not Rs.EOF
strTemp = strTemp + Chr$(34) + Rs.Fields(0) + Chr$(34) + ", "
Rs.MoveNext
Wend
RetourRequete = Left$(strTemp, Len(strTemp) - 2)
End If
Rs.Close
Set Rs = Nothing
End Function

ça marche, mais question style, vous voyez ce que je veux dire ...

2 réponses

Avatar
Eric
Hello Gloops,

Pour ma part, je n'ai jamais vu (mais mon expérience n'est pas très
vieille ;-) ) la possibilité de mettre dans la clause IN le nom d'une
requête. En général, le sql de la requête est du genre:
WHERE monchamp IN (Select Monchamp from tableX WHERE ...)

(Effectivement pour que le IN fonctionne, la sous-requête ne doit
renvoyer qu'un seul champ.)

Pour contourner, mais ce n'est peut-être pas ce que tu souhaites, tu
peux faire un truc du genre:

Dim strSQL as String
Set qry = ....QueryDefs("LaRequête") ou avec With
Data1.Database.QueryDefs(...)

(Cette requête retourne un seul champ nommé LeChamp à partir de UneTable)

Il est possible de récuperer sa chaine SQL à partir de la propriété SQL
de l'objet QueryDef.

Puis construire le nouveau sql à partir du sql de la requête précédente:

strSQL = "select * from UneAutreTable where LeChamp in(" _
& Left(qry.SQL, Len(qry.SQL) - 1) & ");"

Et enfin l'affecter à un autre objet QueryDef.

De cette manière ca t'evites de devoir réécrire tout le sql de la
sous-requête.

Un début de piste, peut-être ...

A+
Eric

(PS : Ceci fonctionne très bien sous Access2K)


Gloops a écrit :
Bonjour tout le monde,

Il me semble bien avoir vu quelque part dans un bouquin SQL qu'on
pouvait enregistrer une requête avec une clause renvoyant à une autre
requête enregistrée, du style
WHERE nomchamp IN (reqReference)

étant entendu que reqReference doit contenir le champ nomchamp (et de
préférence seulement celui-là, ça je ne me rappelle plus très bien).

Est-ce que ce genre de pirouette est envisageable avec une requête
Access 2000 appelée depuis VB6 ?

ça pourrait m'intéresser, vu que dans l'exemple auquel je pense
reqReference ne tarderait pas à être une requête UNION, donc plus facile
à gérer à part.

Pour le moment, si je veux faire ça, il faut que je me livre à une autre
gymnastique lors de l'appel :

With Data1.Database.QueryDefs("reqPurgeAdresses")
.Parameters(0) = _
RetourRequete(Data1.Database.QueryDefs("reqAPurger"))
Data1.Database.Execute Replace(.SQL, "reqAPurger", .Parameters(0))
End With

Public Function RetourRequete(ByVal qry As QueryDef)
Dim Rs As Recordset
Set Rs = qry.OpenRecordset
Dim strTemp As String
If Rs.RecordCount = 0 Then
RetourRequete = ""
Else
strTemp = ""
While Not Rs.EOF
strTemp = strTemp + Chr$(34) + Rs.Fields(0) + Chr$(34) + ", "
Rs.MoveNext
Wend
RetourRequete = Left$(strTemp, Len(strTemp) - 2)
End If
Rs.Close
Set Rs = Nothing
End Function

ça marche, mais question style, vous voyez ce que je veux dire ...



Avatar
Gloops
Hello,

Merci pour ta réponse. Je ne suis pas très sûr de l'opérateur IN, et
après tout peut-être est-ce propre à d'autres modèles de bases de
pouvoir imbriquer deux requêtes nommées.

Cela étant, c'est vrai que quitte à faire un remplacement dans le SQL,
je peux remplacer par le code SQL de la requête imbriquée, plutôt que la
liste des valeurs. Il faut avouer que c'est plus lisible une fois qu'on
a tout sous les yeux. Moui, Samedi on est demain ? J'ai l'impression que
je devrais en tenir compte.

Ton aide est décidément précieuse ...




















Eric a écrit, le 13/05/2005 16:39 :

Hello Gloops,

Pour ma part, je n'ai jamais vu (mais mon expérience n'est pas très
vieille ;-) ) la possibilité de mettre dans la clause IN le nom d'une
requête. En général, le sql de la requête est du genre:
WHERE monchamp IN (Select Monchamp from tableX WHERE ...)

(Effectivement pour que le IN fonctionne, la sous-requête ne doit
renvoyer qu'un seul champ.)

Pour contourner, mais ce n'est peut-être pas ce que tu souhaites, tu
peux faire un truc du genre:

Dim strSQL as String
Set qry = ....QueryDefs("LaRequête") ou avec With
Data1.Database.QueryDefs(...)

(Cette requête retourne un seul champ nommé LeChamp à partir de UneTable)

Il est possible de récuperer sa chaine SQL à partir de la propriété SQL
de l'objet QueryDef.

Puis construire le nouveau sql à partir du sql de la requête précédente:

strSQL = "select * from UneAutreTable where LeChamp in(" _
& Left(qry.SQL, Len(qry.SQL) - 1) & ");"

Et enfin l'affecter à un autre objet QueryDef.

De cette manière ca t'evites de devoir réécrire tout le sql de la
sous-requête.

Un début de piste, peut-être ...

A+
Eric

(PS : Ceci fonctionne très bien sous Access2K)


Gloops a écrit :

Bonjour tout le monde,

Il me semble bien avoir vu quelque part dans un bouquin SQL qu'on
pouvait enregistrer une requête avec une clause renvoyant à une autre
requête enregistrée, du style
WHERE nomchamp IN (reqReference)

étant entendu que reqReference doit contenir le champ nomchamp (et de
préférence seulement celui-là, ça je ne me rappelle plus très bien).

Est-ce que ce genre de pirouette est envisageable avec une requête
Access 2000 appelée depuis VB6 ?

ça pourrait m'intéresser, vu que dans l'exemple auquel je pense
reqReference ne tarderait pas à être une requête UNION, donc plus
facile à gérer à part.

Pour le moment, si je veux faire ça, il faut que je me livre à une
autre gymnastique lors de l'appel :

With Data1.Database.QueryDefs("reqPurgeAdresses")
.Parameters(0) = _
RetourRequete(Data1.Database.QueryDefs("reqAPurger"))
Data1.Database.Execute Replace(.SQL, "reqAPurger", .Parameters(0))
End With

Public Function RetourRequete(ByVal qry As QueryDef)
Dim Rs As Recordset
Set Rs = qry.OpenRecordset
Dim strTemp As String
If Rs.RecordCount = 0 Then
RetourRequete = ""
Else
strTemp = ""
While Not Rs.EOF
strTemp = strTemp + Chr$(34) + Rs.Fields(0) + Chr$(34) + ", "
Rs.MoveNext
Wend
RetourRequete = Left$(strTemp, Len(strTemp) - 2)
End If
Rs.Close
Set Rs = Nothing
End Function

ça marche, mais question style, vous voyez ce que je veux dire ...