SQL Server ve JSON
SQL Server 2016'dan beri JSON'u metin (NVARCHAR) olarak saklayıp işleyebilir; SQL Server 2025 ve Azure SQL'de ayrıca yerel json veri tipi vardır. Dört temel araç:
| Araç | Yön | Ne yapar? |
|---|---|---|
FOR JSON PATH | Tablo → JSON | Sorgu sonucunu JSON dizisine çevirir. API'lere veri vermek için. |
OPENJSON | JSON → tablo | JSON dizisini satırlara açar. |
JSON_VALUE / JSON_QUERY | JSON → değer | Tek bir alanı (skaler) veya alt nesneyi okur. |
JSON_MODIFY, ISJSON | Düzenleme, doğrulama | Alanı değiştirir; metnin geçerli JSON olup olmadığını söyler. |
FOR JSON PATH
SELECT TOP 2 customer_id AS id,
first_name AS [musteri.ad],
city AS [musteri.sehir]
FROM customers
ORDER BY customer_id
FOR JSON PATH, ROOT('musteriler');
Takma addaki nokta (musteri.ad) iç içe nesne oluşturur. Varsayılan olarak NULL alanlar JSON'a yazılmaz; yazılsın istiyorsan INCLUDE_NULL_VALUES ekle. Tek satır dönecekse WITHOUT_ARRAY_WRAPPER köşeli parantezleri kaldırır.
İç içe JSON: alt sorgu ile
SELECT c.customer_id,
c.first_name,
(SELECT o.order_id, o.status
FROM orders o
WHERE o.customer_id = c.customer_id
ORDER BY o.order_id
FOR JSON PATH) AS siparisler
FROM customers c
WHERE c.customer_id <= 3;
OPENJSON
DECLARE @sepet NVARCHAR(MAX) = N'[
{"urun_id": 1, "adet": 2},
{"urun_id": 5, "adet": 1}
]';
SELECT j.urun_id, p.name, j.adet, j.adet * p.price AS tutar
FROM OPENJSON(@sepet)
WITH (urun_id INT '$.urun_id', adet INT '$.adet') AS j
JOIN products p ON p.product_id = j.urun_id;
WITH bölümü yazılmazsa OPENJSON üç sütun döndürür: key, value ve type (0: null, 1: metin, 2: sayı, 3: true/false, 4: dizi, 5: nesne).
JSON_VALUE ve JSON_MODIFY
DECLARE @profil NVARCHAR(MAX) = N'{"ad": "Ayşe", "adres": {"sehir": "İzmir"}, "puan": 4}';
SELECT JSON_VALUE(@profil, '$.adres.sehir') AS sehir,
ISJSON(@profil) AS gecerli,
JSON_MODIFY(@profil, '$.puan', 5) AS guncel;
PerformansJSON içindeki bir alana sık filtre uyguluyorsan, o alanı hesaplanmış sütun olarak çıkarıp indeksle:
ALTER TABLE t ADD sehir AS JSON_VALUE(profil, '$.adres.sehir'); CREATE INDEX ix_sehir ON t(sehir);