A noterCet article s'applique à un système d'exploitation différent de celui que vous utilisez. Le contenu de l'article qui ne vous concerne peut-être pas est désactivé.
Lorsque vous utilisez le pilote Microsoft SQL Server ODBC et SQLSetPos permet d'insérer ou des valeurs de date ou heure mise à jour qui contiennent les valeurs autorisées maximales pour l'heure, minute, seconde et les portions de millisecondes (par exemple, 23:59:59:999 1999-10-03), l'instruction d'insertion réussit, mais des valeurs incorrectes sont enregistrées à la base de données.
Si vous essayez de sélectionner à nouveau les valeurs de date/heure, l'instruction génère une erreur ou qu'il renvoie des valeurs incorrectes, selon la façon dont le champ date/heure est liée. Si le champ est lié comme un SQL_C_TIMESTAMP, message d'erreur qui suit se produit :
SQLState = 22007 [Microsoft][Pilote ODBC SQL Server ODBC]Format d'heure non valide
Lorsque le champ est lié comme un SQL_C_CHAR, aucune erreur ne se produit ; toutefois, des valeurs incorrectes sont retournées, tels que 24:00:00.000 1999-10-03. Cela peut générer des erreurs dans l'application réceptrice car 24:00:00.000 n'est pas une valeur date/heure valide.
Cette erreur se produit avec la version de Windows 2000/MDAC 2.5 du pilote ODBC de SQL Server (version 3.70.820) et les versions antérieures.
Un correctif pris en charge est désormais disponible auprès de Microsoft, mais il ne vise qu'à corriger le problème décrit dans cet article. Uniquement l'appliquer aux systèmes rencontrant ce problème spécifique. Ce correctif peut subir des tests supplémentaires. Par conséquent, si vous n'êtes pas sérieusement concerné par ce problème, nous vous recommandons d'attendre le prochain service pack Microsoft Data Access Components qui comprendra ce correctif.
Pour résoudre ce problème immédiatement, contactez le support technique Microsoft pour obtenir le correctif. Pour obtenir une liste complète des numéros de téléphone support technique Microsoft, ainsi que des informations sur les frais de support technique, reportez-vous au site Web de Microsoft à l'adresse suivante :
Remarque : dans certains cas, frais généralement encourus de support technique par téléphone vous seront facturés si un technicien du support technique Microsoft détermine qu'une mise à jour spécifique peut résoudre votre problème. Les coûts de prise en charge par défaut s'appliqueront aux questions supplémentaires et aux problèmes qui ne relèvent pas de la mise à jour en question.
La version anglaise de ce correctif doit avoir les attributs de fichier suivants ou ceux d'une version ultérieure :
Date Version Size File name
-----------------------------------------------------
04/04/00 3.70.0784 24,848 bytes Odbcbcp.dll
04/04/00 3.70.0784 516,368 bytes Sqlsrv32.dll
Voici deux solutions de contournement potentielles pour ce problème :
Dans la mesure du possible, effectuez les insertions et mises à jour via des instructions SQL directes, puis permet à SQL Server de gérer la conversion des valeurs de date/heure.
- ou -
Si le stockage des millisecondes n'est pas nécessaire, définissez le champ comme un type de données smalldatetime au lieu de datetime. Le type de données smalldatetime uniquement utilise 4 octets pour le stockage et n'inclut pas de précision de la milliseconde.
Quittez les applications ou services qui utilisent le pilote ODBC de SQL Server, Sqlsrv32.dll. Il peut s'agir de Internet Information Server (IIS), Microsoft Transaction Server (MTS) et toutes les applications ODBC, Microsoft ActiveX Data Objects (ADO) ou OLE DB.
Téléchargez le correctif dans un répertoire temporaire.
Recherchez et renommez les versions actuelles des fichiers Sqlsrv32.dll et Odbcbcp.dll, qui doivent se trouver dans le dossier \Winnt\System32 pour les ordinateurs exécutant Microsoft Windows NT et dans le dossier \Windows\System pour les ordinateurs exécutant Microsoft Windows 95 et Microsoft Windows 98.
Copier les fichiers du correctif dans un même emplacement, puis redémarrez vos services et applications.
Copiez le code dans l'étape 2 dans une application de console Microsoft Visual C++ et ensuite compiler le code. Veuillez Notez que vous devrez peut-être modifier le nom de la source de données, id d'utilisateur et le mot de passe.
Exécutez le code et notez qu'une erreur se produit lors de la liaison la valeur de date/heure comme SQL_C_TIMESTAMP et qu'une valeur d'heure non valide est renvoyée lors de la liaison la valeur de date/heure comme SQL_C_CHAR.
#include <windows.h>
#include <stdio.h>
#include <sql.h>
#include <sqlext.h>
#include <time.h>
void CreateTable(HSTMT);
main()
{
// ODBC handles
RETCODE rc;
HENV henv;
HDBC hdbc;
HSTMT hstmt;
// Variables for SQLConnect
char * dsn = "Pubs";
char * uid = "sa";
char * pwd = "";
// Variables for SQLDiagRec
char mstate[6] = "\0";
long native = 0;
char mtext[300] = "\0";
short mlength = 0;
short i = 0;
// Variables for SQLBindCol
int m_ID = 1;
long m_idLen = 4;
TIMESTAMP_STRUCT m_time = {1999,10,03,23,59,59,999000000};
char m_timeChar[30] = "\0";
long m_timeLen = 16;
long sqlnts = SQL_NTS;
// miscellaneous variables
char * strSQL = "Select * from MillisecTest";
char * strDropTable = "Drop table MillisecTest";
unsigned short status = 0;
unsigned long rowcount = 0;
// Allocate ODBC handles and connect
rc = SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&henv);
rc = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3,0);
rc = SQLAllocHandle(SQL_HANDLE_DBC,henv, &hdbc);
rc = SQLConnect(hdbc, (unsigned char *)dsn,
SQL_NTS, (unsigned char *)uid,
SQL_NTS, (unsigned char *)pwd, SQL_NTS);
rc = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
// Table creation
CreateTable(hstmt);
// Set statement attributes so SQLSetPos can be used
rc = SQLSetStmtAttr( hstmt, SQL_ATTR_CONCURRENCY, (SQLPOINTER)SQL_CONCUR_LOCK, 0 );
rc = SQLSetStmtAttr( hstmt, SQL_ATTR_CURSOR_TYPE, (SQLPOINTER)SQL_CURSOR_KEYSET_DRIVEN, 0 );
// Bind the columns, using SQL_C_TIMESTAMP
rc = SQLBindCol(hstmt, 1, SQL_C_SHORT, &m_ID, 4, &m_idLen);
rc = SQLBindCol(hstmt, 2, SQL_C_TIMESTAMP, &m_time, sizeof(m_time), &m_timeLen);
// Execute the statement and use SQLSetPos to insert the date/time data
rc = SQLExecDirect(hstmt, (unsigned char *)strSQL, SQL_NTS);
rc = SQLExtendedFetch(hstmt, SQL_FETCH_NEXT, 1, &rowcount, &status );
rc = SQLSetPos(hstmt, 1, SQL_ADD, SQL_LOCK_NO_CHANGE);
SQLFreeStmt(hstmt, SQL_CLOSE);
memset(&m_time, 0, sizeof(m_time));
// Re-execute the statement, and attempt to fetch back the new date/time value
rc = SQLExecDirect(hstmt, (unsigned char *)strSQL, SQL_NTS);
rc = SQLExtendedFetch(hstmt, SQL_FETCH_NEXT, 1, &rowcount, &status );
SQLGetDiagRec(SQL_HANDLE_STMT, hstmt, 1, (unsigned char *)&mstate, &native,
(unsigned char *)&mtext, 300, &mlength);
printf("\nError when attempting to bind as SQL_C_TIMESTAMP:\n\n");
printf("\tSQLSTATE\t%s\n\tNative Error\t%i\n\tMessage\t%s\n\n",mstate, native, mtext);
SQLFreeStmt(hstmt, SQL_CLOSE);
// Bind the date/time column as SQL_C_CHAR this time
rc = SQLBindCol(hstmt, 2, SQL_C_CHAR, m_timeChar, sizeof(m_timeChar), &sqlnts);
rc = SQLExecDirect(hstmt, (unsigned char *)strSQL, SQL_NTS);
rc = SQLExtendedFetch(hstmt, SQL_FETCH_NEXT, 1, &rowcount, &status );
printf("\nInvalid hour when timestamp is bound as SQL_C_CHAR: %s\n\n", m_timeChar);
SQLFreeStmt(hstmt, SQL_CLOSE);
// Cleanup
SQLFreeStmt(hstmt, SQL_CLOSE);
SQLExecDirect(hstmt, (unsigned char *)strDropTable, SQL_NTS);
SQLFreeStmt(hstmt, SQL_CLOSE);
SQLFreeStmt(hstmt, SQL_DROP);
SQLDisconnect(hdbc);
SQLFreeConnect(hdbc);
SQLFreeEnv(henv);
printf("\nDo the \"Press any key\" thing...");
getchar();
return(TRUE);
};
//------- CreateTable() ----------------
void CreateTable(HSTMT hstmt)
{
RETCODE rc = 0;
char SqlStatements[2][90] =
{"Drop table MillisecTest",
"Create table MillisecTest (ID integer constraint index1 PRIMARY KEY, TimeTest datetime)"};
rc = SQLExecDirect(hstmt, (unsigned char *)SqlStatements[0], SQL_NTS);
SQLFreeStmt(hstmt, SQL_CLOSE);
rc = SQLExecDirect(hstmt, (unsigned char *)SqlStatements[1], SQL_NTS);
SQLFreeStmt(hstmt, SQL_CLOSE);
}
IMPORTANT : Cet article est issu du système de traduction automatique mis au point par Microsoft (http://support.microsoft.com/gp/mtdetails). Un certain nombre d?articles obtenus par traduction automatique sont en effet mis à votre disposition en complément des articles traduits en langue française par des traducteurs professionnels. Cela vous permet d?avoir accès, dans votre propre langue, à l?ensemble des articles de la base de connaissances rédigés originellement en langue anglaise. Les articles traduits automatiquement ne sont pas toujours parfaits et peuvent comporter des erreurs de vocabulaire, de syntaxe ou de grammaire (probablement semblables aux erreurs que ferait une personne étrangère s?exprimant dans votre langue !). Néanmoins, mis à part ces imperfections, ces articles devraient suffire à vous orienter et à vous aider à résoudre votre problème. Microsoft s?efforce aussi continuellement de faire évoluer son système de traduction automatique.
La version anglaise de cet article est la suivante: 259691
(http://support.microsoft.com/kb/259691/en-us/
)
L'INFORMATION CONTENUE DANS CE DOCUMENT EST FOURNIE PAR MICROSOFT SANS GARANTIE D'AUCUNE SORTE, EXPLICITE OU IMPLICITE. L'UTILISATEUR ASSUME LE RISQUE DE L'UTILISATION DU CONTENU DE CE DOCUMENT. CE DOCUMENT NE PEUT ETRE REVENDU OU CEDE EN ECHANGE D'UN QUELCONQUE PROFIT.
Ces informations vous ont-elles aidé ?
Oui
Non
Plutôt
Quel niveau d'effort avez-vous dû personnellement fournir pour utiliser cet article ?
Très faible
Faible
Moyen
Elevé
Très élevé
Dites-nous pourquoi et ce que nous pouvons faire pour améliorer ces informations.
Merci ! Vos commentaires sont très utiles pour l'amélioration de notre contenu d'aide et de support. Si vous avez besoin d'aide complémentaire, veuillez consulter la page d'accueil d'aide et support.