wtorek, 25 stycznia 2011

SMO: sprawdzanie dostępnych serwerów MS SQL i automatyczna konstrukcja ConnectionString [PL]

Jakiś czas temu, we wpisie związanym z SQLServer Management Objects (SMO), pod tytułem: „SMO i sprawdzanie, czy baza danych istnieje [PL]” otrzymałem komentarz, że warto wspomnieć o jeszcze innych możliwościach SMO, jak choćby listowanie instancji SQL Server: SmoApplication.EnumAvailableSqlServers(). W tym wpisie chciałbym właśnie wrócić do tego tematu.
Otóż tak jak zostało to wspomniane statyczna funkcja SmoApplication.EnumAvailableSqlServers() potrafi dostarczyć listę instancji serwera Ms SQL. Można tę funkcję wywoływać z parametrem typu Boolean, wtedy przekazując „prawda” ograniczymy otrzymaną listę tylko do lokalnych instancji. Można również wywołać tą funkcję z parametrem typu String, w którym przekazujemy nazwę serwera, z którego listą instancji jesteśmy zainteresowani.
Funkcja SmoApplication.EnumAvailableSqlServers() zwraca tabelę (typu DataTable, charakterystyczną dla DataSet'ów). Tabela jest następującej postaci:
Kolumna
Typ danych
Opis
Name
String
Nazwa instancji serwera SQL.
Server
String
Nazwa serwera, na której zainstalowana jest instancja serwera SQL.
Instance
String
Instancja SQL Server.
IsClustered
Boolean
Prawda – jeśli instancja uczestniczy w klastrze niezawodnościowym.
Version
String
Wersja instancji.
IsLocal
Boolean
Prawda – jeśli instancja jest lokalna, fałsz, gdy zdalna.
Otrzymane z takiej tabeli dane można wykorzystać przy tworzeniu aplikacji, w której użytkownik musi np. wybrać serwer, z którym chce nawiązać połączenie, lub np. w aplikacji, która ma dostarczać użytkownikowi „ConnectionString” do bazy danych typu Ms SQL.
Właśnie na możliwość automatycznego generowania ConnectionString'a chciałbym tutaj zwrócić uwagę. Można bowiem do tego wykorzystać obiekt klasy ServerConnection, w którym ustawiamy nazwę instancji bazy danych, użytkownika (właściwości: Login, Password lub dla impersonalizacji: ConnectAsUser, ConnectAsUserName, ConnectAsUserPassword), bazę danych (właściwość DatabaseName, np. uzyskaną na podstawie Microsoft.SqlServer.Management.Smo.Server.Databases). Ostatecznie do odczytania stworzonego ConnectionString'a wykorzystujemy właściwość ConnectionString klasy ServerConnection.
Dla przykładu zobaczmy kod, który odczytuje wszystkie dostępne instancje. Wyświetla informacje na temat każdej instancji oraz ConnectionString'i do każdej dostępnej bazy danych:
      DataTable serversDataTable = SmoApplication.EnumAvailableSqlServers(false);
      foreach ( DataRow row in serversDataTable.Rows )
      {
        Console.WriteLine( "Server:" );
        foreach ( DataColumn dc in row.Table.Columns )
        {
          Console.WriteLine( "{0}={1}", dc.ColumnName, row[dc.ColumnName] );

        }
        Console.WriteLine( "Databases ConnectionStrings:" );
        ServerConnection serverConnection = new ServerConnection(); //main connection to MS SQLServer
        serverConnection.ServerInstance = (string)row[ "Name" ];
        serverConnection.ConnectAsUser = false;//we are using windows currently logged-in user
        ServerConnection serverConnection2 = new ServerConnection();//additional connection to each DataBase
        serverConnection2.ServerInstance = (string)row[ "Name" ];
        serverConnection2.ConnectAsUser = false;
        foreach ( Database db in new Server( serverConnection ).Databases )
        {
          serverConnection2.DatabaseName = db.Name;
          Console.WriteLine( "ConnectionString={0}", serverConnection2.ConnectionString );
        }
        Console.WriteLine( "-----------------------------" );
      }
Efekt jego uruchomienia może wyglądać następująco:
Promuj

6 komentarzy:

  1. Jest jakaś różnica pomiędzy ServerConnection a SqlConnectionStringBuilder jeśli chodzi o tworzenie connection stringa?

    Pozdrawiam,
    Paweł

    OdpowiedzUsuń
  2. Cześć,
    Dzięki za komentarz i przepraszam za zwłokę w odpowiedzi.
    Temu pytaniu zaadresowałem kolejny wpis: DbConnectionStringBuilder i ferajna [PL] | Maciej Zbrzezny: Programowanie i Technologie.

    Pozdrawiam!

    OdpowiedzUsuń
  3. Cześć,
    U mnie niestety nie działa dane rozwiązanie - funkcja EnumAvailableSqlServers() nie znajduje niczego. Używam Windows 7 x64 i mam zainstalowane MS SQL 2005 Express oraz MS SQL 2012 RC0 (na każdym serwerze po jednej instancji). Piszę w środowisku Visual C# Express 2010. Ktoś zna rozwiązanie lub inny sposób na pobranie listy instancji serwerów SQL?

    OdpowiedzUsuń
    Odpowiedzi
    1. To dziwne ja również jak to pisałem to robiłem to na Windows 7 x64 (nie pamiętam jaką jednak miałem bazę danych 2005, czy 2008).
      Spróbuj uruchomić zmienić platformę, z x64 na x86 (patrz: http://maciej-progtech.blogspot.com/2011/04/zamieszanie-z-any-cpu-x86-x64-w-net.html), być może nie masz zainstalowanych jakiś komponentów 32 lub 64-bitowych.
      Sprawdź również uprawnienia, zobacz czy EnumAvailableSqlServers działa na uprawnieniach administratora (http://maciej-progtech.blogspot.com/2010/07/jak-wspierac-mechanizm-uac-w-aplikacji.html).
      Sprawdź również czy masz uruchomioną usługę SQL Server Browser.

      Usuń
    2. Architekturę miałem ustawioną na x86, ale SQL Server Browser był wyłączony. Musiałem ustawić jego właściwość Start Mode na Automatic i ręcznie odpalić. Teraz wszystko działa.
      Dziękuję ;)

      Usuń
  4. Ten komentarz został usunięty przez autora.

    OdpowiedzUsuń

Posty powiązane / Related posts