Extrahieren von Teilstrings aus z.B. einer kommaseparierten Liste kann man überall nachlesen. Für Fragestellungen, bei denen es um die Extraktion von Teilstrings stets gleicher Länge geht, kann man aber auch einen anderen Lösungsansatz verwenden.
Vorweggeschickt mag man durchaus darüber diskutieren, ob eine eigene Funktion zur Ermittlung eines Schaltjahres im SQL Server zwingend notwendig ist, da die meisten Client Sprachen bereits mit ausgefeilten hochoptimierten Datumsbibliotheken ausgestattet sind und daher deutlich bessere Performance bieten sollten als pseudokompiliertes T-SQL, aber ehrlich gesagt geht es mir jetzt mehr darum, einen Weg zu zeigen, wie eine T-SQL basierte Lösung für dieses Problem aussehen könnte. Und die Entscheidung, ob die vorgeschlagene Lösung eingesetzt wird, mag jeder Leser mit sich selber und seinen Anforderungen ausmachen. :-)
Was tun, wenn man den Tag, den Monat und das Jahr fein säuberlich in Einzelteilen zerlegt hat? Schauen wir uns mal verschiedene Methoden an, daraus ein gültiges Datum herzustellen.
First() und Last() in T-SQL?
Sehr häufig kann man Fragen in SQL Server Communities beobachten von Leuten, die Ihre Access Datenbanken auf den SQL Server portieren und anschließend versuchen, die proprietäre Access SQL Syntax in T-SQL zu konvertieren. Eine der beliebtesten Fragen in diesem Zusammenhang, ist die Frage, nach dem T-SQL Äquivalent zu First() und Last(). Nun, einfache Antwort: Es gibt kein direktes Äquivalent! Aber es gibt einen Workaround, um das gleiche Ergebnis zu erzielen:
USE NORTHWIND
GO
SELECT
(SELECT
OrderDate
FROM
Orders
WHERE
OrderID =
(SELECT MIN(OrderID)
FROM Orders)) AS First_Order
,
(SELECT
OrderDate
FROM
Orders
WHERE
OrderID =
(SELECT MAX(OrderID)
FROM Orders)) AS Last_Order
First_Order Last_Order
------------------------------------------------------ -----------------------
1996-07-04 00:00:00.000 1998-05-06 00:00:00.000
(1 row(s) affected)
Zu Dokumentationszwecken kann es dann und wann mal nützlich sein, zu wissen, welche Funktion und/oder Stored Procedure welche Parameter verlangt, welche Typ diese Parameter haben usw, usw...
Gelegentlich fragt man sich, ob man wirklich so oft auf die Tastatur hämmern muß, oder ob man sich nicht das eine oder andere Zeichen oder Wort sparen kann. Klingt bekannt? Nun, zumindest mir geht es so. Generell ist das auch so in Ordnung, nur manchmal kann man dabei auch auf die Nase fallen. Wenn dann noch eine merkwürdige Syntaxauslegung ins Spiel kommt, wird es richtig interessant. Beispiel:
SELECT r.royalty , t.title , t.type , t.price FROM roysched r INNER JOIN titles t ON r.title_id = t.title_id ORDER BY r.royalty
Die Ergebnismenge wird hier nicht wiedergegeben. Das obige Beispiel läßt sich folgendermaßen "vereinfachen":
SELECT r.royalty , t.title , t.type , t.price FROM roysched r JOIN titles t ON r.title_id = t.title_id ORDER BY r.royalty
Das INNER Schlüsselwort kann man weglassen, da der INNER JOIN der Standard JOIN Type des SQL Servers ist. So weit, so gut!
Schaut man sich den Ausführungsplan an, sieht man, daß SQL Server NESTED LOOPS verwendet. Nun sind NESTED LOOPS gerade bei umfangreichen Abfragen nicht gerade optimal und darum kommt man vielleicht auf die Idee, den Server einen kleinen Hinweis mit auf den Weg zu geben, wie er den JOIN verarbeiten soll. Also schreibt man:
SELECT r.royalty , t.title , t.type , t.price FROM roysched r MERGE JOIN titles t ON r.title_id = t.title_id ORDER BY r.royalty
Was passiert?
Server: Nachr.-Nr. 170, Schweregrad 15, Status 1, Zeile 8 Zeile 8: Falsche Syntax in der Nähe von 'MERGE'.
Was soll das denn jetzt? Sieht doch syntaktisch einwandfrei aus. Ein Blick in BOL bestätigt dies. Warum also wird das Statement nicht ausgeführt???
Der Grund liegt darin, daß SQL Server bei der Verwendung des MERGE Hinweises (oder jedes anderen JOIN Hints) zwingend auf das INNER Schlüsselwort besteht. Ohne dem geht hier gar nichts. SQL Server ist hier nicht in der Lage, den INNER JOIN als Standard JOIN Typ anzuwenden. Also doch wieder ein paar Mal mehr auf die Tastatur hämmern
SELECT r.royalty , t.title , t.type , t.price FROM roysched r INNER MERGE JOIN titles t ON r.title_id = t.title_id ORDER BY r.royalty
Ah, unsere 86 Zeilen kommen zurück und der Ausführungsplan zeigt den MERGE JOIN an. "By design", also nicht wundern oder nachfragen.
Was soll denn diese Frage? Ein Blick in BOL in die Spezifikationen der maximalen Kapazität sagt einem sofort, daß SQL Server 2000 253 Verweise auf Fremdschlüsseltabellen pro Tabelle haben kann. So, damit wäre diese Frage ja schon beantwortet. Fertig, Neues Thema...Halt
Das Problem hat wahrscheinlich jeder schon einmal gehabt. Man stellt Importanforderungen auf, und die Anwender kümmern sich nicht darum und liefern anstelle von sauber getrennten Strings und Zahlen einen bunten Mischmasch aus beidem.