SQLConnect 函式

符合性
引進版本:ODBC 1.0 標準合規性:ISO 92

總結
SQLConnect 建立驅動程式與資料來源的連線。 連線處理會參考所有關於連線的資訊,包括狀態、交易狀態及錯誤資訊。

Syntax

  
SQLRETURN SQLConnect(  
     SQLHDBC        ConnectionHandle,  
     SQLCHAR *      ServerName,  
     SQLSMALLINT    NameLength1,  
     SQLCHAR *      UserName,  
     SQLSMALLINT    NameLength2,  
     SQLCHAR *      Authentication,  
     SQLSMALLINT    NameLength3);  

Arguments

ConnectionHandle
[輸入] 連線控制代碼。

ServerName
[輸入]資料來源名稱。 資料可能和程式位於相同的電腦上,也可能位於網路內的其他電腦上。 關於應用程式如何選擇資料來源的資訊,請參見 「選擇資料來源或驅動程式」。

名稱長度1
[輸入]*ServerName 字元長度。

UserName
[輸入]使用者識別碼。

名稱長度2
[輸入]*使用者名稱 字元長度。

驗證
[輸入]驗證字串(通常是密碼)。

名稱長度3
[輸入]*以字元為單位的認證 長度。

Returns

SQL_SUCCESS、SQL_SUCCESS_WITH_INFO、SQL_ERROR、SQL_INVALID_HANDLE或SQL_STILL_EXECUTING。

Diagnostics

當 SQLConnect 回傳 SQL_ERROR 或 SQL_SUCCESS_WITH_INFO 時,可以透過呼叫 SQLGetDiagRec 取得 HandleType 為 SQL_HANDLE_DBC 與 ConnectorHandle為 Handle。 下表列出 SQLConnect 通常回傳的 SQLSTATE 值,並在此函式的情境中解釋每個值;「(DM)」符號會置於驅動程式管理器回傳的 SQLSTATE 描述前。 除非另有說明,否則與每個 SQLSTATE 值相關聯的傳回碼會SQL_ERROR。

SQLSTATE 錯誤 Description
01000 一般警告 驅動程式特定的資訊訊息。 (函式會傳回SQL_SUCCESS_WITH_INFO。)
01S02 選項值已變更 驅動程式不支援 SQLSetConnectAttr 中指定的 ValuePtr 參數值,並以類似值替換。 (函式會傳回SQL_SUCCESS_WITH_INFO。)
08001 客戶端無法建立連線 駕駛無法與資料來源建立連線。
08002 連接名稱的使用方式 (DM) 指定的 ConnectionHandle 已被用來建立與資料來源的連線,且該連線仍然開啟,或使用者正在瀏覽連線。
08004 伺服器拒絕了連線 資料來源因實作定義的原因拒絕建立該連線。
08S01 通訊連結故障 驅動程式與驅動程式嘗試連接的資料來源之間的通訊連結在函式完成處理前就中斷了。
28000 無效授權規範 參數 UserName 指定的值或參數 Authentication 的值違反了資料來源所定義的限制。
HY000 一般誤差 發生錯誤,其中沒有特定的 SQLSTATE,也沒有定義任何實作特定的 SQLSTATE。 *MessageText 緩衝區中 SQLGetDiagRec 傳回的錯誤訊息描述錯誤及其原因。
HY001 記憶體配置錯誤 (DM) 驅動程式管理器無法分配支援執行或完成函式所需的記憶體。
HY008 作業已取消 ConnectionHandle 啟用了非同步處理。 SQLConnect 函式被呼叫,在執行完成前,SQLCancelHandle 函式在 ConnectionHandle 上被呼叫,接著在 ConnectionHandle 上再次呼叫 SQLConnect 函式。

或者, SQLConnect 函式被呼叫,在執行完成前, SQLCancelHandle 從多執行緒應用程式的不同執行緒呼叫 ConnectionHandle 。
HY010 函式順序錯誤 (DM) 一個非同步執行的函式(非這個)被呼叫用於 ConnectionHandle ,且在呼叫該函式時仍在執行中。
HY013 記憶體管理錯誤 無法處理函式呼叫,因為基礎記憶體物件無法存取,可能是因為記憶體不足的情況。
HY090 無效的字串或緩衝區長度 (DM) 為 NameLength1、 NameLength2 或 NameLength3 所指定的值小於 0,但不等於 SQL_NTS。

(DM) 參數 NameLength1 所指定的值超過資料來源名稱的最大長度。
HYT00 逾時已超過 查詢逾時期在與資料來源的連線完成前就已過期。 逾時時間由 SQLSetConnectAttr 設定,SQL_ATTR_LOGIN_TIMEOUT。
HY114 驅動程式不支援連線層級的非同步函式執行 (DM) 應用程式在建立連線前啟用了連線句柄上的非同步操作。 然而,驅動程式不支援對連線柄進行非同步操作。
HYT01 連線已逾時 在數據源回應要求之前,連線逾時期限已過期。 線上逾時期間是透過 SQLSetConnectAttr 來設定,SQL_ATTR_CONNECTION_TIMEOUT。
IM001 驅動程式不支援此函式 (DM) 資料來源名稱所指定的驅動程式不支援該函式。
IM002 找不到資料來源,且未指定預設驅動程式 (DM) 在 ServerName 參數中指定的資料來源名稱未在系統資訊中找到,也沒有預設驅動程式規範。
IM003 指定驅動程式無法連接到 (DM) 系統資訊中資料來源規格中列出的驅動程式未被找到或因其他原因無法連接。
IM004 驅動程式的 SQLAllocHandle 在 SQL_HANDLE_ENV 失敗 (DM) 在 SQLConnect 期間,驅動程式管理器呼叫驅動程式的 SQLAllocHandle 函式,並設定 HandleType 為 SQL_HANDLE_ENV,驅動程式回傳錯誤。
IM005 驅動程式的 SQLAllocHandle 在 SQL_HANDLE_DBC 失敗 (DM) 在 SQLConect 期間,驅動程式管理器呼叫驅動程式的 SQLAllocHandle 函式, HandleType 為 SQL_HANDLE_DBC,驅動程式回傳錯誤。
IM006 Driver's SQLSetConnectAttr failed 在 SQLConnect 期間,驅動程式管理器呼叫驅動程式的 SQLSetConnectAttr 函式,驅動程式回傳錯誤。 (函式會傳回SQL_SUCCESS_WITH_INFO。)
IM009 無法連接翻譯 DLL 驅動程式無法連接到資料來源指定的轉換 DLL。
IM010 資料來源名稱太長了 (DM) *ServerName 比 SQL_MAX_DSN_LENGTH 字元還長。
IM014 指定的 DSN 包含驅動程式與應用程式之間的架構不匹配 (DM) 32 位元應用程式使用 DSN 連接 64 位元驅動程式;反之亦然。
IM015 驅動程式的 SQLConnect 在 SQL_HANDLE_DBC_INFO_HANDLE 上失敗 若驅動程式回SQL_ERROR,驅動程式管理員會將SQL_ERROR回應用程式,連線將失敗。

欲了解更多SQL_HANDLE_DBC_INFO_TOKEN資訊,請參閱《 ODBC駕駛員中培養 Connection-Pool 意識》。
IM017 在異步通知模式中停用輪詢 每當使用通知模型時,輪詢就會停用。
IM018 尚未呼叫 SQLCompleteAsync ,以完成此句柄上的先前異步操作。 如果句柄上的上一個函式呼叫傳回SQL_STILL_EXECUTING且啟用通知模式, 則必須在句柄上呼叫 SQLCompleteAsync ,才能執行後續處理並完成作業。
S1118 驅動程式不支援非同步通知 當驅動程式不支援非同步通知時,你無法設定SQL_ATTR_ASYNC_DBC_EVENT或SQL_ATTR_ASYNC_DBC_RETCODE_PTR。

評論

關於應用程式為何使用 SQLConnect 的資訊,請參見 「與 SQLConnect 連接」。

驅動程式管理員不會連接到驅動程式,直到應用程式呼叫函式(SQLConnect、 SQLDriverConnect 或 SQLBrowseConnect)來連接驅動程式。 在此之前,驅動程式管理器會自行處理帳號並管理連線資訊。 當應用程式呼叫連接函式時,驅動程式管理器會檢查該驅動程式目前是否已連接到指定的 ConnectionHandle:

  • 若未連接驅動程式,驅動程式管理器會連接該驅動程式,並呼叫 SQLAllocHandle,HandleType 為 SQL_HANDLE_ENV SQL_HANDLE_DBC,SQLSetConnectAttr(若應用程式指定任何連線屬性),並呼叫驅動程式中的連接函式。 如果驅動程式對 SQLSetConnectAttr 產生錯誤,則 Driver Manager 會回傳 SQLSTATE IM006(驅動程式的 SQLSetConnectOption 失敗)並返回 SQL_SUCCESS_WITH_INFO 連接函式。 欲了解更多資訊,請參閱 「連接資料來源或驅動程式」。

  • 如果指定的驅動程式已經在 ConnectionHandle 上連接,驅動程式管理器只會呼叫該驅動程式中的連接函式。 此時,驅動程式必須確保所有 ConnectionHandle 的連線屬性都維持目前的設定。

  • 若連接的是不同的驅動程式,驅動程式管理器會呼叫 SQLFreeHandle 並設定為 SQL_HANDLE_DBC HandleType ,若該環境中沒有其他驅動程式連接,則 呼叫該驅動 程式中 HandleType 為 SQL_HANDLE_ENV,然後斷開該驅動程式。 接著執行與未連接驅動程式時相同的操作。

驅動程式接著分配 handle 並初始化自己。

當應用程式呼叫 SQLDisconnect 時,驅動程式管理器會呼叫驅動程式中的 SQLDisconnect 。 不過,它不會斷開驅動程式。 這能將驅動程式保留在記憶體中,方便反覆連接與斷開資料來源的應用程式使用。 當應用程式呼叫 SQLFreeHandle 的 HandleType 為 SQL_HANDLE_DBC 時,驅動程式管理器會以 HandleType 為 SQL_HANDLE_DBC 呼叫 SQLFreeHandle,接著在驅動程式中呼叫 SQLFreeHandle 的 HandleType 為 SQL_HANDLE_ENV,接著斷開驅動程式。

ODBC 應用程式可以建立多個連線。

駕駛經理指引

*ServerName 的內容會影響驅動程式管理器與驅動程式如何協同建立與資料來源的連線。

  • 若 *ServerName 包含有效的資料來源名稱,驅動程式管理員會在系統資訊中找到對應的資料來源規格,並連接到相關的驅動程式。 驅動程式管理器會將每個 SQLConnect 參數傳遞給驅動程式。

  • 若找不到資料來源名稱或 ServerName 為空指標,驅動程式管理員會定位預設資料來源規格並連接至相關驅動程式。 驅動程式管理器會將未修改的 UserName 與 Authentication 參數,以及 DEFAULT 參數的「」傳遞給驅動程式。

  • 若 ServerName 參數為「DEFAULT」,驅動程式管理器會定位預設資料來源規格並連接至相關驅動程式。 驅動程式管理器會將每個 SQLConnect 參數傳遞給驅動程式。

  • 若找不到資料來源名稱或 ServerName 為空指標,且預設資料來源規範不存在,驅動程式管理器會回傳 SQLSTATE IM002 SQL_ERROR(找不到資料來源名稱且未指定預設驅動程式)。

驅動程式管理器連接後,驅動程式可在系統資訊中找到對應的資料來源規格,並利用規範中的驅動程式特定資訊來完成所需的連線資訊集合。

如果在資料來源的系統資訊中指定了預設的翻譯函式庫,驅動程式會連接到該函式庫。 可透過呼叫帶有 SQL_ATTR_TRANSLATE_LIB 屬性的 SQLSetConnectAttr 來連接另一個轉譯函式庫。 可透過呼叫帶有 SQL_ATTR_TRANSLATE_OPTION 屬性的 SQLSetConnectAttr 來指定轉換選項。

若驅動程式支援 SQLConnect,則該驅動程式系統資訊中的驅動關鍵字區塊必須包含 ConnectFunctions 關鍵字,且第一個字元設為「Y」。

連線池化

連線池允許應用程式重用已建立的連線。 當啟用連線池並呼叫 SQLConnect 時,驅動程式管理器會嘗試使用一個位於指定為連線池的環境中的連線池中的連線。 此環境是一個共享環境,所有使用池中連線的應用程式都會使用。

在環境分配前,呼叫 SQLSetEnvAttr 將 SQL_ATTR_CONNECTION_POOLING 設定為 SQL_CP_ONE_PER_DRIVER(指定每個驅動程式最多一個池)或 SQL_CP_ONE_PER_HENV(規定每個環境最多一個池)來啟用連線池。 此時 SQLSetEnvAttr 是將 EnvironmentHandle 設為 null 的,使該屬性成為程序層級屬性。 如果SQL_ATTR_CONNECTION_POOLING設為SQL_CP_OFF,連線池會被停用。

啟用連線池後,會呼叫帶有 HandleType SQL_HANDLE_ENV的 SQLAllocHandle 來分配環境。 此呼叫所分配的環境為共享環境,因為連線池已被啟用。 然而,直到呼叫 HandleType 為 SQL_HANDLE_DBC 的 SQLAllocHandle 時,才會確定所使用的環境。

呼叫帶有 HandleType 為 SQL_HANDLE_DBC 的 SQLAllocHandle 來分配連線。 驅動程式管理器嘗試尋找與應用程式設定的環境屬性相符的現有共享環境。 若不存在此類環境,則以隱含 共享環境形式建立。 若找到匹配的共享環境,該環境句柄會回傳給應用程式,並增加其參考數量。

然而,將要使用的連線直到 SQLConnect 被呼叫時才會確定。 此時,驅動程式管理器會嘗試在連接池中找到符合應用程式要求條件的現有連線。 這些條件包括呼叫 SQLConnect 時請求的連線選項( ServerName、 UserName 和 Authentication 關鍵字的值)以及自呼叫 SQLAllocHandle 後設定的連線屬性, HandleType 為 SQL_HANDLE_DBC。 驅動管理員會將這些條件與池中連接中對應的連結關鍵字與屬性進行檢查。 若找到匹配,則使用池中的連線。 若未找到匹配,則建立新的連線。

若SQL_ATTR_CP_MATCH環境屬性設為SQL_CP_STRICT_MATCH,則匹配必須完全一致,池中連線才會被使用。 如果SQL_ATTR_CP_MATCH環境屬性設為 SQL_CP_RELAXED_MATCH,則呼叫 SQLConnect 時的連線選項必須相符,但並非所有連線屬性都必須相符。

當應用程式在呼叫 SQLConnect 前設定的連線屬性與池中該連線屬性不符時,會套用以下規則:

  • 如果連線屬性必須在建立連線前設定:

    若SQL_ATTR_CP_MATCH為SQL_CP_STRICT_MATCH,則集合連線中的SQL_ATTR_PACKET_SIZE必須與應用程式設定的屬性相同。 如果SQL_CP_RELAXED_MATCH,SQL_ATTR_PACKET_SIZE的數值可能會不同。

    SQL_ATTR_LOGIN_VALUE的價值不會影響比賽結果。

  • 如果連線屬性可以在連線前或連線後設定:

    如果連接屬性不是由應用程式設定,但已設定在池中該連線,且有預設值,則池中連線中的連線屬性會被設回預設值並宣告匹配。 若無預設,該合併連線不被視為匹配。

    若應用程式已設定連線屬性,但尚未設定在池中該連線,則池中的連線屬性會被更改為應用程式設定的屬性,並宣告匹配。

    如果應用程式已設定連線屬性,且池中連線的值也被設定,但值不同,則使用應用程式連線屬性的值並宣告匹配。

  • 若驅動程式專屬連線屬性的值不相同且SQL_ATTR_CP_MATCH設為SQL_CP_STRICT_MATCH,則池中的連線不被使用。

當應用程式呼叫 SQLDisconnect 斷開連線時,連線會回傳到連線池並可重複使用。

優化連線池效能

當涉及分散式交易時,可以透過使用 SQL_DTC_TRANSITION_COST(SQLUINTEGER 位元遮罩)來優化連線池效能。 所提及的轉移是連接屬性SQL_ATTR_ENLIST_IN_DTC從值 0 到 non zero 的轉換,反之亦然。 這是一種從未被列入分散式交易到被列入分散式交易,反之亦然的連結。 根據驅動程式如何實作登錄(設定連線屬性SQL_ATTR_ENLIST_IN_DTC),這些轉換可能成本高昂,因此應避免以達到最佳效能。

驅動程式回傳的值包含以下任意組合的位元:

  • SQL_DTC_ENLIST_EXPENSIVE 設定時,意味著從零轉為非零的轉換比從非零轉換到另一個非零值(將先前登錄的連線列入下一筆交易)成本高得多。

  • SQL_DTC_UNENLIST_EXPENSIVE 設定時,意味著非零轉零的轉換成本遠高於使用 SQL_ATTR_ENLIST_IN_DTC 屬性已設為零的連接。

效能與連線使用之間存在取捨。 如果有驅動程式指出其中一個或多個轉換成本較高,驅動管理員的連線池會回應,保留更多連線在池中。 池中有些連線偏好用於非交易用途,有些則偏好用於交易用途。 然而,若驅動程式表示這些轉換成本不高,則可減少連接數量,可能在非交易與交易間交替使用。

不支援SQL_ATTR_ENLIST_IN_DTC的驅動程式不需要支援SQL_DTC_TRANSITION_COST。 對於支援SQL_ATTR_ENLIST_IN_DTC但不支援SQL_DTC_TRANSITION_COST的驅動程式,假設轉換成本不高,就像驅動程式回傳 0(未設定位元)一樣。

雖然SQL_DTC_TRANSITION_COST在 ODBC 3.5 中引入,但 ODBC 2X 驅動程式也能支援,因為驅動程式管理器會查詢這些資訊,不論驅動程式版本為何。

程式代碼範例

以下範例中,應用程式分配環境與連線句柄。 接著它會連接到 SalesOrders 資料來源,使用者 ID 為 JohnS 並以密碼為 Sesame 進行處理。 當資料處理完成後,會斷開與資料來源的連結並釋放 handle。

// SQLConnect_ref.cpp  
// compile with: odbc32.lib  
#include <windows.h>  
#include <sqlext.h>  
  
int main() {  
   SQLHENV henv;  
   SQLHDBC hdbc;  
   SQLHSTMT hstmt;  
   SQLRETURN retcode;  
  
   SQLCHAR * OutConnStr = (SQLCHAR * )malloc(255);  
   SQLSMALLINT * OutConnStrLen = (SQLSMALLINT *)malloc(255);  
  
   // Allocate environment handle  
   retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);  
  
   // Set the ODBC version environment attribute  
   if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {  
      retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);   
  
      // Allocate connection handle  
      if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {  
         retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);   
  
         // Set login timeout to 5 seconds  
         if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {  
            SQLSetConnectAttr(hdbc, SQL_LOGIN_TIMEOUT, (SQLPOINTER)5, 0);  
  
            // Connect to data source  
            retcode = SQLConnect(hdbc, (SQLCHAR*) "NorthWind", SQL_NTS, (SQLCHAR*) NULL, 0, NULL, 0);  
  
            // Allocate statement handle  
            if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {  
               retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);   
  
               // Process data  
               if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {  
                  SQLFreeHandle(SQL_HANDLE_STMT, hstmt);  
               }  
  
               SQLDisconnect(hdbc);  
            }  
  
            SQLFreeHandle(SQL_HANDLE_DBC, hdbc);  
         }  
      }  
      SQLFreeHandle(SQL_HANDLE_ENV, henv);  
   }  
}  
如需有關 看!
分配帳柄 SQLAllocHandle 函數
發現並列舉連接資料來源所需的數值 SQLBrowseConnect 函式
斷開與資料來源的連接 SQLDisconnect 函式
使用 連接字串 或對話框連接資料來源 SQLDriverConnect 函式
傳回連接屬性的設定 SQLGetConnectAttr 函式
設定連線屬性 SQLSetConnectAttr 函式