code it

Martins Tech Blog

SQL Server 2012 und neue Logikfunktionen

Der SQL-Server 2012 bringt unter anderem auch ein paar neue Funktionen mit sich, die im SQL verwendet werden können. Über die Format-Funktion habe ich ja bereits berichtet. Heute soll es um neue Logik-Funktionen gehen.

IIF (Inline IF)

Vor vielen Jahren als ich von Access zu SQL-Server gewechselt bin war es eine ziemliche Umstellung, dass ich die von dort bekannte IIF-Funktion nicht mehr hatte und alle Abfragen angepasst werden mussten. Klar konnte man mit ähnlichen Konstrukten das gleiche erreichen.

SELECT LastName, FirstName, 
CASE WHEN Gender = 1 THEN 'männlich' ELSE 'weiblich' END Gender 
FROM Person

Solche einfachen CASE-WHEN-Konstrukte kann man jetzt (etwas) kürzer schreiben, indem man die IIF-Funktion verwendet.

SELECT LastName, FirstName, 
IIF(Gender = 1, 'männlich', 'weiblich') Gender 
FROM Person

Der Unterschied in der Syntax ist marginal, kann aber dazu führen, dass die Statements einfacher zu lesen sind - besonders dann wenn man die Argumente schachtelt kommt man in meinen Augen bei der Klammern-Schreibweise weniger schnell durcheinander als beim Suchen der Wörter CASE, WHEN, THEN und des jeweils passenden END. Bei der Ausführung wird IIF zu CASE WHEN übersetzt - es handelt sich hier also um eine Art von syntactic sugar. Daraus abgeleitet erlaubt IIF ebenso wie CASE WHEN eine Verschachtelungstiefe von 10.

CHOOSE

Ebenso wie IIF sollte auch CHOOSE allen Access-Jüngern bekannt vorkommen. CHOOSE ermöglicht es, indexbasiert aus Werten auszuwählen. Dazu zunächst ein Beispiel in der bisherigen Syntax:

SELECT LastName, FirstName, 
CASE MaritalStatus 
WHEN 1 THEN 'ledig'
WHEN 2 THEN 'verheiratet'
WHEN 3 THEN 'geschieden'
WHEN 4 THEN 'verwitwet'
WHEN 5 THEN 'getrennt lebend'
WHEN 6 THEN 'verpartnert'
ELSE NULL
END MaritalStatus 
FROM Person

Dieses Konstrukt kann mit CHOOSE anders geschrieben werden:

SELECT LastName, FirstName, 
CHOOSE(MaritalStatus, 'ledig', 'verheiratet', 'geschieden', 'verwitwet', 'getrennt lebend', 'verpartnert') MaritalStatus 
FROM Person

Wichtige Anmerkung für alle C#-Entwickler... der Index ist 1-basiert.

SQL Server 2012 und Contained Databases

Ein sehr spannendes Feature von SQL Server 2012 sind Contained Databases. Dieses Feature ist besonders auf Hosting-Umgebungen ausgerichtet, erlaubt es doch eine bessere Trennung der jeweiligen Datenbank- und damit Anwendungskontexte als es bisher der Fall war.

Was bedeutet das nun de facto? Um bisher einen Nutzer auf einer Datenbank zuzulassen, legte man einen Server-Login an und ließ diesen Nutzer dann auf der jeweiligen Datenbank zu. Das ist ohne Frage auch durchaus sinnvoll, wenn man in Unternehmensgrenzen denkt. Und mal abgesehen von Recovery-Szenarien, bei denen es in der Vergangenheit häufig zu verwaisten Logins und/oder verwaisten Nutzern kam, ist an diesem Ansatz auch nichts auszusetzen. Er ist dann aber hinderlich, wenn man bedenkt, dass man auf einem SQL-Server die Datenbanken völlig voneinander unabhängiger Anwendungen hostet und sicherstellen möchte, dass die dort zugelassenen Nutzer keinesfalls Zugriff auf andere Datenbanken bekommen. Nun unterstelle ich mal, dass Microsoft dieses Feature nicht nur macht, weil es Entwicklern von Webanwendungen und Hostern entgegenkommt, sondern weil Microsoft dieses Feature selbst für Azure auch ganz gut brauchen kann.

Mehr...

SQL Server 2012 und die Format-Funktion

Eigentlich ist Formatierung von Daten in meinen Augen nicht wirklich eine Aktion, die zwingend von der Datenbank durchgeführt werden muss. Aber wie es häufig ist, so gibt es auch hier Anwendungsszenarien in denen dies ein durchaus sinnvoller Weg ist.

In den bisherigen Versionen von SQL Server gestaltete sich dies aber immer etwas schwierig, denkt man nur an verschiedene Datumsformatierungen. Die Funktion CONVERT bot zwar schon begrenzt die Möglichkeit, hier Einfluss zu nehmen, aber wenn man bedenkt, dass für Datumsformate die Auswahlmöglichkeit auf "mit Jahrhundert oder ohne" begrenzt war, so schaute man schon etwas neidisch auf die Möglichkeiten, die beispielsweise die .NET CLR mit string.Format bot.

Mehr...

WIX und das "Unhandled Extension Element"

Zur Erstellung eines Installers für eine Webanwendung verwende ich WIX (Windows Installer XML). Teil dieses Installers ist es auch, das Virtual Directory im IIS anzulegen. Dafür gibt es die WIX IIS Extensions. Um diese verwenden zu können, muss man einfach einen neuen XML-Namespace hinzufügen - so die Information in verschiedenen Blogbeiträgen zum Thema. Gesagt - getan:

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
     xmlns:iis="http://schemas.microsoft.com/wix/IIsExtension">
</Wix>

Und schon funktioniert Intellisense im Visual Studio und man kann die Erweiterungen iis:WebVirtualDir oder iis:WebApplication verwenden. Was diese Blogeinträge nicht verraten: Versucht man nun einen Build des Projekts, so wirft Visual Studio die Fehlermeldung

The Component element contains an unhandled extension element 'iis:WebVirtualDir'.  Please ensure that the extension for elements in the 'http://schemas.microsoft.com/wix/IIsExtension' namespace has been provided.

Problem ist nun nämlich noch, dass zwar der Namespace deklariert ist, aber die Implementierung der Erweiterung nicht gefunden werden kann, weil die dazu passende Assembly nicht referenziert ist. 

Die Lösung des Problems ist dann auch denkbar einfach: Zusätzlich zur Deklaration des Namespaces IIsExtension muss auch die Assembly WixIIsExtension.dll referenziert werden.

ReadOnly(true) vs. Editable(false)

Der DefaultModelBinder in ASP.NET MVC ist die Klasse, die anhand von jeder Menge Magie die im Post enthaltenen Daten in die jeweiligen Properties im Model schreibt. Wenn alle Eigenschaften öffentliche Getter und Setter haben und auch auf der Seite bearbeitbar sein sollen, dann funktioniert diese Magie auch problemlos.

Spannend wird es beispielsweise dann, wenn man Eigenschaften des Models auf der Seite zwar anzeigen, dem Benutzer aber nicht erlauben möchte diese Werte zu ändern. Nichts leichter als das, gibt es doch das ReadOnlyAttribute. Aber schon dann wenn das erste Mal ein Post vom Client zurück an den Server geschickt wird, merkt man, dass ReadOnly keine so gute Idee ist, denn der DefaultModelBinder nimmt dieses Attribut sehr ernst und mit dem ReadOnly-Attribut markierte Eigenschaften werden genauso behandelt, wie auch Eigenschaften ohne öffentlichen Setter behandelt werden würden - sie werden ignoriert.

Ursache ist die interne Methode ShouldUpdateProperty. Diese ermittelt (wie der Name schon sagt), ob es sich um eine Eigenschaft handelt, die beim Binden beachtet wird oder nicht.

Mehr...