Dienstag, 31. März 2015

Liste der SQL Server Fehlercodes

Eine Liste der Fehlercodes, die der SQL Server ausgeben kann, findet sich in der Dokumentation. Wenn Sie jedoch gerade keinen Zugriff aufs Internet haben, können Sie auch den SQL Server direkt fragen:

select * from sys.messages

Das ist sehr praktisch, wenn Sie einen Fehlercode  haben und den vollständigen Text der Fehlermeldung nachschlagen möchten. Oder wenn Sie die deutsche Fehlermeldung kennen und den englischen Text wissen möchten um ihn zum Beispiel in einer Suchmaschine einzugeben. Das ist möglich, weil die Tabelle sys.messages alle Fehlermeldungen in 22 verschiedenen Sprachen enthält.


Tabelle sys.messages enthält jede Fehlermeldung in verschiedenen Sprachen
Welche language_id zu welcher Sprache gehört, können Sie in einer anderen Systemtabelle nachschlagen:

select *
from sys.syslanguages


In der Spalte msglangid dieser Tabelle finden Sie den zu language_id korrespondierenden Wert. In welcher Sprache Sie die Fehlermeldungen sehen, hängt von den Ländereinstellungen auf dem Betriebssystem des Clients ab, der die Verbindung zum SQL Server aufgebaut hat. Wenn Sie die Sprache für eine Verbindung umstellen möchten, können Sie das mit diesem Befehl machen:

SET LANGUAGE FRENCH; 

Mehr zur SET LANGUAGE Anweisung finden Sie in der MSDN.

Sonntag, 1. März 2015

SQL Server Migration Assistant (SSMA) und die Sortierreihenfolge der Datenbanken

Bei der Migration einer größeren Oracle Datenbank nach MS SQL Server haben wir den SQL Server Migration Assistant (SSMA) for Oracle in der Version 6 eingesetzt. Wirklich ein sehr hilfreiches Tool!

Laufzeitprobleme nach Umzug der Datenbank


Ein größeres Problem trat auf, nachdem wir die migrierte SQL Server Datenbank gesichert und auf einer anderen SQL Server Instanz wiederhergestellt hatten. Beim Ausführen von gespeicherten Prozeduren, die der SSMA generiert hatte, gab es auf einmal diesen Laufzeitfehler:

Msg 217, Level 16, State 1, Line 1
Maximum stored procedure, function, trigger, or view nesting level exceeded (limit 32).

Auf dem alten SQL Server funktionierten dieselben Funktionsaufrufe weiterhin fehlerfrei. Die Ursache musste also irgend etwas mit dem neuen Server zu tun haben.

Sortierreihenfolge als Fehlerursache


Um es kurz zu machen: Die Sortierreihenfolge der neuen SQL Server Instanz (Server Collation) war eine andere als auf dem alten Server. Dadurch hatte auch die Systemdatenbank master eine andere Sortierreihenfolge (Database Collation) als die auf dem alten Server. Erst einmal ist nicht ersichtlich, warum das zu Problemen führen könnte. Der Hintergrund ist Folgender: In der master Datenbank werden durch das SSMA Extension Pack drei Extended Stored Procedures installiert. Der vom SSMA generierte T-SQL Code verwendet Kompatibilitätsfunktionen (das sind die im Schema ssma_oracle), welche ihrerseits wiederum diese Extended Stored Procedures in master aufrufen.

Wenn die master Datenbank und die Benutzerdatenbank mit vom SSMA generierten T-SQL Code unterschiedliche Sortierreihenfolgen aufweisen, dann tritt reproduzierbar dieser Fehler auf.

Das Aufspüren dieser Fehlerursache hat unser Team viel Zeit gekostet. Vielleicht hilft diese Erläuterung ja jemandem, der ebenfalls auf dieses etwas exotische Problem stößt. Wir haben es übrigens beseitigt, indem wir die Sortierreihenfolge der Benutzerdatenbank umgestellt haben. Das ist einen weiteren Blog-Post wert, den ich in den nächsten Tagen schreiben werde.

Samstag, 28. Februar 2015

SSMS: Mit Suchen und Ersetzen Zeilenumbrüche einfügen

Oft wäre es nützlich, im SQL Editor von SQL Server Management Studio mit Suchen und Ersetzen auch Sonderzeichen wie "neue Zeile" einfügen zu können. Beispielsweise um vor jedem "CREATE" Statement noch ein "GO" einzufügen, denn nach "GO" muss immer eine neue Zeile beginnen.
Auf dem direkten Weg ist es nicht möglich Sonderzeichen einzugeben. Doch durch die Verwendung regulärer Ausdrücke eröffnen Sie sich diese und noch eine ganze Palette weiterer Möglichkeiten.

Reguläre Ausdrücke sind der Schlüssel


Die im Bild dargestellte Option "Use - Regular expressions" interpretiert die Zeichenfolgen in den Eingabefeldern "Find what" und "Replace with" unter Berücksichtigung der Regeln für reguläre Ausdrücke.

Mit regulären Ausdrücken wird das Suchen und Ersetzen erheblich leistungsfähiger
Weil in regulären Ausdrücken die Zeichenfolge "\n" die Bedeutung "neue Zeile" hat, fügt das im Bild dargestellte Beispiel vor jedem "CREATE" ein "GO" und eine neue Zeile ein.

Vor allem aber können Sie reguläre Ausdrücke bei der Suche von Mustern im Text verwenden, indem Sie diese im Eingabefeld "Find what:" eingeben. Gerade erst musste ich in einem sehr langen SQL Skript alle Funktionsaufrufe finden, denen kein Schemaname vorangestellt war. Da die Funktionsnamen alle mit "fn_" begannen, konnte ich die betreffenden Stellen im Text mit diesem Ausdruck in "Find what:" schnell finden:
[^.]fn_  Dieser reguläre Ausdruck liefert alle Stellen, wo vor fn_ kein Punkt steht. Ist diese Hürde erst einmal genommen, ist es ein Leichtes, mit Suchen und Ersetzten an diesen Stellen noch den Schemanamen hinzuzufügen. In meinem Fall dauerte das für ca. 400 Ersetzungen nur wenige Sekunden.

Eine vollständige Dokumentation regulärer Ausdrücke finden Sie zum Beispiel in der MSDN oder in diesem Wikipedia Artikel.

Noch ein Tipp: Gerade wenn das gesuchte Muster an sehr vielen Stellen im Text vorkommt, dann ist die Option "Find in Files" eine großartige Hilfe. Sie erreichen diese Funktion hier:

Find in Files erstellt eine Liste mit allen Stellen, wo der Suchausdruck gefunden wurde

Fazit: Der Texteditor im Management Studio bietet viele leistungsstarke Funktionen für das Suchen und Ersetzen in Texten. Man muss nur genau hinsehen um sie zu finden.

Sonntag, 15. Februar 2015

Zahl der zertifizierten Business Analysten wächst weiter

Auch im Jahr 2014 ist die Zahl der nach den Anforderungen der IIBA zertifizierten Business Analysten weiter stark gewachsen. Die Grafik zeigt das eindrucksvoll:

Auch 2014 ist die Zahl der zertifizierten Business Analysten stark gewachsen

CBAP: Certified Business Analysis Professional
CCBA: Certified Competency in Business Analysis

In Deutschland ist die Zahl auf 33 CBAP und 2 CCBA angewachsen, zeigt aber im europäischen Vergleich z.B. gegenüber England, Italien und der Schweiz immer noch einen deutlichen Nachholbedarf. Es fällt auch auf, dass inzwischen die Anzahl der CCBA, das sind jüngere Business Analysten, die noch nicht über so viel Berufserfahrung verfügen wie CBAP, deutlich gestiegen ist. Damit gewinnt dieses Zertifikat weitere Anerkennung. Das entspricht meiner Wahrnehmung, dass die Rolle des Business Analysten als Partner des Projektmanagers und als Garant für den Projekterfolg in Bezug auf die Qualität immer bekannter wird. Nicht zuletzt deswegen, weil Projekte, in denen ein qualifizierter Business Analyst mitwirkt, in aller Regel zuverlässiger und mit besserem Erfolg abgeschlossen werden.

Zumindest sind das die Erfahrungen, die ich in meinem beruflichen Umfeld "Business Intelligence" mache. Gerade in BI Projekten, die naturgemäß komplex sind und viele Beteiligte haben, kommen bei Fehlplanungen schnell fünf- und sechsstellige zusätzliche Beträge zusammen, die sich durch die Arbeit eines Business Analysten hätten vermeiden lassen. Das liegt auch daran, dass der Business Analyst wie die IIBA ihn definiert, viel mehr leistet, als lediglich die Anforderungen (Requirements) aufzunehmen, qualitativ hochwertig zu machen und systematisch die Änderungen von Anforderungen zu klären und genehmigen zu lassen. Der Business Analyst stellt darüber hinaus auch zum Beispiel Fragen in Bezug auf die Versionierung einer Lösung (in welchen Schritten wird die Lösung bereitgestellt), die erforderlichen Änderungen bei den Fachanwendern (Schulung, Änderungen bestehender Abläufe, Konvertierung von Daten) und vor allem immer wieder nach dem Wert, den eine neue Lösung (oder ihre Teile) dem Unternehmen liefert. So trägt der Business Analyst entscheidend dazu bei, dass das Projekt auf Kurs bleibt und dass das eingesetzte Geld den größtmöglichen Nutzen für den Auftraggeber bringt. Das sich daraus ergebende positive Arbeitsklima ist ein weiterer angenehmer Nebeneffekt für alle Beteiligten.

Nun bin ich gespannt, was das Jahr 2015 der Business-Analysten Gemeinde bringt und wann wir die Marke von 10.000 CBAPs und CCBAs "knacken" werden.

Quelle: IIBA

Sonntag, 11. Januar 2015

Mit ReportItems auf Inhalte in Tablix-Zellen zugreifen

In etwas anspruchsvolleren Berichten benötigen Sie gelegentlich die Möglichkeit, den Inhalt der Zelle in einer Tabelle oder Matrix an anderer Stelle noch einmal zu verwenden. Das ist durchaus möglich aber nicht ganz offensichtlich.

Ein einfaches Beispiel

Im vorliegenden Beispiel sehen Sie zwei Tabellen, in denen die Umsätze unterschiedlicher Länder dargestellt werden. Der Bericht soll nun noch um ein Textfeld erweitert werden, das die Summe der beiden "Total" Zellen berechnet.


Das Textfeld rechts unten zeigt die Summe der "Total"-Zellen der beiden Tabellen an

Um das zu erreichen, ist es nützlich den beiden Tabellenzellen erst einmal sprechende Namen zu geben. Exakter ausgedrückt: Eine Tabelle (Tablix) in SSRS besteht aus TextBoxen. Diejenigen TextBoxen in den Tabellen, welche den "Total" Wert enthalten, bekommen die Namen "SummeTablix1" und "SummeTablix2". Das folgende Bild zeigt dies deutlicher.


Der Name dieser TextBox wird geändert nach "SummeTablix1"
Nach dieser Vorbereitung kann die neue TextBox rechts unten im Bericht hinzugefügt werden. Der folgende Ausdruck leistet das Gewünschte: 

 =ReportItems!SummeTablix1.Value + ReportItems!SummeTablix2.Value

Die hier verwendete ReportItems Collection enthält alle TextBoxen einer Berichtsdatei. Allerdings ist sie an der grafischen Oberfläche nicht sichtbar. Sie müssen einfach wissen, dass es diese Collection gibt und dann können Sie diese in einer Expression eintippen. Lassen Sie sich nicht irritieren - erst nachdem Sie das Ausrufezeichen nach dem Wort "ReportItems" eingegeben haben, erscheint die Drop-Down Liste als Eingabeunterstützung und bietet Ihnen die Namen aller TextBoxen in diesem Bericht zur Auswahl an. Dies ist der Punkt, wo sich die sprechenden Namen der betreffenden TextBoxen als nützlich erweisen.

Erst nach Eingabe des Ausrufezeichens hinter dem Wort ReportItems nimmt die Eingabehilfe ihre Arbeit auf

Wenn sie diese Hürde genommen haben, ist es ein Leichtes den Ausdruck vollständig einzugeben.

Noch ein Beispiel

Sie möchten in einer Tabelle Verhältniszahlen berechnen? Mit ReportItems ist das kein Problem mehr. Nehmen wir folgende Anforderung als Beispiel: Neben dem Umsatz eines Jahres soll sein prozentualer Anteil am Umsatz aller Jahre angezeigt werden.

Der "Sales Amount" für das Jahr 2005 entspricht 20% des "Sales Amount" über alle Jahre

Der Ausdruck in der Spalte "% Umsatz" ist der Umsatz eines Jahres geteilt durch die Summe des Umsatzes über alle Jahre:

=ReportItems!SalesAmount1.Value / ReportItems!SummeTablix1.Value

ReportItems in Kopf- und Fußzeilen

Noch ein schöner Anwendungsfall ist der Einsatz von ReportItems in Kopf- oder Fußzeilen eines Berichts. Nehmen wir an, in der Kopfzeile soll das erste und das letzte Jahr angezeigt werden, das auf der jeweiligen Seite zu sehen ist. Um das besser demonstrieren zu können, habe ich meinen Beispiel-Bericht so verändert, dass nur noch maximal 3 Jahre auf einer Seite dargestellt werden. (Hierfür habe ich einfach in der Eigenschaft des Berichts "InteractiveSize" die Höhe auf 3 Zentimeter reduziert.)

In der Kopfzeile werden die erste und die letzte Jahreszahl auf dieser Seite angezeigt
Mit Hilfe der Aggregatfunktionen First() und Last() können Sie das erste Jahr und das letzte Jahr in der Spalte "OrderYear" ermitteln. Jedoch gibt es noch eine kleine Hürde zu nehmen. Denn wenn Sie versuchen, einen Ausdruck wie den folgenden zu verwenden, erhalten Sie eine Fehlermeldung:

="Von " & First(ReportItems!OrderYear.Value) & " bis " & Last(ReportItems!OrderYear.Value)

Die Fehlermeldung besagt, dass Sie in Kopf- und Fußzeilen pro Ausdruck jeweils nur ein ReportItem verwenden dürfen.
Zur Lösung könnten Sie zwei nahe nebeneinander gelegene TextBoxen verwenden. Noch eleganter finde ich allerdings die Verwendung von zwei Platzhaltern in derselben TextBox. Jeder Platzhalter wird über einen eigenen Ausdruck mit Inhalt gefüllt.

Eine TextBox kann mehrere Platzhalter enthalten
Der erste Platzhalter enthält diesen Ausdruck:

="Von " & First(ReportItems!OrderYear.Value) & " bis "

Der zweite Platzhalter enthält diesen Ausdruck:

=Last(ReportItems!OrderYear.Value)

Voilá!

Die offizielle Dokumentation

ReportItems sind natürlich auch in der MSDN dokumentiert, wenn auch etwas abstrakt, wie ich finde. Das entsprechende Kapitel in der MSDN enthält hierzu noch einige interessante Anmerkungen über die interne Arbeitsweise von Reporting Services.