[VBNET] 叫用 ODBC 精靈的 API

話說,最近有個需求,需要將現地的資料庫的資料攜回,但是現地的電腦沒裝啥軟體,此外資料庫格式很亂,有走 DSN 的,有走連線字串的,不容易處理這種需求, 所以就寫個小工具來轉換。
收檔的對象我選擇 Access ,不管啥資料通通匯入到 Access ,然後就把 Access 壓縮帶回來,這樣算是滿通用的方法,此外選擇 Access 透過 Oledb 去處理時,可免寫 Dataset 的匯入匯出問題,只要對 Access 檔下 SELCET INTO 配上 IN 子句,就可以輕輕鬆鬆的把資料轉進 Access ,使用 ODBC Driver 對話盒,裡面還有新建、壓縮、修復等功能 (詳見下方圖形) ,若是現地使用的是 Access 資料庫,也可以透過這個對話盒直接維護。
資料來源名稱 (DSN) 的部分,可以透過註冊資訊檔抓,也可以透過 ODBC API 抓,這裡使用 SQLDataSources 這支 API 抓,可分機器來源跟使用者來源,但這隻 API 在 ODBC 2.0 無法分辨是機器來源還是使用者來源,所以會全部傳回來,很不巧,XP 就是用 ODBC 2.0 ,而 Win2008 / Win7 則是用 ODBC 3.0 … 所以要正確的分出機器來源或使用者來源,要直接讀註冊資訊檔:
機器來源為:LOCAL_MACHINE
使用者來源為:CURRENT_USER
都是讀這個位置:Software\ODBC\ODBC.INI
而要讀該資料來源名稱的連線設定,一樣就是到上面的機碼下的子機碼去讀,讀機碼值這部分沒啥特別的,MSDN 跟網路上都可以找到現成的範例,就不再重複描述。
要使用系統內建的 ODBC 精靈,主要是呼叫 SQLDriverConnect 這支 API ,若是沒給 Driver 名稱,則會自動帶出 DSN 的對話盒,若是有給 Driver ,則可正確的叫出對應的對話盒,所以變成要先取得系統內的 Driver 名稱,這部分是呼叫 SQLDrivers 這支 API 。
所以自己主要只需要寫兩個小函數:

程式碼

“‘ <summary>連線字串選擇對話盒</summary>

“‘ <param name="hWnd">視窗代碼</param>

“‘ <param name="constr">空字串為從 DSN 選擇或建立,設定 ODBC Driver 則使用該 Driver</param>

“‘ <returns>傳回DSN 或連線字串</returns>

Friend Function GetConnectionStringDialog(ByVal hWnd As IntPtr, Optional ByVal constr As String = “") As String

      Dim LenBuffer As Integer = 1024

      Dim Buf As String = Space(LenBuffer)

      Dim outlen As Short

      Dim Retcode As Short

      Dim hEnv As Integer

      Dim hDBC As Integer

 

      If SQLAllocEnv(hEnv) = SqlMessage.Success Then

           If SQLAllocConnect(hEnv, hDBC) = SqlMessage.Success Then

                 If SQLDriverConnect(hDBC, hWnd, constr, Len(constr), Buf, LenBuffer, outlen, SqlMessage.DriverCompleteReqired) = SqlMessage.Success Then

                       Retcode = SQLDisconnect(hDBC)

                 End If

                 Retcode = SQLFreeConnect(hDBC)

           End If

           Retcode = SQLFreeEnv(hEnv)

      End If

      Return Buf

End Function

 

“‘ <summary>取得所有 ODBC Driver</summary>

“‘ <param name="AddCaptionRow">是否加標題列</param>

“‘ <returns>DBArray(驅動程式, 屬性)</returns>

Friend Function GetDriversDBArray(Optional ByVal AddCaptionRow As Boolean = False) As Object

      Dim ReturnList As New ArrayList()

      Dim LenBuffer As Integer = 1024

      Dim ReturnValue As Short

      Dim DriverName, DriverAttributes As String

      Dim DriverNameLen, AttributesLen As Short

      Dim SQLEnv As IntPtr   ‘handle to the environment

      Dim initString As String = Space(LenBuffer)

 

      If SQLAllocEnv(SQLEnv) <> -1 Then

           If AddCaptionRow Then

                 ReturnList.Add(Split(“Driver,Attributes"))

           End If

           Do Until ReturnValue <> SqlMessage.Success

                 DriverName = initString

                 DriverAttributes = initString

                 ReturnValue = SQLDrivers(SQLEnv, SqlMessage.FetchNext, DriverName, LenBuffer, DriverNameLen, DriverAttributes, LenBuffer, AttributesLen)

 

                 If ReturnValue = SqlMessage.Success Then

                       ReturnList.Add(New Object() {Left(DriverName, DriverNameLen), Left(DriverAttributes, AttributesLen)})

                 End If

           Loop

      End If

      Return ReturnList.ToArray

End Function

 

ODBC 對話盒會傳回完整的連線字串,包含細部屬性的設定,當然過多也有點累贅就是了。
若是 Oledb 自己直接支援的資料庫,不能直接用在 IN 子句,再自行替換即可。
我把常見的 ODBC Driver 對話盒列在下面,特別要提的是 CSV 這類文字檔,要使用 Microsoft Access Text Driver (*.txt, *.csv) 才會帶出連線字串精靈,還可以看到可以出現欄位自動猜測型別功能,可以玩玩看喔~

不使用任何驅動程式時,會自動呼叫 DSN 對話盒:
取得所有 ODBC Driver ,供精靈使用:
Access 的對話盒:
CSV 的對話盒:
dBase 的對話盒:
Excel 的對話盒:
MySQL 的對話盒:
Visual Foxpro 的對話盒:

SQL Server 的對話盒:
Categories: 資料庫 | 發表留言

文章導覽

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 變更 )

Twitter picture

You are commenting using your Twitter account. Log Out / 變更 )

Facebook照片

You are commenting using your Facebook account. Log Out / 變更 )

Google+ photo

You are commenting using your Google+ account. Log Out / 變更 )

連結到 %s

在 WordPress.com 建立免費網站或網誌.

%d 位部落客按了讚: