Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Lesedauer 6 Min.

JSON mit T-SQL auswerten

Die JSON-Unterstützung in SQL Server 2025 erweitert das relationale Modell um die direkte Verarbeitung dokumentbasierter Daten.
© EMGenie

Relationale Datenbanken speichern strukturierte Informationen: Kunden, Aufträge, Artikel. Moderne Anwendungen liefern dagegen häufig Ereignisse, Zustände oder komplette Requests – und diese kommen fast immer als JSON. Web-APIs, Webhooks, Message-Queues oder Event-Streaming-Systeme verwenden ein Dokumentformat, während die Datenbank weiterhin tabellarisch arbeitet. Die zentrale Frage lautet daher nicht mehr, ob JSON gespeichert werden kann, sondern ob es sich direkt in der Datenbank auswerten lässt.

SQL Server unterstützt JSON seit mehreren Versionen. Während ältere Versionen JSON ausschließlich als NVARCHAR behandelten, besitzt SQL Server 2025 zusätzlich einen nativen JSON-Datentyp. Dieser speichert Dokumente strukturiert und erlaubt effizientere Auswertungen, ohne dass das Dokument bei jeder Abfrage vollständig neu interpretiert werden muss. Die bekannten JSON-Funktionen bleiben dabei weiterhin relevant, arbeiten aber nun auf einem typisierten Datenträger.

Damit wird SQL Server zu einem System, das sowohl relationale Daten als auch dokumentbasierte Nachrichten unmittelbar verarbeiten kann.

Dokumente prüfen

Bevor ein Dokument ausgewertet wird, das nicht mit dem JSON-Datentyp vorliegt, sollte sichergestellt sein, dass es syntaktisch korrekt ist. Das erspart spätere Fehler.

 

SELECT ISJSON(@payload);

 

ISJSON() prüft ausschließlich die JSON-Syntax. Die Funktion stellt sicher, dass das Dokument formal gültig ist, trifft jedoch keine Aussage über Inhalt oder Struktur. In der Praxis wird ISJSON() häufig als Constraint verwendet:

 

ALTER TABLE IncomingMessages
ADD CONSTRAINT CK_IncomingMessages_Json
CHECK (ISJSON(Payload) = 1);

 

Die Datenbank übernimmt damit eine erste technische Validierung, bevor eine fachliche Verarbeitung beginnt.

Einzelne Werte lesen

Der wichtigste Zugriff ist das Extrahieren einzelner Attribute. Hierfür kommt die Funktion JSON_VALUE() zum Einsatz, die über einen JSON-Pfad genau beschreibt, wo der gesuchte Wert steht.

 

SELECT JSON_VALUE(@payload, '$.orderId');
SELECT JSON_VALUE(@payload, '$.customer.name');

 

Der zweite Parameter ist dann dieser JSON-Pfad. Das $ steht für das Wurzelelement, danach folgt die Navigation innerhalb des Dokuments. Die Auswertung erfolgt zielgerichtet: SQL Server durchsucht nur den benötigten Abschnitt des Dokuments. JSON_VALUE() liefert grundsätzlich einen skalaren Wert zurück. Intern wird dieser als Zeichenfolge zurückgegeben, weshalb bei numerischen oder zeitlichen Werten eine explizite Typumwandlung sinnvoll ist.

 

SELECT CAST(JSON_VALUE(@payload, '$.orderId') AS INT);

 

Durch die explizite Konvertierung erhält der Optimizer eindeutige Typinformationen, was für stabile Abfragepläne entscheidend ist. Ist nicht sichergestellt, ob der Inhalt sich wirklich zu einem Integer umwandeln lässt, kommen auch Alternativen wie TRY_CONVERT() oder TRY_PARSE() in Betracht. Diese liefern NULL, wenn der Wert nicht das gewünschte Format hat, und das kann dann in einen Fallback-Wert umgewandelt werden. Dieser Ansatz ergibt also nur dann Sinn, wenn es auch einen sinnvollen solchen Wert gibt – andernfalls ist ein harter Fehler vielleicht die bessere Wahl.

Zeitangaben in JSON folgen üblicherweise dem ISO-8601-Format. Dieses Format ist kulturunabhängig und kann zuverlässig interpretiert werden. Dadurch lassen sich Zeitbereiche filtern oder Ereignisse chronologisch auswerten.

 

SELECT CAST(JSON_VALUE(@payload, '$.created') AS DATETIME2);

Filtern nach JSON-Inhalten

JSON-Dokumente werden häufig zunächst vollständig gespeichert, zum Beispiel in Tabellen wie der in dem folgenden Listing:

 

CREATE TABLE dbo.JsonContent
(
    Id INT IDENTITY PRIMARY KEY,
    Payload JSON
);

 

Filternde Abfragen auf diesen Inhalt können nun direkt auf Inhalte des Dokuments zugreifen und können daher wie folgt aussehen:

 

SELECT * FROM dbo.JsonContent
WHERE JSON_VALUE(Payload, '$.customer.name') = 'Meyer';

 

Die Abfrage ist korrekt, jedoch muss der Server ohne weitere Maßnahmen jedes Dokument untersuchen. Bei größeren Tabellen kann dies zu hohem CPU-Aufwand führen, da der relevante Wert innerhalb des Dokuments gesucht werden muss. Für solche größeren Tabellen bietet der SQL Server 2025 deshalb einen speziellen JSON-Index.

JSON-Index

Mit dem nativen JSON-Datentyp in SQL Server 2025 kommt erstmals ein echter JSON-Index hinzu. Bisher bestand die übliche Strategie darin, einzelne Werte über persistierte berechnete Spalten herauszulösen und darauf klassische B-Tree-Indizes anzulegen. Das funktioniert weiterhin gut, hat aber einen strukturellen Nachteil: Man muss vorher wissen, welche Eigenschaften später abgefragt werden. Bei variablen Dokumenten ist genau das in vielen Fällen nicht möglich.

Der JSON-Index setzt eine Ebene tiefer an. SQL Server zerlegt das Dokument intern in Pfade und Werte und legt darauf eine Suchstruktur an. Der Optimizer kann dadurch gezielt auf einzelne Eigenschaften zugreifen, ohne das komplette Dokument pro Zeile erneut zu parsen. Besonders Abfragen mit JSON_VALUE(), Pfadfiltern oder Existenzprüfungen profitieren davon, weil nicht mehr jede Zeile vollständig untersucht werden muss.

 

-- Für alle Elemente
CREATE JSON INDEX jsonIndex
    ON dbo.JsonContent(Payload);
-- Für Elemente im JSON-Pfad(en), die sich nicht überlappen dürfen
CREATE JSON INDEX jsonIndex
    ON dbo.JsonDemo(Payload) FOR ('$.Customer', '$.Employee', '$.Order')
    WITH (FILLFACTOR = 80);

Aggregationen auf JSON

Da Arrays relational interpretiert werden, können sämtliche SQL-Operationen angewendet werden:

 

SELECT SUM(qty * price) AS TotalAmount
FROM OPENJSON(@payload, '$.items')
WITH (
    sku NVARCHAR(20),
    qty INT,
    price DECIMAL(10,2)
);

 

Der SQL Server berechnet dann das Ergebnis direkt aus dem Dokument. Dabei muss nicht mit Schleifen und Ähnlichem gearbeitet werden – dies vereinfacht das Leben in der T-SQL-Welt deutlich.

JSON mit Tabellen verknüpfen

JSON-Inhalte lassen sich mit relationalen Tabellen kombinieren. Dies geschieht mittels der OPENJSON()-Funktion, die eine Tabelle liefert, die zum Beispiel mit einem JOIN zu einer anderen Tabelle verbunden werden kann:

 

SELECT p.ProductName, j.qty
FROM OPENJSON(@payload, '$.items')
WITH (
    sku NVARCHAR(20),
    qty INT
) j
JOIN dbo.Products p ON p.Sku = j.sku;

 

Damit kann zum Beispiel eine eingehende Nachricht unmittelbar gegen Stammdaten geprüft oder erweitert werden.

Teilobjekte lesen

Bisher ging es um einzelne Werte. In der Praxis reicht das selten aus. Sehr häufig muss nicht nur ein Attribut gelesen werden, sondern ein zusammenhängender Teilbereich des Dokuments – etwa ein Adressblock, ein kompletter Kunde oder Metadaten einer Nachricht. Genau dafür existiert JSON_QUERY(). Neben skalaren Werten können auch komplette Teilstrukturen extrahiert werden.

 

SELECT JSON_QUERY(@payload, '$.customer');

 

JSON_QUERY() gibt dabei ein gültiges JSON-Fragment zurück, das weiter verarbeitet werden kann. Dies eignet sich insbesondere für Archivierung oder Weiterverarbeitung, wenn ein Teil des Dokuments unverändert benötigt wird. Sinnvoll ist das insbesondere bei:

  • Weitergabe an andere Systeme
  • Archivierung von Teilinformationen
  • mehrstufigen Analysen
  • Arbeiten mit verschachtelten Arrays

Die Funktion ist damit weniger eine klassische Lesefunktion, sondern eher ein strukturelles Werkzeug. Sie erlaubt es, Dokumente selektiv zu zerlegen, ohne sie in ihre Einzelteile auflösen zu müssen.

Fazit

Die JSON-Unterstützung in SQL Server erweitert das relationale Modell um die direkte Verarbeitung dokumentbasierter Daten. Einzelne Attribute können gezielt mit JSON_VALUE() gelesen und gefiltert werden, während OPENJSON() komplette Arrays in relationale Ergebnismengen überführt. Ein JSON-Index sorgt dabei auch bei größeren Datenmengen für die entsprechende Performance.

Damit wird die Datenbank nicht nur zum Speicherort für eingehende Informationen, sondern zur ersten Instanz ihrer Analyse: Dokumente können geprüft, interpretiert und in bestehende Datenstrukturen eingeordnet werden, ohne vorherige Transformation außerhalb der Datenbank.

Neueste Beiträge

Vom Python-Modell zur .NET-Anwendung - .NET, Python und KI, Teil 4
Am Szenario einer Sentiment-Analyse verdeutlicht ein durchgängiges Anwendungsbeispiel, wie aus einem isolierten Data-Science-Ergebnis eine konkret genutzte Funktion innerhalb einer .NET-Business-Anwendung entsteht.
7 Minuten
Deep Learning in .NET – TensorFlow.NET und TorchSharp - .NET, Python und KI, Teil 3
Mit modernen KI-Frameworks lassen sich Deep-Learning-Modelle direkt in C# entwickeln.
6 Minuten
SQLite als Dokumentenspeicher: Kann das gut gehen? - SQLite für .NET-Entwickler, Teil 5
Die Embedded SQL-Datenbank SQLite kann auch als objektorientierte Datenbank beziehungsweise Dokumentenspeicher genutzt werden – nach Konzepten also, wie sie NoSQL-Datenbanken wie MongoDB einsetzen.
6 Minuten
29. Apr 2026

Das könnte Dich auch interessieren

Volltextsuche mit SQLite: FTS5 und Fuzzy Search - SQLite für .NET-Entwickler, Teil 4
Hochperformante Suche ohne externe Suchmaschine? Wie man mit der in SQLite eingebauten Volltextsuch-Engine FTS5 eine effiziente Suche mit Tippfehlertoleranz implementiert – und in welchen Fällen Elasticsearch doch die bessere Wahl ist.
6 Minuten
22. Apr 2026
libSQL und Turso: SQLite für verteilte Systeme - SQLite für .NET-Entwickler, Teil 3
libSQL und Turso lösen die größte Einschränkung von SQLite: die Bindung an eine einzelne Instanz.
6 Minuten
15. Apr 2026
SQLite als Dokumentenspeicher: Kann das gut gehen? - SQLite für .NET-Entwickler, Teil 5
Die Embedded SQL-Datenbank SQLite kann auch als objektorientierte Datenbank beziehungsweise Dokumentenspeicher genutzt werden – nach Konzepten also, wie sie NoSQL-Datenbanken wie MongoDB einsetzen.
6 Minuten
29. Apr 2026
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige