Startseite > Techblog > Artikel mit dem Tag: sql2008
dri

Alle SQL PASSler aus Sachsen (und die, die es werden möchten) sind zum Jubiläumstreffen 5 Jahre PASS Deutschland der Regionalgruppe Sachsen am Montag, den 25.01.2010 um 18:30 Uhr einladen.

Der PASS Deutschland e.V. wurde am 31.08.2004 gegründet und feierte deshalb im August/September 2009 in allen Regionen das fünfjährige Bestehen. Zu diesem Jubiläum wurden in allen Regionen Treffen der Regionalgruppen mit besonderen Inhalt veranstaltet. Für die Regionalgruppe Sachsen war folgender Vortrag anberaumt:

SQL Server 2008 R2: Neues vom SQL Server; Georg Urban, Microsoft

Self Service Analysis mit Excel In-Memory Online Analytic Processing & Self Service Reporting mit Report Builder 3.0 sind wichtige Themen – aber es gibt noch mehr zu berichten.

Da Georg Urban zu dem ersten Versuch im September kurzfristig krank geworden war, hat er sich für den 25. Januar bereit erklärt, die Session nachzuholen. Es darf gehofft werden, dass er nun auch die neueste CTP vom November hat und die Teilnehmenden so in den Genuss von „Hot News“ kommen!

Die PASS Regionalgruppe Dresden trifft sich an gewohnter Stelle im IT-Trainingshaus am Waldschlösschen. Nähere Informationen zum Termin und eine Anfahrtsbeschreibung findet man auf der Website der Regionalgruppe.

Kommentar Feed Trackback URL
dri

Am 07.09.2009 fand in Dresden die bereits im Vorfeld hier erwähnte Jubiläumsveranstaltung der SQL Pass Group statt. Thema sollte die bevorstehende Release 2 von SQL Server 2008 (Codename Madison) mit ihren Möglichkeiten zu Self Service BI, SQL Server Data Warehouse Scale Out und weiteren Neuheiten sein.

Leider musste Sprecher Georg Urban wegen Krankheit kurzfristig absagen, weshalb die Veranstaltung wohl hätte ins Wasser fallen müssen, wenn PASS-Organisator Ralf Dietrich nicht einen vollwertigen Ersatz “besorgt” hätte: Andreas Wolter informierte über Reporting Services 2008 Berichtsdesign Features.

Berichte auf Basis der Reporting Services 2008 sehen auf den ersten Blick mit RS 2005 fast identisch aus. Unter der Haube aber ergeben sich ganz neue Möglichkeiten. Andreas Wolter stellte neue bzw. verbesserte Features wie Tablix, Charts und Gauges (KPI) mit möglichen Anwendungsszenarien vor. Zum Schluss gab es mit dem aktuellen Report Builder 3.0 CTP doch noch einen Vorab-Blick auf Release 2, dort stachen insbesondere die wirklich gut integrierten Bing Maps sehr positiv hevor.

Am Ende waren sich alle darin einig, dass es ein äußerst informativer Vortrag (dafür ein Dankeschön an Andreas)  zu einem interessanten Thema und deutlich mehr als ein “Lückenbüßer” (und dafür noch eines an Ralf, der dies noch so kurzfristig “heranorganisierte”) war!

Am 20.11.2009 ist das nächste Treffen der PASS Regionalgruppe Sachsen angesetzt, Thema wird SQL Server Sizing mit einer kurzen Einführung und anschließender Diskussion/ Erfahrungsaustausch sein. Der am Montag ausgefallende Vortrag von Georg Urban soll nicht aufgehoben, sondern nur aufgeschoben sein: geplant ist Januar 2010, der konkrete Termin wird dann rechtzeitig auf der Webseite der Regionalgruppe Sachsen bekannt gegeben.

Kommentar Feed Trackback URL
dri

Das nächste SQL Pass Treffen der Regionalgruppe Sachsen findet bereits am 07.09.2009 18:30 wie gewohnt im IT Trainingshaus (mittlerweile in den neuen Räumlichkeiten im 4. Obergeschoss) statt.

Es gibt eine Jubiläumsveranstaltung anlässlich des 5-jährigen Bestehens von PASS Deutschland e.V. und einen Vortrag zum Thema “SQL Server 2008 R2: Self Service BI, SQL Server Data Warehouse Scale Out und weitere Neuheiten”.

Anmelden kann man sich wie immer mit einer kurzen Mail an Ralf Dietrich (rdi@sqlpass.de) oder an Ulrich Walter (uwa@sqlpass.de). Weitere Informationen gibt es auf der Homepage der Regionalgruppe Sachsen.

Kommentar Feed Trackback URL
dri

SQLdays

Communardo ist Partner der SQLdays, die von 29.-30. September 2009 in Rosenheim stattfinden.

Sichern Sie sich am besten noch heute Ihre Teilnahme und sparen Sie so mit Promocode „SQL-Com89“ mindestens 100,- EUR auf den Konferenzpreis (bis 31. August 2009)!

.

Seien auch Sie 2009 bei den SQLdays mit dabei – wenn es heißt „Von Profis für Profis“. So erfahren Sie im Detail, was der innovative Datenbank Server von Microsoft zu bieten hat, welche Trends aktuell sind und von welchen Tipps & Tricks Sie persönlich profitieren.

Und das sind die Highlights der SQLdays 2009:

  • Profitieren Sie von über 20 vollgepackten 70-Minuten-Sessions in drei TracksAdministration, Development und Business Intelligence.
  • Session-Highlights:
    • Gemini und Du: Gerüchte über Microsofts BI-Selbstbedienungsladen
    • Reporting Services 2008 und Analysis Services: Passt das jetzt?
    • Big Data – SQL Server 2008 vs. große Tabellen!
    • Einführung in das FILESTREAM Storage Attribut des SQL Server 2008
    • Schätze für Microsoft BI, gefunden auf Codeplex
  • Hören Sie die SQL-Experten Steffen Krause, Markus Raatz, Georg Urban und viele weitere Sprecher
  • Neu: Spezieller Pre- und Postkonferenz-Workshop
    • Mo., 28. September 2009: One Day Wonder – In einem Tag zum Admin
    • Do., 01. Oktober 2009: Erstellen einer Data Warehouse- /Business Intelligence-Lösung mit dem SQL Server 2008 R2

Aktuelle Infos zu den SQLdays, zu allen Sessions, allen Sprechern, den Workshops und Anmeldung unter www.SQLdays.net.

http://www.ppedv.de/events/sqldays.jpgSQLdays – Die Fachkonferenz für den Microsoft SQL Server!
Melden Sie sich bis 31. August 2009 mit Promocode „SQL-Com89“ an und sichern Sie sich Ihren Sonderpreis!
29.-30. September 2009, Rosenheim (Obb)

Communardo ist Partner der SQLdays, die von 29.-30. September 2009 in Rosenheim stattfinden.

Kommentar Feed Trackback URL
mhy

Genau wie der Datentyp HierarchyId, so sind auch die neuen räumlichen Datentypen geometry und geography CLR-Datentypen, die in jeder Datenbank verfügbar sind – unabhängig davon, ob CLR-Funktionen aktiviert sind.

Der geometry-Datentyp erlaubt die Darstellung von Daten im kartesischen Koordinatensystem und die Durchführung von Berechnungen mit diesen Daten.
Das möchte ich an einem Beispiel verdeutlichen:
image3

In diesem Koordinatensystem befinden sich 2 geometrische Figuren. Ein Strahl mit den Endpunkten (0; 0), (100; 200) und ein Quadrat mit den Eckpunkten (-40; -40), (100; -40), (100; 100), und (-40, 100).

Die Deklaration einer Tabelle zur Speicherung der Daten ist recht trivial. Hierzu erzeugt man einfach eine Tabellenspalte vom Typ Geometry in die man die Daten schreibt.

Ich möchte hier allerdings auf die Möglichkeiten des Datentyps eingehen. Daher werden in den folgenden Beispielen nur Variablen dieses Datentyps erzeugt. Mit Hilfe der statischen Methode STGeomFromText kann aus einem normalsprachlichen Text (dem sogenannten “Well Known Text” = WKT) eine geometrische Instanz erzeugt werden. Im Beispiel ist das:

DECLARE @line geometry;
SET @line =
geometry ::STGeomFromText(‘LINESTRING (0 0, 100 200)’,0)
DECLARE @rectangle geometry;
SET @rectangle = geometry ::STGeomFromText(‘POLYGON ((-40 -40, 100 -40, 100 100, -40 100, -40 -40))’,0)

Wie man sieht, wird hier die Art der geometrischen Figur angegeben  und Punkte, die die Figur näher beschreiben. Das Quadrat ist verallgemeinert ein Polygon, daher ist der WKT hier POLYGON. Zu beachten ist bei Polygonen, dass Start- und Endpunkt übereinstimmen müssen.

Soweit ganz gut. Das Erzeugen und Speichern von Daten an sich ist recht langweilig. Was können die Methoden, die geometry zur Verfügung stellt?

STAsText: STAsText gibt den WKT für ein geometry-Objekt zurück.

STArea: Diese Funktion berechnet die Oberfläche von geometrischen Objekten. Im Fall der Linie ist die Oberfläche 0, aber das ist ehrlich gesagt auch nicht verwunderlich. Im Fall des Quadrats hat die Methode korrekt 140 * 140 = 19600 zurückgegeben.

STIntersection: Mit STIntersection wird die Überschneidung zweier Objekte berechnet. Das Ergebnis der Berechnung im Beispiel ist eine Linie mit den Endpunkten (0; 0) und (50; 100) – und genau das kann man auch sehr schön im Diagramm ablesen.

STLength: Ein letztes Beispiel an dieser Stelle soll STLength sein. Wie der Name schon vermuten lässt, kann damit die Länge bzw. der Umfang der Objekte berechnet werden.

Die Anwendungsfälle dafür können sehr vielfältig sein. Beispielsweise könnte hier die Entfernung zwischen Gebäuden oder Objekten berechnet werden.

Die Berechnung von Entfernungen mit STLength oder Flächen mit STArea auf geraden Flächen ist nur dann sinnvoll, wenn es sich um kurze Distanzen handelt. Möchte man Entfernungen in der realen Welt berechnen, ist der geometry-Datentyp aufgrund der Krümmung der Erde nicht mehr geeignet. Der geography-Datentyp schafft hier Abhilfe:

Wie schon vom Geometry-Datentyp bekannt, kann ein Objekt mittels der statischen Methode STGeomFromText erzeugt werden. Allerdings spielt hier die dort recht unwichtige SRID hier eine wesentliche Rolle. Sie definiert, anhand welchen Standards Berechnungen durchgeführt werden. In der MSDN findet man zum Thema folgendes:

geometry Instances Default to Zero SRID

The default SRID for geometry instances in SQL Server is 0. With geometry spatial data, the specific SRID of the spatial instance is not required to perform calculations; thus, instances can reside in undefined planar space. To indicate undefined planar space in the calculations of geometry data type methods, the SQL Server Database Engine uses SRID 0.

geography Instances Must Use Supported SRID

SQL Server supports SRIDs based on the EPSG standards. A SQL Server-supported SRID for geography instances must be used when performing calculations or using methods with geography spatial data. The SRID must match one of the SRIDs displayed in the sys.spatial_reference_systems catalog view. As mentioned previously, when you perform calculations on your spatial data using the geography data type, your results will depend on which ellipsoid was used in the creation of your data, as each ellipsoid is assigned a specific spatial reference identifier (SRID).

SQL Server uses the default SRID of 4326, which maps to the WGS 84 spatial reference system, when using methods on geography instances. If you use data from a spatial reference system other than WGS 84 (or SRID 4326), you will need to determine the specific SRID for your geography spatial data.

Im Gegensatz zu Geometry muss für die Initialisierung der Geography-Objekte also zwingend eine SRID angegeben werden. Der Standard ist aktuell 4362. Eine Übersicht der gültigen SRIDs erhält man, wenn man die Systemsicht sys.spatial_reference_systems aufruft:
image11

Es gibt noch eine weitere Einschränkung: Geography-Instanzen dürfen die Hemisphäre nicht überschreiten. Diese Einschränkung spielt natürlich erst dann eine Rolle, wenn man nicht mehr nur geographische Punkte speichert, sondern Berechnungen durchführen möchte und z.B. Entfernungen berechnet. Eine in meinen Augen gute Erklärung für diese Einschränkung liefert ein Blogeintrag von Steve Kass zum Thema. Darin wird auch gut beschrieben, weshalb die Punkte von Polygonen immer entgegen des Uhrzeigersinns angegeben werden müssen.

Kommentar Feed Trackback URL
mhy

Möchte man hierarchische Daten ablegen – wie z.B. Organisationsstrukturen in Unternehmen, so war das Standard-Vorgehen dazu bisher, 2 Felder zu verwenden – zunächst die Id des eigentlichen Elements und in einem weiteren Feld die Id des Elternknotens.

Beispiel für Speicherung hierarchischer Daten

Damit lassen sich Abfragen wie: “Wer ist direkter Vorgesetzter des Mitarbeiters X?” oder “Welche Mitarbeiter sind direkt dem Vorgesetzten Y unterstellt?” recht einfach beantworten. Umfangreichere Aussagen wie: “Was sind alle direkten und indirekten Mitarbeiter des Managers X?” oder “Wer ist Ebene-3-Manager des Mitarbeiters Y?” sind damit schon schwieriger zu ermitteln.

Nun kommt der HierarchyId-Datentyp ins Spiel. Mit ihm können solche Zusammenhänge dargestellt und einfach abgefragt werden. Als Besonderheit gilt es zu beachten, dass dieser Datentyp als CLR-Datentyp implementiert ist, der allerdings auch dann zur Verfügung steht, wenn CLR-Integration deaktiviert ist. Daraus resultierend leitet sich auch die Darstellung der Funktionen ab. Dazu aber später mehr. Zunächst möchte ich die oben gezeigte Struktur mit diesem Datentyp aufbauen. Dazu erstelle ich eine neue Tabelle.

Erstellung der Tabelle

Im nächsten Schritt wird diese mit Daten gefüllt.

Daten einfügen

Lässt man sich nun die Daten einmal anzeigen, ergibt sich folgendes Bild:

Gespeicherte Daten

Man erkennt, dass die Daten vorliegen – allerdings ist OrgNode eine hexadezimale Darstellung, die nicht ganz so benutzerfreundlich ist. Dafür gibt es Abhilfe, denn die Methode ToString gibt die kanonische Darstellung des OrgNodes zurück:

GetString-Beispiel

Nun erkennt man die hierarchischen Beziehungen schon besser.

Um die Vorteile auch komplett ausnutzen zu können, sollte man einen Blick auf die Methoden des HierarchyId-Datentyps werfen:

  • GetRoot(): ermittelt den Hauptknoten
  • GetAncestor(n): ermittelt den n-ten Vaterknoten
  • GetDescendant(child1, child2): ermittelt Kindknoten
  • GetLevel(): ermittelt die Hierarchieebene
  • IsDescendantOf(): ermittelt, ob eine hierarchische Beziehung (ist y Kind von x) zwischen 2 Knoten besteht
  • ToString(): Konvertierung in die kanonische Form
  • Parse(): Konvertierung aus der kanonischen Form
  • GetReparentedValue(): nützlich zum Umhängen von Teilstrukturen

Spalten des Datentyps HierarchyId achten nicht selbst auf die Eindeutigkeit. Aus diesem Grund ist es sinnvoll, einen eindeutigen Index auf die Spalte zu legen. Je nach Anwendungsfall unterscheidet man hier Depth-First-Index und Breadth-First-Index. Beim Depth-First-Index wird zuerst in die Tiefe gegangen – also zuerst alle Kindelemente des Knotens 1 indiziert, bevor zu Knoten 2 übergegangen wird. Beim Breadth-First-Index wird Ebene für Ebene indiziert.

Das Anlegen eines Depth-First-Index ist recht trivial – dazu indiziert man einfach eine bestehende HierarchyId-Spalte.

Depth-First-Index

Für die Anlage eines Breadth-First-Indexes benötigt man noch eine zusätzliche Spalte in der Tabelle, in der der Level persistiert und die dann in den Index mit einbezogen wird.

Breadth-First-Index

Kommentar Feed Trackback URL
dri

Große BLOBs (Videos, Word-Dokumente etc.) konnte man in MS SQL Server bisher entweder in der Datenbank (langsam) oder im Filesystem (unsicher, keine Transaktionen) ablegen. FILESTREAM Storage vereint die Vorteile von beiden.

Das Konzept von FILESTREAM integriert das SQL ServerDatenbankmodul in ein NTFS-Dateisystem: BLOB-Daten vom Typ varbinary(max) werden im Dateisystem gespeichert. Dadurch greift nicht die für varbinary(max) definierte Größenbeschränkung auf 2 GB, sondern die Größe der Dateien ist lediglich durch den verfügbaren Speicherplatz auf dem Laufwerk begrenzt. Ansonsten können FILESTREAM-Daten ganz normal mit Transact-SQL-Anweisungen abgefragt, eingefügt, geändert oder gelöscht werden – das alles natürlich wie gehabt incl. Transaktionen und Datenbanksicherheit (mittels Berechtigungen auf Tabellen- oder Spaltenebene – nur das SQL Server Dienstkonto erhält Zugriff auf die Daten im Dateisystem). Desweiteren  können alle Verwaltungsfunktionen genutzt werden, z.B. zum Sichern und Wiederherstellen.

Und wie geht das?

Zuerst muss FILESTREAM Storage aktiviert werden.

Dies kann man entweder bereits bei der Installation von SQL Server 2008 erledigt haben:

Aktivieren von FILESTREAM bei SQL 2008 Installation

… oder man muss es nachträglich im SQL Server Configuration Manager tun:

  • -> Start -> Programme -> SQL Server 2008 -> Konfigurationstools -> SQL Server Configuration Manager
  • zur gewünschten SQL Server Instanz navigieren -> Eigenschaftsdialog öffnen
  • Registerkarte FILESTREAM-> Checkboxen “FILESTREAM für Transact-SQL-Zugriff aktivieren” und “FILESTREAM für E/A-Streamingzugriff auf Datei aktivieren” aktivieren und einen Freigabenamen für den Datei-Speicherort eingeben
  • Wenn Remote Clients auf die FILESTREAM-Daten zugreifen sollen, dann auch die Checkbox “Streamingzugriff von Remoteclients auf FILESTREAM-Daten zulassen” aktivieren

Aktivieren von FILESTREAM im SQL Configuration Manager

  • Im SQL Management Studio muss zusätzlich folgende Abfrage ausgeführt werden, um FILESTREAM für Transact-SQL und für den Win32-Streamingzugriff zu aktivieren:EXEC sp_configure filestream_access_level, 2
    RECONFIGURE

Dann kann eine FILESTREAM-aktivierte Datenbank erstellt werden:

CREATE DATABASE Test
ON
PRIMARY ( NAME = test1,
FILENAME = ‘c:\data\testdat1.mdf’),
FILEGROUP FileStreamGroup1 CONTAINS FILESTREAM( NAME = test3,
FILENAME = ‘c:\data\filestream1′)
LOG ON  ( NAME = testlog1,
FILENAME = ‘c:\data\testlog1.ldf’)
GO

Wenn FILESTREAM nachträglich für eine bereits vorhandene Datenbank aktiviert werden soll, müssen folgende Abfragen ausgeführt werden:

ALTER DATABASE Test ADD
FILEGROUP FileStreamGroup1 CONTAINS FILESTREAM;
GO

ALTER DATABASE Test ADD FILE (
NAME = FSGroup1File,
FILENAME = ‘c:\data\filestream1′)
TO FILEGROUP FileStreamGroup1;
GO

Achtung!
Das Verzeichnis “filestream1″ darf noch nicht vorhanden sein, es wird automatisch angelegt und ist erst einmal leer bis auf die Datei filestream.hdr und den Ordner $FSLOG.

Zu guter Letzt muss eine Tabelle zum Speichern von FILESTREAM-Daten erstellt werden:

CREATE TABLE Test.dbo.Documents (
DocumentID INT IDENTITY PRIMARY KEY,
Document VARBINARY (MAX) FILESTREAM NULL,
DocumentGuid UNIQUEIDENTIFIER NOT NULL ROWGUIDCOL UNIQUE)
FILESTREAM_ON FileStreamGroup1;
GO

Eine Spalte mit FILESTREAM-Daten ist eine varbinary(max)-Spalte mit FILESTREAM-Attribut. Eine ROWGUIDCOL-Spalte ist nur für die Verwendung von FILESTREAM-Daten mit Win32-APIs erforderlich.

Nun können nach Belieben mit Transact SQL Daten eingefügt, abgefragt etc. werden:

INSERT INTO Test.dbo.Documents
VALUES (1, newid (), CAST (‘Das ist ein Test’ as varbinary(max)));
GO

UPDATE Test.dbo.Documents
SET Document = CAST (‘Das ist noch ein Test’ as varbinary(max)))
WHERE DocumentID = 1;
GO

DELETE Test.dbo.Documents WHERE DocumentID = 1;
GO

Anmerkung:
Das Ändern großer Datenmengen ist mit Transact SQL zwar möglich, aber nicht empfehlenswert. Zum Schreiben großer Datenmengen verwendet man besser die Win32-API (aber das ist eine andere Geschichte, die soll ein andermal erzählt werden…)

Zum Abschluss noch einige Überlegungen zum Einsatz von FILESTREAM:

  • FILESTREAM-Speicherung is sinnvoll bei Objekten, die im Schnitt größer als 1 MB sind.
  • FILESTREAM-Speicherung is sinnvoll, wenn schneller Lesezugriff wichtiger ist als schneller Schreibzugriff.
  • FILESTREAM-Daten werden nicht verschlüsselt (auch dann nicht, wenn die transparente Datenverschlüsselung aktiviert ist).

Kommentar Feed Trackback URL
dri

Um gleich mal zu Beginn übertriebene Erwartungen zu dämpfen (und eventuellen Normalform-Fetischisten den Wind aus den Segeln zu nehmen): in 99% aller Fälle sind Sparse Columns NICHT unbedingt erforderlich.

SQL Server 2008 kann jetzt bis zu 16.384 Spalten in einer Tabelle speichern (zum Vergleich: bisher waren maximal 1024 Spalten in einer Tabelle möglich). Nun fragt man sich angesichts solcher Größenordnungen schon: “Wann, um alles in der Welt, benötige ich in einer relationalen Datenbank eine solche Menge an Spalten?”

Hier mal ein Beispiel-Szenario: Wir designen gerade eine Tabelle für Getränke und haben jede Menge an Attributen zu speichern, die nur bei einzelnen Getränke-Kategorien zutreffen: bei alkoholischen Getränken im Allgemeinen den Alkoholgehalt, bei Wein im Speziellen die Farbe, den Süßegrad, die Rebsorte, das Anbaugebiet, … (Weinkennern fällt bestimmt noch einiges ein), bei Saft die Obstsorte und den Fruchtgehalt, bei Milch den Fettgehalt und ob Frisch- oder H-Milch etc. pp.

Nun wird der eingefleischte Datenbank-Designer feststellen, dass man das alles mit Hilfe von separaten Tabellen für jede Getränkekategorie und 1:1-Verknüpfungen doch hübsch sauber in einer relationalen Struktur abbilden kann, ohne eine Unmenge an Spalten zu benötigen. Sicher – kann man. Aber Hand aufs Herz:  manchmal schießt man damit einfach über das Ziel hinaus und erschwert sich unnötig das Leben durch die daraus resultierenden komplexen Abfragen.

Und hier setzen nun Sparse Columns (“spärlich belegte Spalten”) an: In SQL Server 2008 kann man Spalten mit dem Attribut SPARSE versehen, dann verbrauchen sie, wenn sie leer bleiben, auch keinen Platz.

Tabelle mit SPARSE-Spalten

Tabelle mit SPARSE-Spalten

Ob man die so erlaubten 16.384 Spalten tatsächlich einmal erreicht, sei dahingestellt – dieses Konzept lohnt sich aus Sicht der Speicherplatzersparnis auch mit wenigen Spalten, wenn man in einer Tabelle viele Zeilen hat, für die bestimmte Spalten sehr selten belegt sind.

Kommentar Feed Trackback URL
dri

… oder wie bei Microsoft das Basteln abgeschafft wurde
Wer schon einmal vor dem Problem stand, an eine SQL Server Prozedur oder Funktion eine Liste von Werten oder gar eine Tabelle zu übergeben, der wird für dieses Problem bestimmt eine Lösung gefunden haben: Ob man nun die Werte mit einem geeigneten Trennzeichen versehen (ich bevorzuge Pipes ;-)) alle in eine varchar(max)-Variable packt und mittels einer benutzerdefinierten Funktion wieder “auseinanderschnipselt” oder gleich den XML-Datentyp verwendet - es gibt die verschiedensten Bastellösungsansätze, dieser Problematik Herr zu werden.

SQL Server 2008 offeriert mit Table Valued Parameters diese Funktionalität nun gänzlich ohne Bastelei. Die Technik dafür ist denkbar simpel:

Es wird angenommen, dass eine Tabelle Employees mit folgender Struktur existiert:

Nun muss man

  1. einen benutzerdefinierter Datentyp vom Typ Table erzeugen:
  2. eine SQL Server Prozedur oder Funktion erstellen, die den neuen Typ als Input-Parameter verwendet:
  3. eine Variable von diesem Typ erzeugen und mit Daten befüllen:
  4. die Variable an die Prozedur oder Funktion übergeben:

Fertig ;-)

Für alle, die es gerne schnell mal ausprobieren möchten, hier nochmal zum Kopieren:

CREATE TABLE Employees(
EmployeeID int NOT NULL,
LastName nvarchar(50) NOT NULL,
FirstName nvarchar(50) NOT NULL)
go

CREATE TYPE T_Employees AS TABLE (EmployeeID int, LastName nvarchar(50), FirstName nvarchar(50))
go

CREATE PROCEDURE P_InsertEmployees
@employees T_Employees READONLY
AS
INSERT INTO Employees (EmployeeID, LastName, FirstName)
SELECT EmployeeID, LastName, FirstName
FROM @employees
go

DECLARE @emps T_Employees
INSERT INTO @emps (EmployeeID, LastName, FirstName) VALUES (1, ‘Davolio’, ‘Nancy’)
INSERT INTO @emps (EmployeeID, LastName, FirstName) VALUES (2, ‘Fuller’, ‘Andrew’)

EXEC P_InsertEmployees @emps

Hier noch ein paar Dinge, die zu beachten bzw. wissenswert sind:

  • Der INPUT-Parameter für die Prozedur muss READONLY sein.
  • TVP können nicht als Return-Variable für eine Funktion verwendet werden.
  • Microsoft empfielt die Verwendung von TVP bis zur Anzahl von 1000 Datensätzen, für alles, was drüber ist, sollte BULK INSERT verwendet werden.
  • TVP werden als temporäre Tabellen in der tempdb gespeichert.

Und zum Abschluss noch ein kleiner Leckerbissen für ADO.Net Programmierer: TVP werden auch hier vollständig unterstützt, ein Beispiel für den Aufruf der oben erstellte Prozedur in C# könnte so aussehen:

SqlConnection sqlConn…
DataTable dt = new DataTable();
dt.Columns.Add….
dt.Rows.Add…..
SqlCommand cmd = new SqlCommand(“P_InsertEmployees”, sqlConn);
cmd.Parameters.AddWithValue(“@employees”, dt);
cmd.ExecuteNonQuery();

Kommentar Feed Trackback URL
dri

Wer sich schon immer mal darüber geärgert hat, dass mehrere SQL-Anweisungen nötig waren, um in einer Tabelle, abhängig von den Bedingungen in einer anderen Tabelle, Daten einzufügen, zu ändern und/oder zu löschen, der wird über die neue MERGE-Anweisung in SQL Server 2008 hocherfreut sein – … vorausgesetzt, er kann sich für komplexe SQL-Anweisungen begeistern ;-) .

Das absolute Standard-Szenario für die Anwendung von MERGE ist die Aktualisierung von Daten in einem Data Warehouse auf Basis der Daten aus dem Produktivsystem: Im Data Warehouse sollen

  • Adressdaten, die im Produktivsystem vorhanden sind, aber nicht im Data Warehouse, eingefügt werden (INSERT)
  • Adressdaten, die im Produktivsystem und im Data Warehouse vorhanden sind, geändert werden (UPDATE)
  • Adressdaten, die im Data Warehouse, nicht aber im Produktivsystem vorhanden sind, gelöscht werden (DELETE)

Dafür waren bisher 3 Anweisungen der folgenden Art nötig (je eine für INSERT, UPDATE und DELETE):

Mit dem MERGE-Befehl nun ist das alles in einer Anweisung unterzubringen:

Das kommt nicht nur deutlich eleganter daher, sondern ist auch ressourcensparend, da nur eine anstelle mehrerer Lookup-Operationen durchgeführt wird.

Wichtig: Die MERGE-Anweisung muss immer mit einem Semikolon abgeschlossen werden.

Natürlich ist die MERGE-Anweisung noch deutlich flexibler als hier abgebildete Variante, z.B. kann die USING-Klausel auch eine Unterabfrage (dann mit einem Alias) enthalten oder die MATCHED-Klausel beliebig mit weiteren logischen Ausrücken kombiniert werden, des Weiteren sind beliebig viele MATCHED-Klauseln von jeder Art möglich. Ein etwas komplexeres Beispiel könnte z.B. so aussehen:

Ausführliche Syntaxinformationen finden sich unter http://msdn.microsoft.com/de-de/library/bb510625.aspx.

Kommentar Feed Trackback URL

Tag Cloud

Unsere Themen

Kommentare

  • Christian Heindel: Hallo Volti, die Option “Verbindung mit ‘Dokumentbibliothek̵ 7; herstellen”...
  • volti: Hi, ich hab das beschriebene Probleme mit Outlook 2010, dort finde ich die Option Aktionen >...
  • Michael Wittwer: Hallo Guter Beitrag, bin seit kurzem auch mit Balsamiq am arbeiten und die Effizienz ist einfach...
  • Frank: Danke, tut und ist im Vergleich zur Atlassian Lösung abwärtskompatibel bis Confluence 2.10.
  • Ghost@: Danke für die schnelle Antwort Martin! Das ist natürlich ärgerlich, dass der Datentyp nicht unterstützt ist....

Twitter