Unter dem sehr ungewöhnlichen deutschen Wort Programmierbarkeit versteht der MS SQL Server nicht nur die Fähigkeit, überhaupt nützlichen Quelltext in verschiedenen Sprachen in der Datenbank zu speichern oder wie im Fall von TSQL direkt auszuführen, sondern auch die verschiedenen programmierten Objekte. Die Syntax, mit der diese Objekte erstellt werden können, ist neben der sehr umfangreichen Darstellung von Abfragen und Analysen ein zentrales Thema dieses Artikels. Daher dient dieser Abschnitt nur als Appetithappen. Sie sollen also sehen, welche Objekte programmiert und sogar in der Datenbank gespeichert werden können. Die AdventureWorksDatenbank ist bereits mit sehr vielen programmierten Objekten und damit, um im Jargon von MS SQL Server zu bleiben, mit sehr viel Programmierbarkeit ausgestattet. Daher kann es sehr hilfreich sein, diese verschiedenen Objekte aufzurufen und versuchen, auf ihre Einsatzweise hin zu verstehen.
Eine Prozedur stellt ein kleines Programm dar, das in der Datenbank gespeichert ist und das innerhalb der Datenbank über SQL oder außerhalb der Datenbank über eine beliebige Programmiersprache aufgerufen werden kann. Typische Einsatzbereiche von Prozeduren sind vereinfachte Datenbearbeitungsroutinen. In diesem Fall verwendet man in der Anwendung, welche die Datenbank nutzt, nicht den entsprechenden SQLBefehl für die Erfassung, Löschung oder Aktualisierung von Daten, sondern ruft die entsprechende Prozedur auf und übergibt die Daten. Dadurch kann man Validierungen oder beliebige, über die einfache Datenbearbeitung hinausgehende Anweisungen automatisiert ausführen, ohne in der äußeren Anwendung darauf Rücksicht zu nehmen. Ein weiterer Einsatzbereich, der gerade für den MS SQL Server sehr wichtig ist, stellt gespeicherte Abfrage in Form von Prozeduren dar, wobei hier Filterwerte als Parameter übergeben werden können und dadurch der Datenabruf besonders einfach gestaltet wird. Eine solche Prozedur liefert eine Ergebnismenge wie eine Abfrage in SQL zurück.

Rufen Sie vorhandene Prozeduren folgendermaßen auf. Sie können über den folgenden Weg auch neue Prozeduren erstellen, sofern Sie nicht einfach den dazu notwendigen TSQLQuelltext in ein leeres Abfragefenster eingeben. Interessant ist das gleich erwähnte Kontextmenü noch für den Aufruf der Objekte, die von der Prozedur abhängig sind. Sofern solche abhängigen Objekte existieren, kann diese Prozedur nicht einfach gelöscht werden, weil die abhängigen Objekte dadurch ungültig würden.

TODO: Set parameter values here.
SET @StartProductID = 970
SET @CheckDate = (SELECT MAX(StartDate)
FROM Production.BillOfMaterials)
Eine Funktion hat viele Gemeinsamkeiten mit einer Prozedur, was sich insbesondere auch in ihrer Darstellung in der grafischen Oberfläche und in diesem einleitenden Niveau dieses Abschnitts deutlich widerspiegelt. Es handelt sich ebenfalls um ein kleines Programm, das in der Datenbank gespeichert ist und das einen klar begrenzten Verantwortungsbereich im Rahmen der Datenbankbenutzung ausfüllt. Eine Funktion hat ebenfalls die Fähigkeit, Übergabeparameter anzunehmen, kann über das gleiche Kontextmenü verschiedentlich in ihrem Quelltext betrachtet oder ausgeführt werden. Daher soll aus Platzgründen auf eine erneute Darstellung dieses Kontextmenüs verzichtet werden. Man findet im vorherigen Abschnitt ausreichendes Bildmaterial dazu.
Im Gegensatz zu einer Prozedur besitzt eine Funktion allerdings einen so genannten Rückgabewert, sodass man sie mit Methoden oder Funktionen einer gewöhnlichen Programmiersprache vergleichen kann, wenn in diesem Vergleich vorausgesetzt wird, dass die erwähnte Funktion oder Methode ebenfalls einen Rückgabewert liefert. Einige Programmiersprachen unterscheiden ja auch mit Hilfe verschiedener syntaktischer Elemente, ob sich eine Funktionalität eher als Prozedur oder eher als Funktion bezeichnen lassen würde auch dann, wenn die Programmiersprache an sich diese Unterscheidung nicht trifft. Entweder handelt es sich um das Schlüsselwort void, um anzugeben, dass diese Methode keinen Rückgabewert liefert, oder nur um die Verwendung der returnAnweisung für die tatsächliche Rückgabe eines Wertes. Eine Prozedur kann über einen Ausgabeparameter ebenfalls einen Wert an das aufrufende Programm zurückgeben, doch ein Rückgabewert zeichnet sich dadurch aus, dass man den Funktionsaufruf auf die rechte Seite einer Zuweisung bzw. überall dort platzieren kann, wo ein Ausdruck erwartet wird. Eine Prozedur ist kein solcher Ausdruck, da man den Ausgabeparameter zunächst abrufen und dann die Variable mit dem abgerufenen Wert wieder als Ausdruck verwenden könnte.
Wenn eine Funktion sich dadurch auszeichnet, einen Rückgabewert zu haben und als Ausdruck verwendet werden zu können, dann kann man sie so gestalten, dass sie auch direkt in SQL zum Einsatz kommen können. Dies bedeutet, dass sie neben solchen Standardfunktionen wie COUNT, MIN oder SUM in einer SQLAnweisung stehen und Werte für einen Filter oder eine Berechnung liefern können. Sie ermöglichen es damit genauso wie Prozeduren, die Arbeit mit der Datenbank sehr zu vereinfachen, wobei in einem solchen Fall allerdings ganz gewöhnliches SQL dadurch vereinfacht werden kann, weil die selbst erstellte Funktion komplexe Berechnungen, Auswertungen oder Verknüpfungen selbst vornimmt und nur noch die gewünschten, vielleicht sogar parametrisierten Werte zurückliefert.
Wie gerade schon gesehen, ist eine Prozedur in der Lage, ein Abfrageergebnis zurückzuliefern. Diese Fähigkeit besitzt eine Funktion auch, wobei sie allerdings in der FROMKlausel einer Abfrage erscheinen kann, die normalerweise eine Tabellen oder Sichtreferenz erwartet. Über eine solche Funktion ist es möglich, fertige Teilabfragen mit bspw. komplexen, sicherheitsrelevanten Bedingungen sowie Verknüpfungen parametrisiert aufzurufen.
Trigger sind ein weiteres programmierbares SchemaObjekt. Es wird allerdings nur in ganz wenigen Beispielen genutzt und im Rahmen des Artikels nicht weiter vertieft. Im Wesentlichen ist die Erstellung von Triggern zwar mit den TSQLFähigkeiten, die in diesem Artikel vermittelt werden, zu bewerkstelligen. Allerdings handelt es sich um ein hauptsächlich administratives Thema, sodass es besonders gut im AdministrationsArtikel aufgehoben ist.
Während eine Prozedur ausdrücklich über ihren Namen aufgerufen wird, ist ein Trigger entweder einem SchemaObjekt wie einer Tabelle oder einer Sicht zugeordnet oder wartet auf die Ausführung bestimmter DDL (Data Definition Language)Befehle. Die eine TriggerArt wird als DML (Data Manipulation Language)Trigger bezeichnet, da sie auf die SQLAnweisungen INSERT, UPDATE und DELETE wartet, welche den Trigger auslösen und damit seine Anweisungen zur Ausführung bringen. Die andere Art bezeichnet man als DDLTrigger, weil diese Trigger auf Anweisungen wie CREATE, ALTER oder DROP warten, welche zur DDL gehören. Innerhalb eines solchen Triggers lassen sich nahezu beliebige Anweisungen wie auch in einer Prozedur oder Funktion angeben.
Die Besonderheit von Trigger liegt tatsächlich ausschließlich in der automatischen Ausführung auf Basis von anderen Befehlen. Dadurch ist es möglich, bestimmte Sicherheits oder Datenkonsistenzregeln zu programmieren, die mit gewöhnlichem SQL oder sonstigen Datenbankeinstellungen administrativer Art nicht abgebildet werden können. Da innerhalb eines Triggers die gesamte TSQLSyntax zur Verfügung steht, stellen Trigger eine wesentliche Fähigkeit von Datenbanken ab, um sicher zu sein und konsistent zu bleiben.
Mit Hilfe der Anweisung CREATE ASSEMBLY name FROM 'C:\assembly.dll' lassen sich .NETAssemblies in der Datenbank verankern. Dies eröffnet für den MS SQL Server ganz neue Möglichkeiten der Datenbank und Softwareentwicklung. Bislang konnte besonders Oracle neben der datenbankeigenen Programmiersprachen PL/SQL auch noch zusätzlich anbieten, kompilierte Klassen einer so umfangreichen Programmiersprache wie Java für die Entwicklung von Datenbankmodulen zu verwenden. Dies ist nun für den MS SQL Server auch in Form der .NETTechnologie möglich geworden. Assemblies aus den Sprachen C#.NET oder VB.NET sowie natürlich anderen .NETfähigen Sprachen lassen sich nun direkt in die Datenbank laden. Dies eröffnet Möglichkeiten, objektrelational zu arbeiten, indem komplexe Datenstrukturen in Form von Klassen mit mehreren Eigenschaften/Feldern und Methoden abgebildet werden, als auch Prozeduren, Funktionen und Trigger nicht mehr über TSQL, sondern direkt über .NET zu erstellen und sie dann wie gewöhnliche, in TSQL erstellte Module zu verwenden. TSQLVorwissen ist dennoch notwendig, weil die Organisation und Verwaltung der Assemblies über TSQL funktioniert und Abfragen sowie die Erstellung von sonstigen SchemaObjekten weiterhin über TSQL erfolgt.
comelio.com
