Récursivité en SQL + ADO

Résolu
Calade Messages postés 1207 Date d'inscription dimanche 20 avril 2003 Statut Membre Dernière intervention 4 juin 2016 - 16 juil. 2010 à 08:56
Calade Messages postés 1207 Date d'inscription dimanche 20 avril 2003 Statut Membre Dernière intervention 4 juin 2016 - 17 juil. 2010 à 09:08
Bonjour à tous,

Depuis quelques temps, je me heurte à un problème que je n'arrive pas à résoudre.

Je cherche à établir une fonction de contrôle des données d'alimentation pour une base SQL. Cette fonction tente de modifier la valeur du champ avec la nouvelle valeur saisie et "trappe" l'erreur éventuelle. Dans ce cas, une petite interface propose à l'utilisateur soit (pour une chaîne de caractères) de réduire sa longueur, soit d'augmenter la taille du champ qui la reçoit par un ALTER TABLE. Jusque là pas de soucis. Celui-ci vient après. Pour vérifier que les modifications ont été suffisantes, je refais une tentative d'alimentation par cette même fonction (récursivité) en lui fournissant le champ à l'aide d'un petit SELECT. Celui-ci fonctionne très bien mais toute tentative d'utilisation de champ reconstitué se solde par le message "Ce champ n'est plus valide", et si je regarde les propriétés du champ dans "Fenêtres Variables Locales" chaque valeur de propriété est remplacée par ce même message.

Voici des extraits de mon code:

Dans toute application je remplace la simple assignation par la fonction suivante (située dans une DLL personnelle):
   Call SQL_FillField(rstParams.Fields("PARM_KEY"), TParam.ParmKey)

Ci-dessous la fonction appelée:
Public Function SQL_FillField(ByRef oField As ADODB.Field, ByRef Value As Variant, _
                              Optional ByVal EnableAlterTable As Boolean = False) As Variant
   Dim oSQLTable As SQL_Tables:                             Set oSQLTable = New SQL_Tables
   Dim oRst As SQL_Recordset:                               Set oRst = New SQL_Recordset
   Dim oConn As SQL_Connection:                             Set oConn = New SQL_Connection
   Dim strSQL As String   
   On Error GoTo ErrorField
   
   oField.Value = Value
   Exit Function

ErrorField:
   FillField.Field2Fill p_oField2Fill:                           FillField.Value2Fill Value
   FillField.EnableAlterTable = EnableAlterTable:           FillField.Show vbModal
   If Not FillField.HasCancel Then
      If FillField.AlterTable Then
         Call oSQLTable.SQL_AlterTable(oField.Properties(COLPROP_COLUMNNAME).Value, FillField.FieldType, _
                                       FillField.FieldLength, BH_IsFlagActivate(Field.Attributes, adFldIsNullable), _
                                       oField.Properties(COLPROP_TABLENAME).Value, oField.Properties(COLPROP_DBNAME).Value)
                                             
         strSQL = "SELECT " & oField.Name & " FROM " & oField.Properties(COLPROP_TABLENAME).Value

         Set oField = oRst.SQL_RecordsetQuery(strSQL, oConn.SQL_ConnectOnTheFly(oField.Properties(COLPROP_DBNAME).Value)).Fields(oField.Name)

         End If

   End If
Les objets dimensionnés en début de fonction servent à utiliser les autres fonctions de cette DLL. Elle sert à manipuler sous forme de fonctions les différentes méthodes des objets ADO. Comme elles sont regroupés dans des modules de classe dédié à un objet particulier (Recordset, Connection, Field, etc...), ces définitions sont obligatoires pour un appel à l'intérieur même de la DLL, mais pas de l'extérieur (une simple référence suffit). Les propriétés référencées 
oField.Properties(COLPROP_DBNAME).Value
récupérent directement de l'objet Field le nom de la Table et de la DB sous-jacentes.
La fonction SQL_ConnectOnTheFly(oField.Properties(COLPROP_DBNAME).Value)) sert à établir une connection "on the fly" pour une base donnée et à l'abandonner tout de suite derrière (il n'y a pas de perte de temps en local, je modifierais ça évidemment à la mise en prod'.
J'ai essayé en déplaçant la reconstitution du champ dans la même fonction que l'ALTER, mais aucun changement. De même en utilisant une variable Private dans le module de classe ou Static dans la fonction, rien n'a résolu le problème.

Et la fonction appelant l'ALTER TABLE
Public Function SQL_AlterTable(ByVal FieldName As String, ByVal FieldType As String, ByVal FieldLength As Integer, _
                               ByVal NullAble As Boolean, ByVal TableName As String, ByVal DBName As String)
   Dim oRst As SQL_Recordset:                               Set oRst = New SQL_Recordset
   Dim oConn As SQL_Connection:                             Set oConn = New SQL_Connection
   Dim oDataType As SQL_DataTypes:                          Set oDataType = New SQL_DataTypes
   Dim rst As ADODB.Recordset
   Dim strSQL As String
   
   strSQL = "ALTER TABLE " & TableName
   strSQL = strSQL & " ALTER COLUMN " & FieldName
   strSQL = strSQL & " " & FieldType
   strSQL = strSQL & "(" & FieldLength & ")" & IIf(NullAble, " NULL", " NOT NULL")
   Call oRst.SQL_RecordsetQuery(strSQL, oConn.SQL_ConnectOnTheFly(DBName))
End Function
la fonction SQL_RecordsetQuery() effectue une requête, la plupart du temps un SELECT mais ici un ALTER.



Voilà, j'ai conscience que tout ceci n'est peut-être pas très clair, alors n'hésitez pas à me poser des questions.

Merci d'avance pour vos réponses.


Calade

2 réponses

Calade Messages postés 1207 Date d'inscription dimanche 20 avril 2003 Statut Membre Dernière intervention 4 juin 2016 10
17 juil. 2010 à 09:08
Salut et désolé de mon retard,

Non il ne s'agissait pas de cacher Server mais d'un petit détail que tu ne pouvais pas deviner.

Pour récupérer mon champ altéré, j'utilisais ma fonction:

Set oField oRst.SQL_RecordsetQuery(strSQL, oConn.SQL_ConnectOnTheFly(oField.Properties(COLPROP_DBNAME).Value))Set oField oRst.SQL_RecordsetQuery(strSQL, oConn.SQL_ConnectOnTheFly(oField.Properties(COLPROP_DBNAME).Value)).Fields(oField.Name)



Cette fonction perso' renvoyant un recordset je ne prenais que le champ du recordset (d'où le Set oField = .Fields(oField.Name) de la fin et apparemment c'est cela qui le dérangeait.

En récupérant cette fois tout le recordset puis en isolant le champ qui m'intéressait tout est rentré dans l'ordre.

En tout cas merci de ton aide.



Calade
3
nhervagault Messages postés 6063 Date d'inscription dimanche 13 avril 2003 Statut Membre Dernière intervention 15 juillet 2011 37
16 juil. 2010 à 14:57
Salut,

As-tu fermé la connexion entre les 3 ordres sql.
Surtout apres le ALTER.

Il y a peut etre du cache server qui traine?
0
Rejoignez-nous