文章編號: 259691 - 上次校閱: 2005年10月12日 - 版次: 4.4
FIX: 錯誤訊息 「 無效的時間格式 」 當您插入日期/時間與最大值
系統提示 本文適用於您使用的作業系統之外的作業系統。與您不相關的文章內容已停用。
當您使用 Microsoft SQL Server ODBC 驅動程式,而且您使用
SQLSetPos 來插入或為小時、 分鐘、 秒及毫秒部分 (如 「 1999年-10-03 23:59:59:999) 包含最大允許值的更新日期或時間值,插入陳述式會成功,但不正確的值儲存到資料庫。
如果您嘗試重新選取日期/時間值返回,陳述式會產生錯誤或傳回不正確的值取決於 [日期/時間] 欄位所繫結。如果 [] 欄位結合成一個 SQL_C_TIMESTAMP,就會發生錯誤訊息下列敘述所示:
SQLState = 22007 [Microsoft][ODBC SQL Server ODBC 驅動程式]時間格式不正確
欄位繫結為一個 SQL_C_CHAR 時, 不會發生錯誤 ; 然而,不正確的值會傳回,1999年-10-03 24:00:00.000 等。這可以接收的應用程式中產生錯誤,因為 24:00:00.000 不是有效的日期/時間值。
與 Windows 2000/MDAC 2.5 組建的 SQL Server ODBC 驅動程式 (版本 3.70.820) 或更早版本,就會發生這個錯誤。
將轉換日期/時間的演算法中的錯誤不將透過時間的小時部分循環日期天的部分。
支援的 Hotfix 現在可以從 Microsoft,但它只用來修正本文所述的問題。僅適用於發生此特定問題的系統。此 Hotfix 可能會接受其他測試。因此,如果您不會嚴重影響這個問題,我們建議您等候下一個的 Microsoft 資料存取元件 Service Pack 包含此 Hotfix。
如果要立即解決這個問題,洽詢 Microsoft 技術支援部以取得此修正程式。如需 Microsoft 產品支援服務電話號碼及支援成本的相關資訊的完整清單,請造訪下列 Microsoft 網站]:
注意 : 在特殊情況中通常會因支援電話所產生的費用如果,可能就不收取 Microsoft 支援人員認為某特定更新程式可以解決您的問題。典型的支援成本將會套用到其他支援問題是所做不限定特定有問題的更新程式。
此修正程式的英文版應該具有下列檔案屬性或更新版本:
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
因應措施 以下是這個問題的兩種潛在的解決方法:
如果可以執行插入並更新透過直接讓 SQL Server 的 SQL 陳述處理日期/時間值的轉換。 -或者- 如果不需要的毫秒儲存,請將欄位定義為 smalldatetime 資料型別,而非日期時間。smalldatetime 資料型別只儲存體,使用 4 個位元組,而且也未納入毫秒精確度。 Microsoft 已確認這是在本文開頭所列之 Microsoft 產品中的有錯誤。
手動安裝的 Hotfix 檔案 請結束任何應用程式或使用 SQL Server ODBC 驅動程式 Sqlsrv32.dll 的服務。這可能包含網際網路資訊伺服器 」 (IIS)、 Microsoft 交易伺服器 (MTS) 及任何 ODBC、 Microsoft ActiveX 資料物件 (ADO) 或 OLE DB 應用程式。 下載 Hotfix 到暫存目錄。 找出並重新命名 Sqlsrv32.dll 和 Odbcbcp.dll 檔案,應該是在執行 Microsoft Windows NT 的電腦 \Winnt\System32 資料夾中,執行 Microsoft Windows 95 與 Microsoft Windows 98 的電腦 \Windows\System 資料夾中的目前版本。 將 Hotfix 檔案複製到相同的位置,然後重新啟動您的服務及應用程式。 重製行為的步驟 在步驟 2 到 Microsoft Visual C++ 主控台應用程式中複製程式碼,並編譯程式碼。請注意您可能需要變更資料來源名稱、 使用者 ID 和密碼。 執行程式碼,並注意繫結 SQL_C_TIMESTAMP,作為日期/時間值時,會發生錯誤,而且是無效的小時值會傳回繫結 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);
}
這篇文章中的資訊適用於: 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 Microsoft ODBC Driver for Microsoft SQL Server 3.7 kbmt kbhotfixserver kbqfe kbbug kbcodesnippet kbdatabase kbfix kbmdac210sp2fix kbqfe KB259691 KbMtzh
機器翻譯 重要:本文是以 Microsoft 機器翻譯軟體翻譯而成,而非使用人工翻譯而成。Microsoft 同時提供使用者人工翻譯及機器翻譯兩個版本的文章,讓使用者可以依其使用語言使用知識庫中的所有文章。但是,機器翻譯的文章可能不盡完美。這些文章中也可能出現拼字、語意或文法上的錯誤,就像外國人在使用本國語言時可能發生的錯誤。Microsoft 不為內容的翻譯錯誤或客戶對該內容的使用所產生的任何錯誤或損害負責。Microsoft也同時將不斷地就機器翻譯軟體進行更新。
按一下這裡查看此文章的英文版本:
259691 ?
(http://support.microsoft.com/kb/259691/en-us/
)
Microsoft及(或)其供應商不就任何在本伺服器上發表的文字資料及其相關圖表資訊的恰當性作任何承諾。所有文字資料及其相關圖表均以「現狀」供應,不負任何擔保責任。Microsoft及(或)其供應商謹此聲明,不負任何對與此資訊有關之擔保責任,包括關於適售性、適用於某一特定用途、權利或不侵權的明示或默示擔保責任。Microsoft及(或)其供應商無論如何不對因或與使用本伺服器上資訊或與資訊的實行有關而引起的契約、過失或其他侵權行為之訴訟中的特別的、間接的、衍生性的損害或任何因使用而喪失所導致的之損害、資料或利潤負任何責任。
請說明您希望我們對本篇文章進行什麼改善及需要改善的原因
謝謝您!您的意見將協助我們改進支援內容。如需更多協助選項,請造訪
說明及支援首頁 。