SQL LEFT OUTER JOIN et RecordSet
Bonjour à tous,
J'essaie de comprendre pourquoi une requête SQL (avec une jointure externe) executée via un ADODB.RecordSet ne me retourne aucune ligne alors que la même requête exécutée dans une solution SQL (Toad en l'occurence, que j'utilise) retourne des lignes.
C'est la propriété rs.RecordCount qui m'indique qu'aucune ligne n'est retournée.
Pour être sûr que la requête générée est correcte et retourne effectivement au moins une ligne, j'ai copiée la variable qry obtenue dans le presse-papier et l'ai exécutée dans Toad, avec justement des lignes de résultats, me prouvant que la requête est bien fonctionnelle.
Peut-être que j'utilise mal la propriété Open du recordset, ou autre chose mal écrite dans le code ?
Je précise que pour une requête classique (le qry que j'ai commenté par exemple) sans jointure externe, ça marche bien, le recordset obtenu après éxécution du SQL n'étant pas vide ...
Voici mon code :
Function RemplirCelluleCO_CC(filtre As String, reste As Integer, tour As Integer)
Dim tableau As Variant
Dim valeur As String
' la variable filtre contient une suite de comptes_ID
'qry = "SELECT ACCT_ID, BILL_CYC_CD FROM CI_ACCT WHERE ACCT_ID in (" & filtre & ")"
qry = "SELECT A.ACCT_ID, DECODE (B.ACCT_ID, NULL, A.BILL_CYC_CD, B.CYC_ORIGINE) AS CYC_ORI, " & _
"DECODE (B.ACCT_ID, NULL, A.BILL_CYC_CD, B.CYC_EN_COURS) AS CYC_EN_COURs, " & _
"FROM CI_ACCT A LEFT OUTER JOIN CM_C_TMP_MAJ_CYC_S B ON A.ACCT_ID = B.ACCT_ID " & _
"WHERE A.ACCT_ID in (" & filtre & ")"
Call ConnexionOracle(fichierConnexionProd)
Set rs = New ADODB.Recordset
rs.Open qry, cnx, adOpenKeyset, adLockOptimistic
'MsgBox rs.RecordCount
Set obj = New DataObject
obj.SetText qry
' J'ai mis qry dans le presse-papier pour savoir ce que contient qry et l'éxécuter dans Toad
obj.PutInClipboard
If rs.RecordCount < 1 Then
rs.Close
'Rien dans le recordset, on sort du programme
Call DeconnexionOracle
Exit Function
Else
tableau = rs.GetRows
rs.Close
End If
Call DeconnexionOracle
( ... )
End Function
Merci pour votre aide ... je suis dans une impasse ... !
A très vite !
Hum,
Essaye de pointer au début du recordset avant de compléter ton tableau :
Else
rs.MoveFirst
tableau = rs.GetRows
rs.Close
End If
Bonjour Pierrep56,
En fait je ne rentre même pas dans ce code :
Else
tableau = rs.GetRows
rs.Close
End If
Mais dedans :
If rs.RecordCount < 1 Then
rs.Close
'Rien dans le recordset, on sort du programme
Call DeconnexionOracle
Exit Function
Car le recordset est vide ... alors qu'il ne devrait pas l'être ...
Ok,
Alors 2 tests possibles :
* vérifier que la connexion est correcte (cf connectionString, nom de la base, identifiant, mot de passe)
* placer le curseur à la fin avant de compter, et pour éviter les redondances, j'écrirai plutôt :
dim Nb as long
'...
rs.open truc_chouette ...
rs.movelast
Nb=rs.recordcount
rs.movefirst
if not Nb = 0 then tableau = rs.GetRows
rs.close
set rs = nothing ' c'est plus propre! ;)
Call DeconnexionOracle
end function
Et aussi, il faut que ta fonction retourne le tableau!
Function RemplirCelluleCO_CC(filtre As String, reste As Integer, tour As Integer) as variant()
' ...
' blabla
' ...
Call DeconnexionOracle
RemplirCelluleCO_CC=tableau
end function
Je viens de tester quelques chose pris sur un forum.
J'ai remplacé
rs.Open qry, cnx, adOpenKeyset, adLockOptimistic
par
rs.Open qry, cnx, 3, 1
Et ça a marché ... !
Il faut maintenant que je cherche à quoi correspondent le 3 (var CursorType) et 1 (LockType) pour comprendre pourquoi çà marche avec ces types choisis plutôt que adOpenKeyset (=1) et adLockOptimistic (=3)
Et merci pour le truc du
set rs = nothing
ok, super
Le 3 c'est très certainement adOpenStatic
Le 1 c'est un verrouillage : adLockReadOnly (?) possiblement je pense, et comme son nom l'indique bloque en lecture seule, donc pour des Insert ou Update, il faut déverrouiller en adLockOptimistic