Ottenere l’elenco dei database Navision su un’istanza SQL Server (Review)

Se si osserva il comportamente del client di Navison quando apre un database SQL Server si nota che vengono visualizzati solo i database di Navision a cui si può accedere con le credenziali fornite e non tutti quelli dell’istanza.
Questo ci porta a fare la considerazione che il controllo viene fatto fatto sul database dove infatti troviamo la tabella $ndo$dbproperty che contiene un solo record con le informazioni di Navision (ad esempio nella colonna databaseversionno troviamo la versione).

Quindi per ottenere l’informazione possimao ricavare l’elenco dei database a cui si ha diritto di accedere con le credenziali fornite e controllare poi l’esistenza della tabella $ndo$dbproperty.

Il seguente codice scritto in VB.NET 2005 ottiene l’elenco dei database (esclusi quelli di sistema) per un’istanza di SQL Server a cui sia ha accesso tramite le credenziali fornite (un graze all’MVP Andrea Benedetti per avermi indicato la funzione HAS_DBACCESS) e quindi verifica l’esistenza della suddetta tabella.

    Public Overloads Shared Function GetSQLDatabases(ByVal server As String, ByVal userID As String, ByVal password As String) As String()
        ‘Build Connection String
        Dim connectionStringBuilder As New System.Data.SqlClient.SqlConnectionStringBuilder()

        connectionStringBuilder.DataSource = server
        connectionStringBuilder.InitialCatalog = “master”
        If String.IsNullOrEmpty(userID) Then
            connectionStringBuilder.IntegratedSecurity = True
        Else
            connectionStringBuilder.UserID = userID
            connectionStringBuilder.Password = password
        End If

        Dim databases As New System.Collections.Generic.List(Of String)
        Dim navisionDatabases As New System.Collections.Generic.List(Of String)

        Using connection As New System.Data.SqlClient.SqlConnection(connectionStringBuilder.ToString())
            connection.Open()

            ‘Selezione dei database a cui sia accesso
            Using command As System.Data.SqlClient.SqlCommand = connection.CreateCommand
                command.CommandText = “SELECT name FROM sysdatabases”
                command.CommandText &= ” WHERE HAS_DBACCESS(name)=1″
                command.CommandText &= ” AND name NOT IN (‘master’, ‘model’, ‘msdb’, ‘tempdb’)”
                command.CommandText &= ” ORDER BY name”

                Dim reader As System.Data.SqlClient.SqlDataReader = Nothing
                reader = command.ExecuteReader()

                While reader.Read()
                    databases.Add(reader.Item(0).ToString())
                End While

                reader.Close()
            End Using

            ‘Verifica esistenza della tabella $ndo$dbproperty
            For Each database As String In databases
                connection.ChangeDatabase(database)
                Using tables As System.Data.DataTable = connection.GetSchema(“tables”, New String() {Nothing, Nothing, “$ndo$dbproperty”})
                    If tables.Rows.Count = 1 Then
                        navisionDatabases.Add(database)
                    End If
                End Using
            Next

            connection.Close()
        End Using

        Return navisionDatabases.ToArray()
    End Function