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