L'architecture d'accès aux données en ASP est la suivante :
| Composant | Type | Exemples |
|---|---|---|
| 1. Application ASP | Logique fonctionnelle | Fichiers *.asp |
| 2. ADO | API d'accès aux données | N/A (librairie standardisée) |
| 3. OLE DB | Provider / adaptateur | Provider=MSDASQL;Provider=Microsoft.ACE.OLEDB.12.0;Provider=SQLOLEDB; |
| 4. ODBC | Driver / pilote | Driver={MariaDB ODBC 3.2 Driver};Driver={MySQL ODBC 5.1 Driver}; |
| 5. Données | Fichier ou Moteur de Base de données | MariaDB Server 11.4 Microsoft SQL Server Fichier *.mdb Fichier *.xlsx |
Provider=MSDASQL ou est absent, soit via la bibliothèque cliente ou le protocole natif, par un Provider OLE DB natif situé en amont, lorsque la chaîne de connexion spécifie un Provider= différent de MSDASQL et qu'aucun paramètre ODBC (Driver= ou Dsn=) n'est présent.ADO utilise toujours un OLE DB Provider, qui est le composant logiciel implémentant l'interface OLE DB qui permet à une application utilisant ADO d'accéder à une source de données.
ADO ne communique jamais directement avec une base de données ni avec ODBC : il s'appuie toujours sur un OLE DB Provider, lequel joue le rôle d'intermédiaire technique entre ADO et le système d'accès aux données sous-jacent.
Selon la nature de la chaîne de connexion, le fournisseur OLE DB utilisé varie. Lorsque la chaîne de connexion est de type ODBC (présence de Driver=, Dsn=, ou Provider=MSDASQL), le OLE DB Provider implicitement utilisé est MSDASQL ("OLE DB Provider for ODBC"). Dans ce cas, MSDASQL traduit les appels OLE DB émis par ADO en appels ODBC, compréhensibles par le pilote ODBC ciblé (MySQL, MariaDB, MS SQL Server, MS Access, MS Excel, etc.).
À l'inverse, lorsque la chaîne de connexion ne fait aucune référence à ODBC (absence de Driver= ou Dsn=), ADO utilise alors un OLE DB Provider natif, conçu spécifiquement pour le moteur de base de données concerné (par exemple SQLOLEDB, MSOLEDBSQL, etc.), sans passer par ODBC ni par MSDASQL.
MSDASQL ("OLE DB Provider for ODBC") n'est utilisé implicitement que si la chaîne de connexion est de type ODBC (c'est-à-dire présence de Dsn=, ou Provider=MSDASQL). En l'absence de Provider= et de paramètres ODBC, ADO n'injecte pas automatiquement Provider=MSDASQL.
En résumé, OLE DB Provider peut être spécifié explicitement via Provider= dans la chaîne de connexion. À défaut, ADO déduit le provider à utiliser à partir du format de la chaîne de connexion : lorsque celle-ci est de type ODBC (présence de Driver= ou Dsn=), le provider implicitement utilisé est MSDASQL.
ADO (ActiveX Data Objects) est une bibliothèque d'accès aux données de Microsoft utilisée par ASP Classic pour manipuler des bases de données. C'est une couche d'abstraction légère au-dessus d'OLE DB permettant aux applications (notamment ASP Classic et VBScript) de se connecter à des sources de données hétérogènes, d'exécuter des requêtes et de manipuler des résultats via une API uniforme constituée d'objets comme Connection, Command et Recordset.
ADO est donc la couche logicielle qui crée les objets Connection ou Recordset, applique les propriétés CursorType, appelle les méthodes .Open(), .Execute(), .MoveNext(), .MoveLast(), et gère/renvoie la propriété RecordCount.
ADO n'est pas un driver ; il ne sait pas parler directement au serveur MySQL, MariaDB, Microsoft SQL Server, ou MS Access. Lorsqu'un script ASP interroge une base de données, ADO transmet la requête au Provider OLE DB que vous avez indiqué dans votre chaîne de connexion, ce dernier pouvant dialoguer avec le driver ODBC si vous en avez spécifié un via Driver=. Ce driver est le composant système chargé de dialoguer réellement avec le serveur de bases de données.
OLE DB est la couche d'adaptation entre ADO et la couche d'accès au données, cette dernière pouvant être soit un Driver ODBC, soit un Provider natif. OLE DB a pour rôle de standardiser les échanges entre ADO et cette couche d'accès aux données. OLE DB Provider for ODBC (MSDASQL) est un provider fourni par Microsoft qui sert de pont entre ADO et les drivers ODBC lorsque la chaîne de connexion cible un Driver ODBC via la présence de Driver=.
Son usage est soit explicite via l'instruction Provider= dans votre chaîne de connexion, soit implicitement Provider=MSDASQL par défaut s'il n'est pas spécifié ET que votre chaîne de connexion fait référence à un Driver ODBC spécifié au moyen du paramètre Driver=. En d'autres termes, si Provider= est absent de votre chaîne de connexion mais qu'un driver ODBC est requis via la présence de Driver=, ADO utilise alors implicitement MSDASQL en arrière-plan pour communiquer avec le Driver ODBC. Ce mécanisme permet un rétrocompatibilité avec les chaînes de connexion ODBC.
Retenez en permanence que ADO ne parle pas directement à ODBC : lorsqu'un script ASP utilise une chaîne de connexion avec Driver=, ADO passe par MSDASQL, qui traduit les appels OLE DB d'ADO en appels ODBC compréhensibles par le driver (MySQL, MariaDB, etc.).
Le Driver ODBC est le composant bas niveau qui dialogue réellement avec la base de données. De ce fait, lorsque ADO est utilisé via un fournisseur OLE DB pour ODBC (MSDASQL), ce dernier transmet ses demandes (requêtes, curseurs, verrous) au driver ODBC, qui est en charge de les appliquer ou de les adapter selon ses capacités
Chaque Driver ODBC est conçu par un fournisseur différent et est adapté aux capacités et fonctionnalités prévues par le moteur de base de données ciblé. Ceci explique les comportements parfois différents que l'on peut observer avec un code source identique, mais un moteur de base de données différent, ou un Driver ODBC différent, ou encore une version différente d'une série de Drivers ODBC, malgré des appels ADO strictement identiques en amont.
En ADO, les types de curseurs (0=Forward-Only, 3=Static, 1=Keyset, 2=Dynamic) définissent de quelle manière un Recordset est parcouru et maintenu dans la mémoire côté ASP, ou dans la mémoire du serveur de bases de données. Ces types de curseurs ont donc un impact direct sur les performances, la consommation mémoire et les fonctionnalités disponibles à votre Recordset.
Le choix du curseur conditionne ainsi la capacité à se déplacer dans le Recordset, à compter les lignes, à voir les changements concurrents et à tenir la charge côté serveur ou client. La maîtrise des curseurs ADO est à ce titre indispensable.
Les types de curseurs ADO sont les suivants :
Documentation officielle Microsoft :
Au-delà des considérations de performances ou d'utilisation mémoire, le critère principal lors du choix d'un curseur est la manière dont vous comptez le parcourir. Vous devez choisir parmi les deux options suivantes :
Le type de curseur ADO que vous utilisez lors de l'accès à un Recordset détermine grandement les possibilités qui sont offertes à votre code pour parcourir et manipuler les données. Le type de curseur 0=adOpenForwardOnly est celui utilisé par défaut lorsque vous utilisez la méthode rs.Open() sans spécifier la propriété rs.CursorType, ou bien lorsque vous utilisez la méthode dbConn.Execute().
Lorsque l'ouverture de votre Recordset est effectuée sans spécifier explicitement le type de curseur, et selon la taille des données retournées par votre requête d'une part, et le Driver ODBC utilisé en aval d'autre part, il existe un risque que le Driver ODBC décide parfois :
Il est important de noter que ADO définit une intention, mais que c'est toujours le Driver ODBC qui décide en aval de la réalité du curseur qu'il utilisera.
Le Driver ODBC reste en effet libre de choisir implicitement un autre type de curseur que celui que vous avez spécifié s'il le juge nécessaire, ceci étant dans les spécifications officielles de la norme ADO.
Ce genre de situations est en général peu courant, ou non problématique : le Driver ODBC respecte généralement le curseur demandé, mais certains Drivers ODBC émulent dans certains cas un curseur serveur, ce qui peut provoquer une consommation mémoire importante sur les jeux de données conséquents.
Si votre site comporte des pages PHP qui accèdent à des bases de données MySQL ou MariaDB, sachez qu'elles n'utilisent presque jamais ODBC par défaut, sauf si vous l'avez explicitement codé ainsi dans certaines situations spécifiques. Vos pages PHP se connectent généralement à vos bases de données au travers de l'une des méthodes suivantes :
PHP peut utiliser ADO via COM (uniquement sous Windows) dans des contextes hérités/legacy Windows/ADO ou des besoins très ciblés. Ces connections sont appellées de la manière suivante :
<?php
$conn = new COM("ADODB.Connection");
$conn->Open("Provider=MSOLEDBSQL;Server=localhost;Database=TestDB;Trusted_Connection=Yes;");
?>Si votre site comporte des pages exécutées par la plateforme ASP.NET pour accéder à des bases de données MySQL ou MariaDB, sachez qu'elles n'utilisent pas ADO, mais ADO.NET. Vos pages .NET se connectent généralement à vos bases de données au travers de l'une des méthodes suivantes :
SqlConnection, SqlCommand, SqlDataReader, DataSet)Lorsque vous accédez à des données via ADO et un Driver ODBC (ou un Provider OLE DB natif), vous souhaitez vous assurer que votre code ASP fonctionne correctement sans générer d'erreur serveur (HTTP 500). Certaines pratiques permissives ont historiquement été utilisées en développement ASP Classic, pouvant parfois conduire à des erreurs d'exécution ou provoquer des comportements différents selon le Provider OLE DB ou le Driver ODBC utilisé (ou encore sa version installée sur le serveur d'hébergement).
ADO est une interface statique, fiable et prévisible, incluse sous Windows + IIS. Vos sites ASP peuvent donc compter dessus.
En revanche, les Providers OLE DB et les Drivers ODBC, eux, évoluent périodiquement. Ceux que vous utilisez ou avez utilisé par le passé pour accéder aux données via ADO peuvent avoir des comportements différents selon les moteurs de bases de données ou les versions du Provider/Driver. Cela peut conduire à des situations où le même code source provoque des erreurs sur certains serveurs ou avec certains Drivers, et pas avec d'autres.
Afin de rendre votre code ASP Classic fiable et à l'épreuve du futur lorsqu'il accède à des données via ADO, et ce quel que soit le Driver ODBC utilisé, votre code doit idéalement être développé en respectant les bonnes pratiques suivantes. Ces dernières consistent à correctement spécifier explicitement les types de curseurs dans votre code ASP, afin d'obtenir des résultats et fonctionnalités prévisibles sur votre Recordset.
Ce tableau présente les principales méthodes et propriétés ADO autorisées et déconseillées selon chaque type de curseur ADO (CursorType).
| Méthode / Propriété ADO | 0=Forward-Only (par défaut) | 3=Static | 1=Keyset | 2=Dynamic |
|---|---|---|---|---|
| MoveNext | Oui | Oui | Oui | Oui |
| MoveFirst | Non | Oui | Oui | Oui |
| MoveLast | Non (ou comportement non garanti) | Oui | Oui | Oui |
| MovePrevious | Non | Oui | Oui | Oui |
| AbsolutePosition | Non | Oui | Oui | Oui |
| PageSize / PageCount / AbsolutePage | Non | Oui | Oui | Oui |
| RecordCount | Inexploitable (renvoie -1) | Fiable | Fiable | Fiable |
| Bookmark / Supports(adBookmark) | Non | Oui | Oui | Oui |
| Sort | Non (provoque bascule client-side) | Oui (client-side stable) | Oui | Oui |
| Filter | Non (provoque bascule client-side) | Oui | Oui | Oui |
| Édition (Update, AddNew, Delete) | Non (Read-Only) | Oui (mais snapshot) | Oui (lignes visibles) | Oui (réactif) |
| Voir les nouvelles lignes insérées après l'ouverture | Non | Non | Non | Oui |
| Stabilité concurrentielle des données | Très élevée (flux figé) | Élevée (snapshot) | Moyenne | Faible |
Tous les types de curseurs, y-compris le CursorType 0=adOpenForwardOnly vous permettent de faire usage des méthodes et propriétés suivantes :
Votre Recordset est ouvert en mode "0=Forward-Only" lorsque :
dbConn.Execute()rs.Open() sans avoir précédemment spécifié le type de curseur dans la propriété rs.CursorType. ADO utilise alors le type de curseur par défaut, à savoir 0=adOpenForwardOnly. Le Recordset ne permet dans ce cas qu'une lecture séquentielle.Exemples d'ouverture en mode "0=Forward-Only" (surlignés en jaune) :
<%
'Ouvrir la connection
Set dbConn = Server.CreateObject("ADODB.Connection")
dbConn.Open dbConnString
'Ouvrir le Recordset en mode "Forward-Only" via .Open()
Set rs = Server.CreateObject("ADODB.Recordset")
rs.Open strSQL, dbConn
''Ou bien : ouvrir le Recordset en mode "Forward-Only" via .Execute()
'Set rs = dbConn.Execute(strSQL)
%>Les seules les méthodes et propriétés disponibles sur votre Recordset ouvert en mode 0=Forward-Only sont :
Ne comptez par sur .RecordCount, qui renverra toujours -1. Recherchez dans votre code tous les usages de la propriété .RecordCount, et assurez-vous que le Recordset a été ouvert avec rs.Open() + un rs.CursorType différend de 0, et qu'il n'a pas été ouvert avec dbConn.Execute().
Le seul test robuste et indépendant du type de curseur qui vous permet de vous assurer de la présence d'enregistrements dans votre Recordset est le suivant :
<%
'Si le Recordset contient des enregistrements
if ((NOT rs.BOF) AND (NOT rs.EOF)) then
do while NOT rs.EOF
'Renvoyer la valeur du champ "field_1"
Response.Write rs("field_1")
'Passer à l'enregistrement suivant
rs.MoveNext
loop
end if
%>Les opérations de déplacement de type rs.MovePrevious() ou rs.MoveLast() peuvent parfois fonctionner lorsque votre Recordset est ouvert en mode 0=Forward-Only. Cela se produit si vous n'avez pas spécifié le rs.CursorType, mais que vous avez indiqué rs.CursorLocation=3 (adUseClient). Dans ce cas, ADO peut décider de mettre le recordset en cache client, ce qui transforme implicitement le curseur et le rend scrollable/déplaçable.
Toutefois ce comportement n'est pas garanti, et cela reste incohérent avec la définition même d'un curseur 0=Forward-Only. Vous ne devez donc pas faire reposer votre logique de code sur ce cas particulier : spécifier explicitement un rs.CursorType autre que 0=adOpenForwardOnly reste la méthode la plus sûre.
Si vous devez faire usage de la propriété .RecordCount, ou bien si vous avez besoin de filtrer ou vous déplacer dans le Recordset (ex. .Filter, .PageSize, .MovePrevious), vous devez alors impérativement utiliser la méthode rs.Open() en spécifiant le .CursorType. Vous obtiendrez alors un Recordset scrollable/déplaçable.
Lorsque vous utilisez la méthode rs.Open(), vous devez impérativement spécifier auparavant le type de curseur dans la propriété rs.CursorType. Procédez de la manière suivante :
<%
Set rs = Server.CreateObject("ADODB.Recordset")
'Spécifier le type de curseur
rs.CursorLocation = 3 'adUseClient (de préférence, car les curseurs côté serveur dépendent du Driver ODBC)
rs.CursorType = 3 'adOpenStatic (ou bien 1 ou 2 selon vos besoins)
rs.LockType = 1 'adLockReadOnly (le plus rapide si aucune écriture)
'Ouvrir le Recordset de manière scrollable/déplaçable
rs.Open strSQL, dbConn
%>À l'exception du rs.CursorType = 0 'adOpenForwardOnly, tous les autres types de curseurs vous permettent bénéficier d'un Recordset scrollable/déplaçable — rs.CursorType = 3 'adOpenStatic étant préférable. Vous pouvez alors faire usage des méthodes et propriétés suivantes :
Vous disposez désormais de l'accès à la propriété .RecordCount, et pouvez alors tester le nombre d'enregistrements contenus dans le Recordset :
<%
'Le recordset a été mis en cache mémoire côté client grâce au rs.CursorType différend de 0
'La propriété .Recordcount et donc calculable et reflète le nombre réel de lignes récupérées
if (rs.RecordCount <> 0) then
'Faire quelquechose
end if
%>Si vous avez uniquement besoin de lire les résultats l'un après l'autre de manière séquentielle, vous pouvez alors omettre cette propriété CursorType : ADO utilisera alors le type de curseur par défaut, à savoir 0=adOpenForwardOnly. Vous pouvez également dans ce cas faire un simple appel à dbConn.Execute().
Lorsque vous ouvrez un Recordset en vue de le trier, le filtrer ou vous déplacer d'avant en arrière, utilisez uniquement le CursorType = 3 'adOpenStatic.
Bien qu'en pratique, tous les curseurs autres que rs.CursorType = 0 'adOpenForwardOnly vous permettent ces opérations, cela n'est dû qu'au fait que vous avez indiqué à ADO un curseur côté client avec rs.CursorLocation = 3 'adUseClient. ADO met alors les données en cache via le Microsoft Cursor Engine . Ce comportement dépend en réalité des 3 couches suivantes :
Afin de vous prémunir contre tout effet indésirable dans votre code, et le rendre résistant à l'épreuve du futur, seul le CursorType = 3 'adOpenStatic vous permet de faire un usage fiable et prévisible des méthodes et propriétés suivantes :
Le CursorType = 3 'adOpenStatic possède les caractéristiques suivantes :
Le CursorType = 3 'adOpenStatic est donc le seul type de curseur qui :
Les CursorType = 1 'adOpenKeyset ou 2 = adOpenDynamic peuvent quant à eux fonctionner, mais tenez compte des points suivants :
Les opérations de tri et filtrage d'un Recordset ne fonctionnent correctement qu'avec un curseur côté client rs.CursorLocation = 3 'adUseClient. Les curseurs côté moteur de base de données ne supportent pas ces opérations.
Le Driver ODBC Microsoft SQL Server fournit un support réel et optimal du curseur Forward-Only côté serveur. Lorsque vous spécifiez un autre type de curseur via la propriété rs.CursorType, celui-ci est respecté.
Différentes options sont disponibles pour établir la connexion à vos bases MSSQL (lien externe ).
Le Driver ODBC Microsoft Access émule souvent en mémoire (bufferisation) le curseur Forward-Only. Les performances sont correctes sur des jeux de données de taille modeste. Lorsque vous spécifiez un autre type de curseur via la propriété rs.CursorType, celui-ci est respecté.
Différentes options sont disponibles pour établir la connexion à vos bases Microsoft Access (lien externe ).
Le Driver ODBC MySQL 3.51 / 5.3 charge fréquemment l'intégralité du jeu de données en mémoire (bufferisation) afin d'émuler le curseur Forward-Only, le pilote ODBC MySQL n'ayant historiquement pas de vrai curseur côté serveur. L'utilisation de la mémoire et les performances peuvent être dégradées avec des jeux de données importants.
La norme ODBC requiert que chaque Driver ODBC utilise par défaut un curseur Forward-Only (SQL_CURSOR_FORWARD_ONLY) si le type de curseur n'est pas fourni dans les OPTION lors de l'établissement de la connexion à la base de données via ADO.Connection, ou lors de l'ouverture du ADODB.Recordset via la propriété rs.CursorType.
Le Driver {MySQL ODBC 3.51 Driver} (MySQL Connector/ODBC 3.51) implémente l'interface ODBC 3.5x, et supporte donc les fonctionnalités ODBC v3, mais pas strictement ODBC 3.8.
En pratique, le type de curseur 0=adOpenForwardOnly est utilisé par défaut par ADO avant l'établissement de la connexion ODBC lorsque vous utilisez la méthode rs.Open() sans spécifier la propriété rs.CursorType, ou bien lorsque vous utilisez la méthode dbConn.Execute(). En effet, ADO intervient en amont du Driver ODBC, dont la valeur par défaut ne serait utilisée que si la couche au‑dessus (càd ADO) ne spécifiait rien. ADO ne laisse jamais la main au Driver ODBC, et spécifie par défaut un curseur Forward-Only si vous n'avez pas réglé explicitement la propriété rs.CursorType.
De ce fait, le curseur par défaut du Driver ODBC n'est jamais utilisé avec ADO, qui prime. Si votre code ASP Classic a toujours fonctionné correctement avec le Driver {MySQL ODBC 3.51 Driver} utilisé via ADO, il est quasiment certain qu'il fonctionnera de manière identique avec d'autres versions de Drivers ODBC MySQL ou MariaDB, puisque ADO respectera vos choix via rs.CursorType, ou utilisera à défaut le curseur 0=adOpenForwardOnly comme il l'a toujours fait.
ADO spécifie bien évidemment au Driver ODBC les autres types de curseurs si vous en spécifiez un de manière explicite dans la propriété rs.CursorType. Gardez à l'esprit que le Driver ODBC peut dans certains cas utiliser et retourner un autre type de curseur : la norme ADO le permet. Il est donc prudent de vous assurer que votre code source ASP Classic respecte les bonnes pratiques suivantes.
Le Driver {MySQL ODBC 5.3 Unicode Driver} (MySQL Connector/ODBC 5.3) implémente l'interface ODBC 3.8 de manière stricte, y-compris pour ses variantes Unicode et ANSI. Cela signifie qu'il utilise par défaut un curseur Forward-Only (SQL_CURSOR_FORWARD_ONLY) si le type de curseur n'est pas fourni dans les OPTION lors de l'établissement de la connexion à la base de données via ADO.Connection, ou lors de l'ouverture du ADODB.Recordset via la propriété rs.CursorType.
En pratique, le type de curseur 0=adOpenForwardOnly est utilisé par défaut par ADO avant l'établissement de la connexion ODBC lorsque vous utilisez la méthode rs.Open() sans spécifier la propriété rs.CursorType, ou bien lorsque vous utilisez la méthode dbConn.Execute(). En effet, ADO intervient en amont du Driver ODBC, dont la valeur par défaut ne serait utilisée que si la couche au‑dessus (càd ADO) ne spécifiait rien. ADO ne laisse jamais la main au Driver ODBC, et spécifie par défaut un curseur Forward-Only si vous n'avez pas réglé explicitement la propriété rs.CursorType.
De ce fait, le curseur par défaut du Driver ODBC n'est jamais utilisé avec ADO, qui prime. Si votre code ASP Classic a toujours fonctionné correctement avec le Driver {MySQL ODBC 5.3 Unicode Driver} utilisé via ADO, il est quasiment certain qu'il fonctionnera de manière identique avec d'autres versions de Drivers ODBC MySQL ou MariaDB, puisque ADO respectera vos choix via rs.CursorType, ou utilisera à défaut le curseur 0=adOpenForwardOnly comme il l'a toujours fait.
ADO spécifie bien évidemment au Driver ODBC les autres types de curseurs si vous en spécifiez un de manière explicite dans la propriété rs.CursorType. Gardez à l'esprit que le Driver ODBC peut dans certains cas utiliser et retourner un autre type de curseur : la norme ADO le permet. Il est donc prudent de vous assurer que votre code source ASP Classic respecte les bonnes pratiques suivantes.
Lorsque vous ne spécifiez par le type de curseur, ou que vous indiquez explicitement le curseur Forward-Only, il est possible de demander au Driver ODBC MySQL utilisé via ADO de ne pas mettre en mémoire le jeu d'enregistrements complet côté client, mais de réellement parcourir le jeu d'enregistrements ligne par ligne côté moteur de bases de données. Il s'agit d'un mode "streaming" réel.
Les données ne sont pas chargées d'un seul coup côté ASP, mais ligne par ligne lors de chaque appel à rs.MoveNext(). La requête SQL n'est pas ré-exécutée à chaque appel à rs.MoveNext(), mais n'est exécutée qu'une seule fois : le Driver ODBC récupère les lignes au fil de l'eau depuis le serveur, selon un mécanisme équivalent au modèle mysql_use_result(). Chaque appel à rs.MoveNext() constitue un “fetch” (une lecture) qui lit la suite du flux. L'intérêt est une diminution de l'utilisation de la mémoire côté client (moteur ASP) car le Driver ne met pas en cache l'intégralité du Recordset.
Notez que l'usage de cette technique comporte un désagrément : pendant que vous consommez ce flux, la connexion est “bloquée”. Vous devez donc finir de lire puis libérer le résultat avant d'exécuter autre chose sur la même connexion, ce qui peut mobilier les ressources côté serveur durant plus longtemps.
Notez que l'usage de cette technique est compatible mais inutile lors de l'utilisation de la méthode ADO rs.GetRows(). En effet la méthode ADO rs.GetRows() copie toutes les lignes restantes (option adGetRowsRest) dans un tableau en mémoire, ce qui fait de-facto perdre l'avantage de la faible utilisation de la mémoire de cette méthode de "streaming". En effet, la méthode rs.GetRows() a pour effet de faire porter l'intégralité de la charge mémoire côté ASP, sous forme de tableau (Array 2D).
Pour mettre en œuvre cette technique vous devez activer un curseur Forward-Only et désactiver le cache côté Driver MySQL.
Ajoutez la valeur des Flags suivants au paramètre OPTION de votre chaîne de connexion :
1048576 (NO_CACHE)2097152 (FORWARD_CURSOR)Si vous établissez votre connexion via un DSN, vous devrez peut-être ajouter Provider=MSDASQL; DSN=MonDSN; à votre chaîne de connexion. Toutefois, l'ajout explicite de Provider=MSDASQL; à votre chaîne de connexion est inutile dans le cas d'une connexion DSN-Less établie depuis votre code ASP.
Le Driver ODBC MariaDB 3.1 / 3.2 charge fréquemment l'intégralité du jeu de données en mémoire (bufferisation) afin d'émuler le curseur Forward-Only, le pilote ODBC MariaDB n'ayant historiquement pas de vrai curseur côté serveur. L'utilisation de la mémoire et les performances peuvent être dégradées avec des jeux de données importants.
La norme ODBC requiert que chaque Driver ODBC utilise par défaut un curseur Forward-Only (SQL_CURSOR_FORWARD_ONLY) si le type de curseur n'est pas fourni dans les OPTION lors de l'établissement de la connexion à la base de données via ADO.Connection, ou lors de l'ouverture du ADODB.Recordset via la propriété rs.CursorType.
Le Driver {MariaDB ODBC 3.1 Driver} implémente l'interface ODBC 3 et en supporte donc les fonctionnalités, mais pas strictement ODBC 3.8.
En particulier, le Driver {MariaDB ODBC 3.1 Driver} utilise par défaut un curseur statique (SQL_CURSOR_STATIC), ce qui diffère de la norme ODBC 3.8.
En pratique, le type de curseur 0=adOpenForwardOnly est utilisé par défaut par ADO avant l'établissement de la connexion ODBC lorsque vous utilisez la méthode rs.Open() sans spécifier la propriété rs.CursorType, ou bien lorsque vous utilisez la méthode dbConn.Execute(). En effet, ADO intervient en amont du Driver ODBC, dont la valeur par défaut ne serait utilisée que si la couche au‑dessus (càd ADO) ne spécifiait rien. ADO ne laisse jamais la main au Driver ODBC, et spécifie par défaut un curseur Forward-Only si vous n'avez pas réglé explicitement la propriété rs.CursorType.
De ce fait, le curseur par défaut du Driver ODBC n'est jamais utilisé avec ADO, qui prime. Si votre code ASP Classic a toujours fonctionné correctement avec le Driver {MariaDB ODBC 3.1 Driver} utilisé via ADO, il est quasiment certain qu'il fonctionnera de manière identique avec d'autres versions de Drivers ODBC MySQL ou MariaDB, puisque ADO respectera vos choix via rs.CursorType, ou utilisera à défaut le curseur 0=adOpenForwardOnly comme il l'a toujours fait.
ADO spécifie bien évidemment au Driver ODBC les autres types de curseurs si vous en spécifiez un de manière explicite dans la propriété rs.CursorType. Gardez à l'esprit que le Driver ODBC peut dans certains cas utiliser et retourner un autre type de curseur : la norme ADO le permet. Il est donc prudent de vous assurer que votre code source ASP Classic respecte les bonnes pratiques suivantes.
Le Driver {MariaDB ODBC 3.2 Driver} implémente l'interface ODBC 3.8 de manière stricte. Cela signifie qu'il utilise par défaut un curseur Forward-Only (SQL_CURSOR_FORWARD_ONLY) si le type de curseur n'est pas fourni dans les OPTION lors de l'établissement de la connexion à la base de données via ADO.Connection, ou lors de l'ouverture du ADODB.Recordset via la propriété rs.CursorType.
Cet alignement avec la norme ODBC 3.8 diffère du comportement qui était précédemment observé avec le Driver {MariaDB ODBC 3.1 Driver}, qui utilisait par défaut un curseur statique (SQL_CURSOR_STATIC). Cet alignement du Driver MariaDB 3.2 sur la norme ODBC 3.8 a pour conséquence des accès aux bases plus rapides et plus fiables qu'avec la précédente version 3.1 du Driver ODBC.
Ce changement est documenté dans les notes de version du Driver ODBC 3.2 de MariaDB, en ces termes :
ODBC-290 = Cursor type now defaults to SQL_CURSOR_FORWARD_ONLY as it is required by specs. 3.1.x series has default cursor type SQL_CURSOR_STATIC.
En pratique, le type de curseur 0=adOpenForwardOnly est utilisé par défaut par ADO avant l'établissement de la connexion ODBC lorsque vous utilisez la méthode rs.Open() sans spécifier la propriété rs.CursorType, ou bien lorsque vous utilisez la méthode dbConn.Execute(). En effet, ADO intervient en amont du Driver ODBC, dont la valeur par défaut ne serait utilisée que si la couche au‑dessus (càd ADO) ne spécifiait rien. ADO ne laisse jamais la main au Driver ODBC, et spécifie par défaut un curseur Forward-Only si vous n'avez pas réglé explicitement la propriété rs.CursorType.
De ce fait, le curseur par défaut du Driver ODBC n'est jamais utilisé avec ADO, qui prime. Si votre code ASP Classic a toujours fonctionné correctement avec le Driver {MySQL ODBC 5.3 Unicode Driver} utilisé via ADO, il est quasiment certain qu'il fonctionnera de manière identique avec d'autres versions de Drivers ODBC MySQL ou MariaDB, puisque ADO respectera vos choix via rs.CursorType, ou utilisera à défaut le curseur 0=adOpenForwardOnly comme il l'a toujours fait.
ADO spécifie bien évidemment au Driver ODBC les autres types de curseurs si vous en spécifiez un de manière explicite dans la propriété rs.CursorType. Gardez à l'esprit que le Driver ODBC peut dans certains cas utiliser et retourner un autre type de curseur : la norme ADO le permet. Il est donc prudent de vous assurer que votre code source ASP Classic respecte les bonnes pratiques suivantes.
Lorsque vous ne spécifiez par le type de curseur, ou que vous indiquez explicitement le curseur Forward-Only, il est possible de demander au Driver ODBC MariaDB utilisé via ADO de ne pas mettre en mémoire le jeu d'enregistrements complet côté client, mais de réellement parcourir le jeu d'enregistrements ligne par ligne côté moteur de bases de données. Il s'agit d'un mode "streaming" réel.
Cette fonctionnalité est disponible depuis la version 3.1.17 du Driver ODBC MariaDB, comme indiqué dans la documentation de MariaDB .
Les données ne sont pas chargées d'un seul coup côté ASP, mais ligne par ligne lors de chaque appel à rs.MoveNext(). La requête SQL n'est pas ré-exécutée à chaque appel à rs.MoveNext(), mais n'est exécutée qu'une seule fois : le Driver ODBC récupère les lignes au fil de l'eau depuis le serveur, selon un mécanisme équivalent au modèle mysql_use_result(). Chaque appel à rs.MoveNext() constitue un “fetch” (une lecture) qui lit la suite du flux. L'intérêt est une diminution de l'utilisation de la mémoire côté client (moteur ASP) car le Driver ne met pas en cache l'intégralité du Recordset.
Notez que l'usage de cette technique est compatible mais inutile lors de l'utilisation de la méthode ADO rs.GetRows(). En effet la méthode ADO rs.GetRows() copie toutes les lignes restantes (option adGetRowsRest) dans un tableau en mémoire, ce qui fait de-facto perdre l'avantage de la faible utilisation de la mémoire de cette méthode de "streaming". En effet, la méthode rs.GetRows() a pour effet de faire porter l'intégralité de la charge mémoire côté ASP, sous forme de tableau (Array 2D).
L'usage de cette technique avec le Driver MariaDB ODBC 3.1 comporte un désagrément : pendant que vous consommez ce flux, la connexion est “bloquée”. Vous devez donc finir de lire puis libérer le résultat avant d'exécuter autre chose sur la même connexion, ce qui peut mobilier les ressources côté serveur durant plus longtemps.
L'usage de cette technique avec le Driver MariaDB ODBC 3.2 améliore significativement le désagrément précédemment présent dans le Driver MariaDB ODBC 3.1. En effet, comme indiqué dans les notes de version , le Driver 3.2.1 (et suivants) améliore la résilience du protocole lors du traitement en continu des résultats. Là où, dans la version 3.1, l'utilisation du traitement en continu des résultats bloquait la connexion et renvoyait une erreur lors de toute nouvelle requête, le Driver 3.2.1 met désormais en cache le reste des résultats en cours de traitement, et exécute sans attendre toute nouvelle requête sans erreur. Cette amélioration apporte une connexion ininterrompue et renforce la fiabilité du Driver.
Pour mettre en œuvre cette technique vous devez activer un curseur Forward-Only et désactiver le cache côté Driver MariaDB.
Ajoutez la valeur des Flags suivants au paramètre OPTION de votre chaîne de connexion :
1048576 (NO_CACHE)2097152 (FORWARD_CURSOR)Ou bien ajoutez ces paramètres à votre chaîne de connexion :
FORWARDONLY=1;NO_CACHE=1;Si vous établissez votre connexion via un DSN, vous devrez peut-être ajouter Provider=MSDASQL; DSN=MonDSN; à votre chaîne de connexion. Toutefois, l'ajout explicite de Provider=MSDASQL; à votre chaîne de connexion est inutile dans le cas d'une connexion DSN-Less établie depuis votre code ASP.
Nous vous assistons avec IIS et votre code ASP Classic.
Prenez contact avec notre équipe.
NOTE : Vos changements seront appliqués dès la prochaine page que vous visiterez/chargerez.
En utilisant ce site, vous acceptez que nous utilisions des statistiques anonymes pour analyser notre trafic et améliorer votre expérience de navigation sur notre site, ainsi que des technologies et cookies pour personnaliser le contenu. Ces informations anonymes peuvent être partagées avec nos partenaires de médias sociaux et d'analyse de confiance.