VB.NET ODBC.NET limitations solved DSN list / Tables list 
Author Message
 VB.NET ODBC.NET limitations solved DSN list / Tables list

Took me a while, but I got around the ODBC.NET limitations around
getting a list of available DSN Sources and getting a list of tables
in the database.  I had to call the ODBC API SQLDataSources for the
DSN list and reference ADO to get the Tables list.   Below is my
class.  I would really like to use the ODBC API SQLTables to get the
list of tables, but no matter what I tried it didn't work - I just got
back SQL_NO_DATA_FOUND.  If someone solves this I would really
appreciate seeing how they did it.   Because I am using unmanaged code
here, do I need to provide a Dispose method?  I didn't think so since
I am calling everything local to Sub's and they get cleaned up in the
Sub by either me, or by going out of scope...

Anyway, I thought I'd share this since I{*filter*}d so much code off of
google groups in the past!  This is the best programmers resource
around!

***********************
THE CLASS  - You must reference ODBC.NET and ADO 2.5 in your project
It returns a DataTable object back through the properties -
also below that... how to call it...
***********************
Imports ADODB
Imports Microsoft.Data.Odbc

    Public Class CRODBCHelper
        Inherits Object

        Private Const SQL_BUFFER_SIZE As Short = 1024
        Private Const SQL_FETCH_FIRST As Short = 1
        Private Const SQL_SUCCESS As Short = 0
        Private Const SQL_SUCCESS_WITH_INFO As Short = 1
        Private Const SQL_NO_DATA As Short = 100

        Private Const SQL_HANDLE_ENV As Integer = 1
        Private Const SQL_HANDLE_DBC As Integer = 2
        Private Const SQL_HANDLE_STMT As Integer = 3
        Private Const SQL_HANDLE_DESC As Short = 4
        Private Const SQL_NULL_HANDLE As Short = 0

        Private Declare Function SQLAllocEnv Lib "ODBC32.DLL" (ByRef
env As Integer) As Short
        Private Declare Function SQLFreeHandle Lib "odbc32.dll" (ByVal
handleType As Short, ByVal Handle As Integer) As Short

        Private Declare Function SQLDataSources Lib "ODBC32.DLL" _
                                             (ByVal WindowHandle As
Integer, _
                                              ByVal Direction As
Short, _
                                              ByVal DSNBuffer As
String, _
                                              ByVal DSNBufferLength As
Short, _
                                              ByRef DSNLength As
Short, _
                                              ByVal DESCBuffer As
String, _
                                              ByVal DESCBufferLength
As Short, _
                                              ByRef DESCLength As
Short) As Short

        Declare Function SQLGetDiagRec Lib "odbc32.dll" (ByVal iHType
As Short, _
           ByVal lHInput As Integer, _
           ByVal iRecNumber As Short, _
           ByVal szSQLState As String, _
           ByRef iNativeError As Integer, _
           ByVal strMessageText As String, _
           ByVal iBufferLength As Short, _
           ByRef iTextLength As Short) As Short

        Private m_ConnectString As String
        Private m_DSNDataTable As DataTable
        Private m_TablesDataTable As DataTable
        Private m_ODBCNativeError As Integer
        Private m_ODBCMessage As String

        Public Sub New(ByVal ConnectStr As String)
            MyBase.New()
            m_ConnectString = ConnectStr
            InitializeTables()
        End Sub

        Public Sub New()
            MyBase.New()
            InitializeTables()
        End Sub

        Public Property ConnectString() As String
            Get
                Return m_ConnectString
            End Get
            Set(ByVal Value As String)
                m_ConnectString = Value
            End Set
        End Property

        Public ReadOnly Property DSNDataTable() As DataTable
            Get
                Return m_DSNDataTable
            End Get
        End Property

        Public ReadOnly Property TablesDataTable() As DataTable
            Get
                Return m_TablesDataTable
            End Get
        End Property

        Public ReadOnly Property ErrorCode() As Integer
            Get
                Return m_ODBCNativeError
            End Get
        End Property

        Public ReadOnly Property ErrorMessage() As String
            Get
                Return m_ODBCMessage
            End Get
        End Property

        Private Sub InitializeTables()

            m_DSNDataTable = New DataTable("DSNList")
            m_TablesDataTable = New DataTable("TableList")

            m_DSNDataTable.Columns.Add(New
System.Data.DataColumn("DSN_NAME"))
            m_DSNDataTable.Columns.Add(New
System.Data.DataColumn("DSN_DESCRIPTION"))

            m_TablesDataTable.Columns.Add(New
System.Data.DataColumn("TABLE_CATALOG"))
            m_TablesDataTable.Columns.Add(New
System.Data.DataColumn("TABLE_SCHEMA"))
            m_TablesDataTable.Columns.Add(New
System.Data.DataColumn("TABLE_NAME"))
            m_TablesDataTable.Columns.Add(New
System.Data.DataColumn("TABLE_TYPE"))

        End Sub

        Public Function BuildDSNDataTable() As Boolean

            Dim EnvHandle As IntPtr
            Dim env As Integer

            Dim hDbc As IntPtr
            Dim ODBCRC As Integer
            Dim ret As Short
            Dim DSNBuffer As String
            Dim DSNBufferLength As Short
            Dim ReturnedDSNLength As Short
            Dim DESCBuffer As String
            Dim DESCBufferLength As Short
            Dim ReturnedDESCLength As Short
            Dim DSNName As String
            Dim DSNDescription As String

            'Initialize the string buffer lengths
            DSNBufferLength = SQL_BUFFER_SIZE
            DESCBufferLength = SQL_BUFFER_SIZE

            ODBCRC = SQLAllocEnv(env)
            If ProcessODBCError(env, ODBCRC) = True Then
                SQLFreeHandle(SQL_HANDLE_ENV, env)
                env = Nothing
                Return False
            End If

            ret = SQL_SUCCESS
            'Get the DSN names & descriptions
            While (ret = SQL_SUCCESS) Or (ret = SQL_SUCCESS_WITH_INFO)
                DSNBuffer = Space(DSNBufferLength)
                DESCBuffer = Space(DESCBufferLength)
                ret = SQLDataSources(env, SQL_FETCH_FIRST, DSNBuffer,
_
                DSNBufferLength, ReturnedDSNLength, DESCBuffer,
DESCBufferLength, _
                ReturnedDESCLength)
                If ProcessODBCError(env, ret) = True Then
                    SQLFreeHandle(SQL_HANDLE_ENV, env)
                    env = Nothing
                    Return False
                End If

                DSNName = DSNBuffer.Substring(0, ReturnedDSNLength)
                DSNDescription = DESCBuffer.Substring(0,
ReturnedDESCLength)

                Dim nr As System.Data.DataRow =
m_DSNDataTable.NewRow()

                nr("DSN_NAME") = DSNName
                nr("DSN_DESCRIPTION") = DSNDescription

                m_DSNDataTable.Rows.Add(nr)

            End While

            SQLFreeHandle(SQL_HANDLE_ENV, env)
            env = Nothing
            Return True

        End Function

        Public Function BuildTablesDataTable(ByVal ConnectStr As
String) As Boolean
            Dim ret As Boolean
            m_ConnectString = ConnectStr
            Return BuildTablesDataTable()
        End Function

        Public Function BuildTablesDataTable() As Boolean
            Dim mConnect As New Connection()
            Dim rstSchema As New ADODB.Recordset()
            Dim Buffer As String
            Dim Ret As Boolean

            Ret = True

            mConnect.ConnectionString = m_ConnectString
            Try
                mConnect.Open()
            Catch Ex As Exception
                m_ODBCNativeError = -1
                m_ODBCMessage = Ex.Message
                Try
                    mConnect.Close()
                Catch Ex2 As Exception
                    'Do Nothing
                Finally
                    mConnect = Nothing
                End Try
                Return False
            End Try

            'Get the database schema.
            Try
                rstSchema =
mConnect.OpenSchema(SchemaEnum.adSchemaTables)
            Catch Ex As Exception
                m_ODBCNativeError = -1
                m_ODBCMessage = Ex.Message
                Try
                    mConnect.Close()
                Catch Ex2 As Exception
                    'Do Nothing    
                Finally
                    mConnect = Nothing
                    rstSchema = Nothing
                End Try
                Return False
            End Try

            With rstSchema

                'Make sure something is found.
                If Not .BOF And Not .EOF Then

                    'Add the tables to the collection.
                    Do While Not rstSchema.EOF

                        Dim nr As System.Data.DataRow =
m_TablesDataTable.NewRow()

                        nr("TABLE_CATALOG") =
rstSchema.Fields("TABLE_CATALOG").Value
                        nr("TABLE_SCHEMA") =
rstSchema.Fields("TABLE_SCHEMA").Value
                        nr("TABLE_NAME") =
rstSchema.Fields("TABLE_NAME").Value
                        nr("TABLE_TYPE") =
rstSchema.Fields("TABLE_TYPE").Value

                        m_TablesDataTable.Rows.Add(nr)

                        rstSchema.MoveNext()
                    Loop

                    Ret = True

                Else  'No tables found.

                    Ret = False

                End If
            End With

            mConnect.Close()
            mConnect = Nothing
            rstSchema = Nothing

            Return Ret

        End Function

        Private Function ProcessODBCError(ByVal env As Integer, ByVal
retval As Short) As Boolean
            Dim ODBCRC As Short
            Dim State As String, Message As String
            Dim NativeError As Long, Length As Integer
            Dim strErrMsg As String

            strErrMsg = Space(128)

            ODBCRC = retval

            If (ODBCRC <> SQL_SUCCESS) And (ODBCRC <>
SQL_SUCCESS_WITH_INFO) Then
                ODBCRC = SQLGetDiagRec(SQL_HANDLE_ENV, env, 1, State,
NativeError, strErrMsg, strErrMsg.Length, Length)
                If ODBCRC = SQL_SUCCESS Then
                    m_ODBCNativeError = NativeError
                    m_ODBCMessage = strErrMsg
                    env = Nothing
                    Return True
                End If
            ElseIf (ODBCRC = SQL_SUCCESS_WITH_INFO) Then
                ODBCRC = SQLGetDiagRec(SQL_HANDLE_ENV, env, 1, State,
NativeError, strErrMsg, strErrMsg.Length, Length)
                If ODBCRC = SQL_SUCCESS Then
                    m_ODBCNativeError = NativeError
                    m_ODBCMessage = strErrMsg
                    Return False
                End If
            End If

            Return False

        End Function

    End Class

******************************
How to call it
******************************

Private ODBCHelper As New CRODBCHelper()

Private mDSNTable As DataTable
Private mTablesList As DataTable

--------------------------

'GET THE DSN LIST
Dim ret As Boolean

        ret = ODBCHelper.BuildDSNDataTable()
        If ret = True Then
            mDSNTable = ODBCHelper.DSNDataTable
' Use the Datatable to show in a grid or loop through it to get the
data...
            DataGrid2.DataSource = mDSNTable
        Else
            MsgBox("(" + Str(ODBCHelper.ErrorCode) + ")" +
ODBCHelper.ErrorMessage)
        End If

-----------------------
' Get the tables list

Dim ret As Boolean

        ODBCHelper.ConnectString =
"DSN=MySQLServerDsn;uid=sa;pwd=manager;database=Northwind"

        ret = ODBCHelper.BuildTablesDataTable()
        If ret = True Then
            mTablesList = ODBCHelper.TablesDataTable
' Use the Datatable to show in a grid or loop through it to get the
data...
            DataGrid1.DataSource = mTablesList
        Else
            MsgBox("(" + Str(ODBCHelper.ErrorCode) + ")" +
ODBCHelper.ErrorMessage)
        End If



Sat, 30 Apr 2005 23:48:45 GMT  
 
 [ 1 post ] 

 Relevant Pages 

1. Packing a FoxPro table via ODBC.net from VB.net

2. List tables in ODBC DSN

3. Severe VB.NET COM/.NET Interop Limitation

4. Know anyone a good .NET/C#/Vb.net/ASP.NET/ADO.NET message board/mailing list/newsletter???????

5. Retrieve a list of ODBC DSN

6. ODBC DSN listing?

7. How to list all the DSN in ODBC?

8. ADO ODBC DSN List

9. what create table using ADO.NET to VB.NET

10. Handling LISTs and QUEUEs in VB.NET

11. TreeView State Image List Problem - VB.Net

12. List of changes to vb.net 2003?

 

 
Powered by phpBB® Forum Software