SqlGenerator: Sql-Insert Statements generieren #1

Vor einiger Zeit habe ich ein kleines Script geschrieben, welches mir aus einer Tabelle einer Microsoft SQL Datenbank alle Datensätze als INSERT-Statements zurückliefert. Da der Microsoft SQL Server das nicht von alleine herstellt und man – alleine schon als Datenbank- und Softwareentwickler – recht häufig diese Funktionalität vermisst, musste ein kurzer und schmerzfreier Weg her.
Die Suche im Internet (man ist ja faul :)) brachte nicht das gewünschte Ergebnis. Zwar gibt es vergleichbare Tools aber eine schlanke, schnelle Lösung boten Sie nicht. Ich verstehe persönlich ja nicht, warum bei solchen kleinen Helferlein direkt eine Installation dabeisein muss und warum mir neue DLLs Windows verlangsamen müssen und Registry-Einträge die OS-Datenbank vollspammen müssen.
Also wollte ich ein kleines Programm welches man einfach starten kann, ohne Kosten, ohne Suchen, ohne Setup und ohne Pipapo. Sowas fand ich aber nicht. Also schnell selbergeschrieben.

Die Anwendung selber kann in der derzeit aktuellen (Beta) Version auf www.pracma.de unter “Download” heruntergeladen werden. Der komplette Quellcode der Anwendung inklusive der dazu nötigen Erklärungen gibts hier.

Das Prinzip ist – wie immer – eigentlich recht einfach. Man startet das Programm und bei Programmstart prüft die Anwendung nach auffindbaren SQL Instanzen. Diese werden gelistet und man kann sich per Login einwählen. Ein paar grundsätzliche Infos zu dem angemeldeten Server werden abgerufen und angezeigt (Version etc.) und die zur Verfügung stehenden Datenbank – natürlich abhängig vom angemeldeten User – aufgelistet. Nach Auswahl einer Datenbank kann man eine darin befindliche Tabelle auswählen und darin die zu skriptenden Felder. Hieraus wird dann ein SQL-INSERT ím Batch erzeugt. Das ganze funktioniert natürlich nicht nur mit lokalen sondern auch entfernten SQL-Servern.

1. SQL Server Instanzen abfragen
Die Abfrage von verfügbaren (also direkt erreichbaren) SQL Instanzen ist per .Net mit recht wenig Code machbar:

        Dim oSqlInstance As SqlDataSourceEnumerator = SqlDataSourceEnumerator.Instance
        Dim oDataTable As System.Data.DataTable = oSqlInstance.GetDataSources()
        Dim oRow As DataRow

        Dim oInstances As New ArrayList
        Dim sInstance As String
        oInstances = New ArrayList

        For Each oRow In oDataTable.Rows
            sInstance = oRow.Item("ServerName").ToString
            If Len(oRow.Item("InstanceName").ToString) > 0 Then
                sInstance &= "\" & oRow.Item("InstanceName").ToString
            End If

            oInstances.Add(sInstance)
        Next

was hier passiert ist, dass eine ArrayList definiert wird, die alle verfügbaren SQL-Instanzen aufnimmt. Diese Collection ist nicht nur einfach zu handeln sondern kann auch einfach als Datasource an bsw eine DropdownList gebunden werden.

        Me.cboSqlInstances.DataSource = oInstances

Gründe genug sich immer wieder für diese Art der internen Datenhaltung zu entscheiden.
Es wird im ersten Schritt eine Enumeration über alle SQL-Instanzen initialisiert, dann diese in einer DataTable gebunden und schließlich nacheinander durchgegangen um die Instanz-Namen in die ArrayList zu extrahieren.

2. Die Anmeldung
Nach der Eingabe von einem Login und Passwort (per Textfelder und mit der Unterscheidung ob man diese überhaupt ausfüllen muss [SQL Authentifizierung] oder nicht [Windows-Authentifizierung]) müssen wir per Code die Anmeldung ausführen. Dazu bedienen wir uns einem ConnectionStringBuilder und übergeben dem – abhängig von SQL-Authentifizierung oder Windows-Anmeldung – die Anmeldedaten:

        private _oSqlConnection  As SqlConnection
        Dim oConnectionStringBuilder As SqlConnectionStringBuilder

        oConnectionStringBuilder = New SqlConnectionStringBuilder

        With oConnectionStringBuilder
            .DataSource = Me.cboSqlInstances.Text
            If Me.cbIntegratedSecurity.Checked Then
                .IntegratedSecurity = True
            Else
                .IntegratedSecurity = False
                .UserID = Me.txtUser.Text
                .Password = Me.txtPassword.Text
            End If
        End With

        _oSqlConnection = New SqlConnection(oConnectionStringBuilder.ConnectionString)
        Try
            _oSqlConnection.Open()
        Catch ex As Exception
            MsgBox("Could not connect to SQL Server. Please review the login parameters.")
            Exit Sub
        End Try

Erhalten wir in dieser Routine keinen Fehler, dann sind wir bei dem Server angemeldet.

3. Grundlegende Informationen zu der Instanz abfragen
Wollen wir ein paar Infos darüber erhalten was das für ein Server ist und mit welcher Version wir es zu tun haben, lässt sich das nach Anmeldung mit dem Server per SQL gut erledigen. Als erstes brauchen wir die Version um die weiteren Schritte – abhängig davon – auszuführen.

Die Version des MSSQL Servers erhalten wir mit

SELECT SERVERPROPERTY('productversion') AS ProductVersion, SERVERPROPERTY ('productlevel') AS ProductLevel, SERVERPROPERTY ('edition') AS ProductEdition

Hieraus erhalten wir drei verschiedenen Informationen:
a) die erste Stelle des Resultstring von SERVERPROPERTY(‘productversion’) AS ProductVersion verrät uns die Hauptversion des Servers. Hier steht bsw. “8” für einen MSSQL Server 2000, eine “9” für 2005 und so weiter. Diese Property verrät uns den kompletten Versionsstand.
b) SERVERPROPERTY(‘productlevel’) AS ProductVersion, also Hinweise auf das installierte ServicePack
c) SERVERPROPERTY(‘edition’) AS ProductVersion verrät uns die Edition, also bsw eine “Developer Edition” oder ähnliches

Damit schließe ich mal den heutigen Part. In den folgenden Teilen zeigen wir alle verfügbaren Datenbanken an und wählen per Listbox eine aus um die Tabellen zu erhalten um daraus die Felder auszuwählen die wir als INSERT scripten wollen.
Und ganz zum Schluß gibts vielleicht auch eine Solution zum download…