FAQ ASP
FAQ ASPConsultez toutes les FAQ
Nombre d'auteurs : 6, nombre de questions : 44, dernière mise à jour : 15 juin 2021
- Comment déboguer une requête SQL ?
- Comment afficher une image provenant d'une base de données ?
- Pourquoi mon champ memo/text ne s'affiche pas le deuxième fois ?
- Erreur 80004005 lors d'une mise à jour ou d'une insertion dans une table
- Pourquoi RecordCount renvoi la valeur -1 ?
- Comment savoir si un enregistrement est vide ?
La première chose à faire est de tester votre requête directement dans le SGBD concerné. Si votre requête comporte des variables, testez-là en utilisant des valeurs possibles.
Ensuite, une fois que vous avez testé sa validité dans le SGBD, vous pouvez la recopier dans votre script ASP. Mais ce n'est pas fini! Avant de l'exécuter, vous allez tester qu'elle est toujours correctement écrite et que les variables sont bien remplies. Pour cela, il suffit de la faire afficher à l'écran avec la méthode Write de l'objet Response. Vous vous rendrez compte ainsi de sa validité et de sa similitude avec celle que vous avez précédemment testé dans le SGBD.
Une fois seulement ceci effectué, vous pouvez écrire le code qui exécute votre requête.
Voici quelques erreurs récurrentes qui font planter une requête dépendante de variables :
- Ne pas tester que les variables que l'on va injecter dans la requête sont bien remplies. Ceci arrive fréquemment avec les valeurs issues de variables session, car celles-ci ayant une durée de vie limitée (20 min. par défaut), il se peut que lors de vos tests vous perdiez cette variable session.
- Ne pas tester que le type des variables correspond au type des champs dans la table. Par défaut le type des valeurs récupérées dans les collections Querystring et Form est string (chaine de caractères). Un moyen simple de le vérifier est d'utiliser la fonction vbscript VarType(VarName) qui va invariablement renvoyer la valeur 8 qui correspond à la constante vbscript prédéfinie vbString. Il faut donc avant d'utiliser une variable dans une requête effectuer la conversion de type qui s'impose, en utilisant une des nombreuses fonctions de conversion que propose vbscript : CBool(), Cbyte(), CCur(), CDate(), CInt(), CLng(), CSng(), CStr().
Si vous avez enregistré vos images sous forme binaire dans un champ blob, le plus simple est de créer un fichier (show_image.asp) qui va s'occuper d'afficher les données binaires.
Il faut simplement préciser dans ce fichier quel type de contenu doit être envoyé au navigateur avec la propriété ContentType de l'objet Response et écrire les données binaires avec la méthode BinaryWrite de ce même objet.
Par exemple, on possède une table images avec les colonnes suivantes :
Notre procédure d'affichage va donc s'effectuer en 2 pages (fichiers)
La première page qui va être le document affiché à l'écran et la deuxième s'occupant de renvoyer l'image au document.
document.asp
- id_image entier auto_incrémenté => permet d'identifier de façon unique une image
- bin_image blob => va contenir les données binaires de l'image
- type_image texte => va contenir le type de l'image (image/gif, image/jpeg, image/png)
<html>
<head>
...
</head>
<body>
...
<img src
=
"show_image.asp?idimage=5"
>
...
</body>
</html>
On va ensuite récupérer le paramètre idimage dans le fichier show_image.asp grâce à la collection QueryString de l'objet Response.
show_image.asp
<%
' récupération du paramètre
idimage_get =
Request
.QueryString
(
"idimage"
)
' création de la connexion à la base de données
Set
conn =
Server
.CreateObject
(
"ADODB.Connection"
)
' ouverture de la connexion
conn.Open
chainedeconnexion ' chainedeconnexion est à préciser suivant votre sgbd et nom de base
' création de la requete
requete =
"SELECT type_image, bin_image FROM images WHERE idimage="
&
idimage_get
' exécution de la requête
Set
rs =
conn.Execute
(
requete)
' positionnement du content-type
Response
.ContentType
=
rs
(
"type_image"
)
' écriture du contenu du champ blob
Response
.BinaryWrite
(
rs
(
"bin_image"
))
' fermeture et destruction de la connexion
conn.close
Set
conn =
Nothing
%>
Lorsque vous exécutez une requête de sélection sur un champ memo/text et que vous essayez d'utiliser ensuite la valeur de ce champ contenue dans le recordset résultant - par exemple un test pour voir s'il est vide et si non l'affichage de ce champ - l'affichage reste vide. Ceci est dû à la façon dont les drivers ODBC traîtent les champs BLOB (Binary Large Object).
Quel rapport entre mon champ memo et un champ BLOB ? Et bien tout simplement le fait que les SGBD considèrent les champs memo/text comme des champs BLOB contenant du texte. Vous trouverez à cette adresse des liens vers des explications techniques avancées sur la façon de traiter les champs BLOB/memo/text et la résolution du problème qui nous intéresse ici.
Pour résumer rapidement les solutions proposées :
- Evitez d'utiliser la notation SELECT * FROM ... mais nommez les champs que vous voulez extraire, et nommez les champs BLOB/memo/text en dernier.
- Utilisez les champs dans l'ordre dans lequel vous les avez défini dans la requête ou mieux, stockez immédiatement dans une variable le contenu des champs BLOB/memo/text et travaillez ensuite sur cette variable.
- Mettez toujours à jour votre version de MDAC (Microsoft Data Access Components) en téléchargeant les dernières versions. .
Microsoft OLE DB Provider for ODBC Drivers (0x80004005)
[Microsoft][ODBC Microsoft Access Driver] Operation must use an updateable query.
La première chose à faire est de vérifier que vous avez les droits en écriture sur le répertoire où sont situés les fichiers visés, ainsi que sur ces mêmes fichiers.
En effet, IIS se sert par défaut de l'utilisateur IUSR_NOMORDI (NOMORDI étant le nom du serveur) pour accéder aux fichiers.
Dans la liste des utilisateurs, il s'appelle généralement "Compte invité Internet".
Cet utilisateur doit avoir les droits d'écriture sur tout ce que vous voulez modifier avec vos pages ASP, sinon l'opération ne se fera pas.
Pour des renseignements complémentaires, vous pouvez consulter l'article correspondant dans la base de connaissances du site de Microsoft.
Vous trouverez également d'autres liens (en français) sur les autres causes possibles d'une erreur 80004005 dans le post-it correspondant du forum ASP de developpez.com.
Par défaut, un recordset est ouvert en lecture seule (constante ADO adLockReadOnly = 1) et en avance seule (constante ADO adOpenForwardOnly = 0). Or, pour pouvoir compter le nombre de lignes renvoyées par l'exécution de la requête, le curseur doit pouvoir se déplacer dans les deux sens (en avant et en arière) afin d'être repositionné sur le premier enregistrement une fois le comptage effectué. Il faut donc paramétrer le recordset (avant ouverture ou lors de son ouverture) au minimum avec un curseur statique (constante ADO adOpenStatic = 3) ou par clés (constante ADO adOpenKeyset = 1) pour pouvoir utiliser la propriété ADO RecordCount.
En paramétrant la propriété ADO CursorType avant l'ouverture de l'objet Recordset :
<%
' Création de la connection au SGBD
...
' Création de l'objet Recordset
Set
objRS =
Server
.CreateObject
(
"ADODB.Recordset"
)
' paramétrage du type de curseur
objRS.CursorType
=
3
' paramétrage du type de verrou
objRS.LockType
=
1
' ouverture du Recordset
objRS.Open
query, objConn
%>
Directement à l'ouverture de l'objet Recordset :
<%
' Création de la connection au SGBD
...
' Création de l'objet Recordset
Set
objRS =
Server
.CreateObject
(
"ADODB.Recordset"
)
' ouverture du Recordset
objRS.Open
query, objConn, 3
, 1
%>
Vous pouvez retrouver les différentes constantes et leur valeur qu'il est possible d'utiliser avec les objets ADO dans les fichiers adovbs.inc et adojavas.inc.
Pour savoir si un recordset est vide, il faut tester si la propriété eof (end of file) et la propriété bof (begin of file) du jeu d'enregistrement sont vraies en même temps.
<%
if
(
RS.eof
and
RS.bof
) then
'traitement si vide
else
'traitement des résultats
end
if
%>