Numéro d'article: 259691 - Dernière mise à jour: mercredi 12 octobre 2005 - Version: 4.4

CORRECTIF : Message d'erreur «Format d'heure non valide» lors de l'insertion de date/heure avec les valeurs maximum

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é.

Sommaire

Agrandir tout | Réduire tout

Symptômes

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.

Cause

Une erreur dans l'algorithme qui convertit la date et l'heure est répercutant pas les heures de temps sur à la partie jours de la date.

Résolution

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 :
http://support.microsoft.com/contactus/?ws=support (http://support.microsoft.com/contactus/?ws=support)
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

				




Solution de contournement

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.

Statut

Microsoft a confirmé l'existence de ce bogue dans les produits Microsoft répertoriés au début de cet article.

Plus d'informations

Installation manuelle du fichier de correctif

  1. 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.
  2. Téléchargez le correctif dans un répertoire temporaire.
  3. 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.
  4. Copier les fichiers du correctif dans un même emplacement, puis redémarrez vos services et applications.

Procédure pour reproduire le problème

  1. 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.
  2. 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);
    
    
    }
    					

Les informations contenues dans cet article s'appliquent au(x) produit(s) suivant(s):
  • Microsoft Data Access Components 2.1 Service Pack 2
  • Microsoft Data Access Components 2.1 Service Pack 1
  • Microsoft Data Access Components 2.1 Service Pack 2
  • Microsoft Data Access Components 2.5
  • Pilote ODBC Microsoft pour Microsoft SQL Server 3.7
Mots-clés : 
kbmt kbhotfixserver kbqfe kbbug kbcodesnippet kbdatabase kbfix kbmdac210sp2fix kbqfe KB259691 KbMtfr
Traduction automatiqueTraduction automatique
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.