Glorf.it

Glorf IT

Bedenkliches aus dem IT-Alltag

21. Mai 2007 um 18:57

Verbindungseinstellungen

Wenn man sich mit einer Anwendung zum SQL-Server verbindet, dann kann und sollte man über die Sitzungsseinstellungen das Verhalten des SQL-Servers konfigurieren. Das ist recht kompliziert, weil

Die für eine Session tatsächlich geltenden Optionen kann man auf zwei Arten herausbekommen. Entweder auf die "harte Tour": @@OPTIONS enthält die Werte in kodierter Form. Um sie im Klartext zu bekommen, kann man sich behelfen.

select
name as "SetOption",
(case when @@options&number=number then 1 else 0 end) as "Status"
from master..spt_values
where type=(select type
from master..spt_values
where number=0 and name='@@options')
and number != 0

Das Ergebnis sieht beispielsweise so aus:

SetOption                           Status
=======                             =====
disable_def_cnst_check              0
implicit_transactions               0
cursor_close_on_commit              0
ansi_warnings                       1
ansi_padding                        1
ansi_nulls                          1
arithabort                          1
arithignore                         0
quoted_identifier                   1
nocount                             0
ansi_null_dflt_on                   1
ansi_null_dflt_off                  0
concat_null_yields_null             1
numeric_roundabort                  0
xact_abort                          0

Alternativ kann man auch DBCC verwenden. Hier werden nur die Optionen angezeigt, die tatsächlich aktiv sind. Ein ARITHIGNORE = OFF wird also nicht angezeigt.
dbcc useroptions

Wie man sieht, werden aber auch so nützliche Sachen wie DATEFORMAT oder LANGUAGE angezeigt:

SetOption                  Value
=======                    =====
textsize                   2147483647
language                   Deutsch
dateformat                 dmy
datefirst                  1
lock_timeout               -1
quoted_identifier          SET
arithabort                 SET
ansi_null_dflt_on          SET
ansi_warnings              SET
ansi_padding               SET
ansi_nulls                 SET
concat_null_yields_null    SET
isolation level            read committed
18. Mai 2007 um 20:23

Trigger – wie viele Sätze sind betroffen?

Gestern las ich bei coreworxx den Artikel "UPDATE Trigger – schon mal reingefallen?" und wollte auch gleich einen Kommentar schreiben. Weil ich dazu aber einen Google-Account einrichten müsste, antworte ich lieber hier und setze einen Trackback…
Schade, weil ich jetzt erst mal den Kontext herstellen muss, damit man nicht erst den einen Artikel lesen muss, um diesen zu verstehen. Übrigens liebe ich es Artikel über SQL-Themen zu lesen: also bitte nicht abschrecken lassen…

Andreas Gümbel beschreibt in dem Artikel, wie man mittels der Tabellen INSERTED und DELETED mitbekommt wie die Werte des geänderten Datensatzes vor und nach der Änderung kommt. Hier eines seiner Beispiele:

CREATE TRIGGER [TRIGGER_NAME_Update] ON [dbo].[myTableName]
FOR UPDATE
AS
DECLARE @myInsertId int
SELECT @myInsertId=myTableId FROM INSERTED
[weitere Verarbeitung …]

Das ist völlig korrekt beschrieben.
Aber dennoch würde ich von diesem Statement abraten. Es geht strikt davon aus, dann immer nur ein einziger Datensatz geändert wird. Um die optimale Performance zu erreichen werden in Datenbanksystemen aber immer möglichst alle betroffenen Datensätze mit einem Schwupps geändert.
Ich merke immer wieder, dass es gerade altgedienten Programmierern schwer fällt, dass man jetzt nicht mehr mühsam alles über eine Schleife machen muss: In SQL macht man das mit einem einzigen Befehl. Hier mein Lieblingsbeispiel: Alle Mitarbeiter der Datenbankbetreuung bekommen eine 10%ige Gehaltserhöhung…

UPDATE Stammdaten.Mitarbeiter
SET Gehalt = Gehalt * 0.1
WHERE team='Datenbanktechnologie'

Das Statement dauert fast genau so lange wie der Update eines einzelnen Datensatzes. Deswegen macht man eher selten einen Update auf einen Satz. Und selbst wenn man jetzt fest überzeugt ist, dass man niemals mehrere Sätze gleichzeitig wird. Sollte man das dennoch vorsehen, weil sich meiner Erfahrung nach sehr schnell die Randbedingungen ändern und "Puff" knallt der Trigger mitten im laufenden Betrieb an die Wand.
Das ist übrigens eine Tuningmaßnahme, die ich immer wieder bei Performanceanalysen empfehlen muss: Mengenupdates anstelle von Schleifen. In der ersten Runde geht es meist auf gar keinen Fall, weil man ja in dem jeweiligen Objekt keine Infos darüber hat, welche anderen Objekte sonst noch betroffen sind. Wenn der Druck von Seiten der Kunden steigt, geht es meistens doch…

Daher: Im Trigger selber bitte immer die Verarbeitung von mehreren Datensätzen vorsehen.

17. Mai 2007 um 12:51

Übersichtsartikel: SQL-Server-Replication

Robyn Page bietet in dem Artikel "SQL Server Replication Crib Sheet" einen sehr schönen Übersichtsartikel rund um die Replikation des SQL-Servers. Das freut mich besonders, weil ich in letzter Zeit immer wieder zu dem Thema und nach Übersichtsartikel dazu befragt wurde. 🙂

Neben den ausgezeichneten weiterführende Links im Artikel von Robyn Page (ganz unten), möchte ich Folgende explizit nennen:

17. Mai 2007 um 12:49

neue Demo-DB

Kaum passt man mal nicht auf, da verpasst man etwas wichtiges. Aber zum Glück hat mich der Newsletter des SQL-Server-Magazine noch darauf hingewiesen: Es gibt eine neue Demo-Datenbank für den SQL-Server-2005.

Sie heißt "AdventureWork Light" und ist eine kleine niedliche DB, die alles enthält, was man braucht. Tatsächlich fand ich die neue Adventure-Works auch so klobig, das ich für meine Schulungen immer noch die "Northwind" verwendete. Und das nicht bloß aus Faulheit, damit ich meine Schulungen nicht ändern muss, sondern auch für völlig neue Schulung, wie die zum Thema "XML mit dem SQL-Server-2005".

Die AdventureWorks ist zwar viel vorbildlicher als die Northwind, aber eben so komplex, dass ich schon eine ganze Stunde investieren müsste, um den Schulungsteilnehmer die DB-Struktur zu erklären…

Die Neue ist hingegen klein und recht leicht zu verstehen. Ob das eine Alternative ist, muss ich mal schauen, wenn ich versuche meine erste Schulung darauf umzustricken…

Der Dwnload findet sich auf der Seite "SQL Server 2005 Samples and Sample Databases February 2007" gut versteckt. deswgeen hier auch noch der direkte Link.

15. Mai 2007 um 20:32

Unit-Testing ohne Ende

Heute habe ich zum dritten mal in den letzten Tagen Kollegen von meine Erfahrungen mit den Unit-Tests für Datenbank-Objekte erzählt. Dazu benutze ich die "Visual Studio Team Edition for Database Professionals", die ich eigentlich wegen anderer Dinge angeschaut habe.
Das interessant daran ist, dass ich mittlerweile zwar schon recht deutlich ein paar Nachteile sehe, aber schon denke, dass es sich schon fast alleine wegen der Units-Tests lohnt die sehr teure Lizenz anzuschaffen.

Es wird einem echt viel Arbeit abgenommen und man muss sich nur um wenige Dinge selber kümmern. Man kann alles Testen, das sich mit SQL ausdrücken lässt: Prozeduren, Funktionen, Views, Trigger, sogar Assemblies.
Ich denke, es eignet sich besonders gut für entwicklungsbegleitendes Testen.

Hier ein paar Schattenseiten, die ich schon fand:

  • Für Negativ-Tests muss man gewünschte Fehlermeldungen in einem Catch-Block auffangen und schauen, ob der gewünschte Fehler auftrat. Wenn nicht, muss man einen Fehler werfen. Das geht schon, ist aber unnötig aufwändig: Es wäre schön, wenn man eine Test-Bedingung "Fehler xy tritt auf" angeben könnte.
  • Es gibt keine Test-Bedingung, die ein ResultSet mit einer Datei vergleicht. Allerdings war es nur ein geringer Aufwand so eine Erweiterung selber zu schreiben.
  • Man kann nicht automatisch die gleichen Tests mit verschiedenen Datenbanken (z.B. mit verschiedenen Datenmengen oder Konstellationen) hintereinander ausführen. Mann muss dazu selber etwas außen rum machen, dass die DBs "austauscht" und die Tests dann neu startet. Dazu hatte ich noch keine Lust, äh Zeit, wird mir aber vermutlich nicht erspart bleiben.

Ich glaube, dass ich langsam aus dem Hype rauskomme und in die Phase "get real" reinrutsche… 😉

10. Mai 2007 um 22:21

Unit-Tests für Datenbank-Objekte

Ich bin derzeit total begeistert von den neuen Möglichkeiten der Unit-Tests für Datenbank-Objekte mit der neuen "Visual Studio Team Edition for Database Professionals" (DB-Pro). Einfach unglaublich, wie einfach und komfortabel das geht. Man kann für alle Datenbank-Objekte Unit-Tests erstellen. Ich mache aktuell welche für Stored-Procedures und Functions, aber man kann genauso gut Views automatisch testen.

Für "meine" etwa 50 Prozeduren habe ich schon etwa 180 Unit-Tests geschrieben. Bei Ausdenken der neuen Tests bzw. Umschreiben der alten (ich testete bislang mit einem eigenen Werkzeug) stoße ich immr wiedre auf kleinere Macken, die nach der Umstellung auf SQL-Server-2005 viel eleganter zu machen sind. Mit den Unit-Tests ist das kein Problem: Vorher Tests laufen lassen, Änderung durchführen und wieder die Tests laufen lassen. Wenn dann kein Fehler kommt, dann kann ich sicher sein, dass die Änderung klar ging.

Mit dem sehr guten Artikel "Database Unit Testing with Team Edition for Database Professionals" fiel mir der Einstieg in die Thematik sehr leicht.

Auf dem Weblog des Autors findet sich übrigens ein Beispiel, wie eigene Testbedingungen anlegen kann. Das klappt ganz gut, nachdem ich aus der Datei "SachTestConditions.extensions.xml" das Attribut "xsi:schemaLocation" vom Element "extensions" entfernt hatte.

Ein Beispiel bei SQL-Server-Central (kostenlose Anmeldung erforderlich), dass jedoch leider einige Patzer enthält, z.B fehlt in der Extension-Xml die Angabe des Attributs xmlns, ist der Artikel "Putting Unit Tests to Work".

Alleine schon wegen dieser tollen Möglichkeit rund um Unit-Tests zu SQL-Server-Datenbankobjekten würde ich jedem Datenbank-Entwickler dazu raten sich diese Edition anzuschaffen. Der Preis ist schon ganz schön hoch, aber der Zugewinn in der QS sollte dem Chef die Ausgabe wert sein…

8. Mai 2007 um 19:16

Wenn der Sommer kommt, verabschieden sich die Platten

Ich nutze die leichte "Kälteperiode", um an ein heißes Problem zu erinnern, das nun wieder auf uns zu kommt: Festplatten verkraften keine Hitze.

Diese triviale Weisheit wird gerne vergessen oder verdrängt. Deswegen der Rat doch noch mal zu überprüfen, wo der Server mit den wichtigen Daten steht: Unter dem Dach? In einem fensterlosen Raum ohne Klimananlage? Ist ein Thermometer in dem Raum?

Natürlich ist auch ein Standort im tiefen Keller nicht immer die beste Wahl (siehe "Problem mit dem Safe"), aber dennoch sind die Hitzeperioden meiner Erfahrung nach die bedeutensten Plattenkiller.

Wir hatten beispielsweise letztes Jahr einen recht lehrreichen Fall bei einem unserer Kunden:
Im seinem Geschäft war es eines Freitags im Laufe des Tages so heiß geworden, dass er zum Feierabend mal lieber alle Rechner herunterfuhr, auch den Server. Die Rechner hatten Zeit sich zu erholen und mussten nicht die unbemannten Räume heizen. Am Montag früh wurde der Server gestartet. Wie sich herausstellte, waren da alle Datenbanken im Eimer, weite Teile der Platte übrigens auch.

Leider kannte ich zu dem Zeitpunkt noch nicht den Artikel "Hitzetod: Jeder PC ist gefährdet" aus TecChannel.

Aus den Datenbank-Dateien konnten wir keinen fachlich brauchbaren Stand mehr basteln. Tragischerweise führte der Kunde immer nur am Wochenende eine Datensicherung durch, aber da war der Server ja gestoppt…
🙁

Deswegen der Tipp: Nur abends oder am Wochenende die Kisten ausschalten reicht nicht: Man benötigt einen kühlen Standort für die Server. Auch in einem kleinen Laden.

2. Mai 2007 um 20:03

Und dann kam Jasper

Ich bin noch nicht mal dazu gekommen mich in LINQ einzuarbeiten, da schiebt Microsoft schon das nächste Datenzugriffs-Api nach: Jasper

"Jasper" ist der Codename für "Dynamic ADO.NET 3.0" und bietet angeblich:

  • dynamische Klassengenerierung (ohne Konfiguration)
  • umfangreiches O/R-Mapping
  • automatisches Binding für ASP.NET, WinForms und WPF

Die ersten beiden Punkte lassen aufhorchen und könnten begeistern, immerhin fehlt es hier bisher immer noch ein Stückchen. Der Letzte macht es aber auch ein wenig suspekt, womöglich werden hier die Oberflächen auch wieder so stark an die Datenzugriffsklassen drangeklebt?

Warten wir es ab, interessant wird es auf jeden Fall. Infos aus ersten Hand findet man im Ado-Net-Blog.

Eine ganz hübsche Sammlung zu allen Jasper- Informationen findet man im OakLeaf-Blog: ""Jasper" to Deliver Dynamic ADO.NET 3.0"

Der Download des CTP steht seit zwei Tagen bereit. Als Vorausetzung benötigt man aber das Visual Studio (Codename "Orcas") Beta1…

2. Mai 2007 um 19:53

SQL Server 2005 Performance Dashboard

Heute habe ich mal das neue "SQL Server 2005 Performance Dashboard" installiert und damit rumgespielt. Ich bin wirklich begeistert. Die neuen Berichte sind wirklich nützlich. Ich denke, dass sollten wir zur Standard-Ausrüstung eines jeden Test-Systems erklären…

Aufmerksam wurde ich durch den Artikel "Making the Most Out of the SQL Server 2005 Performance Dashboard" bei sql-server-performance.com. Er enthält auch jede Menge Screenshots und eine sehr detaillierte Auflistung der einzelnen Berichte.

Meiner Ansicht nach sind viele der ganz wichtigen Dinge abgedeckt, ein paar Beispiele:

  • die aufwändigsten Anfragen (nach CPU-Zeit, oder IO oder Dauer)
  • Missing Indexes
  • CPU-Auslastung (gesamt und Anteil des SQL-Servers)
  • Waiting Request, kummulative Wartezeiten nach Typ,

Klingt gut? Ist gut!

Link: Download

27. April 2007 um 20:00

SQL-Server: GO 10

Was ich gerade bei Jon Galloway im Artikel "Using 'GO 100' to execute a batch 100 times" las, habe ich nicht gewusst. Microsoft hat in die Werkzeuge des SQL-Servers-2005 ein nettes und undokumentiertes Feature eingebaut: Ein Batch wird in einer Schleife mehrfach wiederholt. Echt cool!

Mal ein Beispiel:

print 'Hello'
go 10

liefert als Ergebnis im Message-Window des Management-Studio:

Beginning execution loop
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Batch execution completed 10 times.

Das geht genauso im sqlcmd (allerdings ohne "Beginning execution loop" und "Batch execution completed x times.") und im mitgelieferten osql (mit "x xacts:" am Ende).

Das "go" ist ein reiner Steuerungsbefehl für die Werkzeuge und dient dazu zwei Batches hintereinander an den SQL-Server zu schicken. Das wurde jetzt aufgebohrt.

Tatsächlich gibt es dazu einige nützliche Anwendungen:

  • Wenn man mal eben schnell ein paar hundert Datensätze einfügen will und keinen Bock auf eine Schleife hat.
  • Protokollieren von dynamischen System-Eigenschaften, wie die Wait Events oder Informationen über Blockierungen
  • Wenn man den SQL-Server unter Last setzen will, um das Verhalten des Systems zu beobachten.

Risiken und Nebenwirkungen: Weil es undokumentiert ist, haftet Microsoft für nix und behält sich vor, das tolle Feature jederzeit wieder einklappen zu können. Das fände ich allerdings ziemlich schade…

gefunden bei TheDailyGrind
26. April 2007 um 19:40

Celko des Tages

Im Artikel "Joe Celko The SQL Apprentice: Stored procedure returns duplicates" wird Joe Celko zitiert, wie er völlig fassungslos auf das Listing einer SQL-Prozedur eines SQL-Anfängers in einer UseNet-Gruppe reagiert, der das Konzept von SQL einfach nicht verstanden hat:

EVERYTHING you are doing is TOTALLY wrong. You have just been cussed but by one of the people who wrote this language. If you have brain instead of an ego, you might want to listen.

This is a (bad) COBOL program written in SQL! There is so much formatting done in SQL code! The bad news – for me– is that this code is so awful I cannot use it in my next book as a bad example because it is too proprietary! You could be famous!

Your code is so awful, you even use the "tbl-" prefixes to tell us you have no idea about RDBMS! You keep converting dates to strings because you are writing COBOL in SQL and want strings!

"cussed" heißt laut Leo übrigens "verflucht". Und Joe ist tatsächlich einer der Verfasser von SQL.

Falls es für irgendjemandem ein Trost ist: mich hat er übrigens auch mal zur Schnecke gemacht, weil ich in SQL-Server-Manier "GO" zwischen die SQL-Statements schrieb und im Sample-Create generell alle Spalten auf "NULLable" setzte…

Hat mir gut getan, ich nahm es mir zu Herzen. 😉

25. April 2007 um 21:28

Celko des Tages

In dem Posting "Joe Celko The SQL Apprentice: dynamically change column name when displaying" wird ein SQL-Newbie zitiert. Da läuft es einem kalt den Rücken runter. Die Antwort von Joe Celko ist einfach nur großartig!

You have missed the ENTIRE CONCEPT OF A TIERED ARCHITECTURE!!

You NEVER query a table for display; you query a table for **data** and the front end does their display. You are writing 1950's file systems in SQL!!

Joe, du hast recht! Danke!