JSON verilerini mssql-python ile kullanın

Microsoft SQL 2016 ve daha sonraki sürümler ile Azure SQL, sütunlar üzerinde nvarchar çalışan fonksiyonlar aracılığıyla JSON desteği sağlar. mssql-python sürücüsü, JSON'u normal Python dizeleri olarak gönderir ve alır. Şunları yapabilirsiniz:

  • JSON verilerini nvarchar sütunlarda dize olarak sakla.
  • JSON_VALUE, JSON_QUERY ve OPENJSON kullanarak JSON’u yol ifadeleriyle sorgulayın.
  • İlişkisel veriyi JSON'a dönüştürün .FOR JSON
  • JSON'u ilişkisel formata ile OPENJSONayrıştırın.

Note

Microsoft SQL, JSON verilerini ayrı bir JSON sütun türünde değil, nvarchar sütunlarında depolar. mssql-python sürücüsü, JSON'u normal dizi olarak gönderir ve alır. İstemci tarafında serileştirmek ve seri durumdan çıkarmak için Python'un yerleşik json modülünü kullanın.

JSON verilerini sakla

Python dict'lerini, nvarchar sütunlarına yerleştirmeden önce dizelere serileştirin json.dumps()

JSON dizisi ekleyin

Bir Python sözlüğünü JSON metni olarak bir veritabanı tablosunda depolayın:

import json
import mssql_python

conn = mssql_python.connect(
    "Server=<server>.database.windows.net;"
    "Database=<database>;"
    "Authentication=ActiveDirectoryDefault;"
    "Encrypt=yes"
)
cursor = conn.cursor()

# Create table with JSON column
cursor.execute("""
    CREATE TABLE #JsonProducts (
        ProductID INT IDENTITY PRIMARY KEY,
        Name NVARCHAR(100),
        JsonData NVARCHAR(MAX)
    )
""")

# Python dict to JSON string
product_data = {
    "name": "Widget Pro",
    "specs": {
        "weight": 2.5,
        "dimensions": {"width": 10, "height": 5, "depth": 3}
    },
    "tags": ["electronics", "gadgets", "bestseller"]
}

cursor.execute("""
    INSERT INTO #JsonProducts (Name, JsonData)
    VALUES (%(name)s, %(json)s)
""", {"name": "Widget Pro", "json": json.dumps(product_data)})
conn.commit()

JSON'u insert üzerinde doğrulama

Eklemeden önce JSON sözdizimini doğrulamak için fonksiyonu ISJSON() kullanın:

data = {"name": "Widget", "specs": {"weight": 1.5}}

cursor.execute("""
    CREATE TABLE #JsonValidate (
        ProductID INT IDENTITY, Name NVARCHAR(100), JsonData NVARCHAR(MAX)
    )
""")
cursor.execute("""
    INSERT INTO #JsonValidate (Name, JsonData)
    SELECT %(name)s, %(json)s
    WHERE ISJSON(%(json)s) = 1
""", {"name": "Widget", "json": json.dumps(data)})

if cursor.rowcount == 0:
    raise ValueError("Invalid JSON data")

JSON verilerini sorgulama

Sunucudaki değerleri çıkarmadan önce istemciye geri göndermek için Microsoft SQL JSON yol fonksiyonlarını kullanın.

Skalar değerleri ayıkla

Tek değerleri çıkarmak için kullanılır JSON_VALUE :

# Create table with sample JSON data
cursor.execute("""
    CREATE TABLE #JsonExtract (
        ProductID INT IDENTITY, Name NVARCHAR(100), JsonData NVARCHAR(MAX)
    )
""")
cursor.execute("""
    INSERT INTO #JsonExtract (Name, JsonData) VALUES (
        'Widget Pro',
        '{"name":"Widget Pro","specs":{"weight":2.5,"dimensions":{"width":10,"height":5,"depth":3}},"tags":["electronics","gadgets"]}'
    )
""")

cursor.execute("""
    SELECT 
        Name,
        JSON_VALUE(JsonData, '$.specs.weight') AS Weight,
        JSON_VALUE(JsonData, '$.specs.dimensions.width') AS Width
    FROM #JsonExtract
    WHERE JSON_VALUE(JsonData, '$.name') = %(name)s
""", {"name": "Widget Pro"})

row = cursor.fetchone()
print(f"Weight: {row.Weight}, Width: {row.Width}")

Nesneleri veya dizileri çıkarma

Nesneler ve diziler için JSON_QUERY kullanın.

cursor.execute("""
    CREATE TABLE #JsonQuery (
        ProductID INT IDENTITY, Name NVARCHAR(100), JsonData NVARCHAR(MAX)
    )
""")
cursor.execute("""
    INSERT INTO #JsonQuery (Name, JsonData) VALUES (
        'Widget Pro',
        '{"specs":{"weight":2.5,"color":"blue"},"tags":["electronics","gadgets"]}'
    )
""")

cursor.execute("""
    SELECT 
        Name,
        JSON_QUERY(JsonData, '$.specs') AS Specs,
        JSON_QUERY(JsonData, '$.tags') AS Tags
    FROM #JsonQuery
""")

for row in cursor:
    specs = json.loads(row.Specs) if row.Specs else {}
    tags = json.loads(row.Tags) if row.Tags else []
    print(f"{row.Name}: {specs}, Tags: {tags}")

JSON dizisi sıralara ayrıştır

Bir JSON dizisini şu şekilde satırlara OPENJSONgenişletin:

cursor.execute("""
    CREATE TABLE #JsonArray (
        ProductID INT IDENTITY, Name NVARCHAR(100), JsonData NVARCHAR(MAX)
    )
""")
cursor.execute("""
    INSERT INTO #JsonArray (Name, JsonData) VALUES 
        ('Widget Pro', '{"tags":["electronics","gadgets","bestseller"]}'),
        ('Gadget X', '{"tags":["tools","gadgets"]}')
""")

cursor.execute("""
    SELECT p.Name, t.value AS Tag
    FROM #JsonArray p
    CROSS APPLY OPENJSON(p.JsonData, '$.tags') t
""")

for row in cursor:
    print(f"Product: {row.Name}, Tag: {row.Tag}")

JSON nesnesini sütunlara ayrıştır

JSON nesnelerinden tek tek alanları JSON_VALUE() kullanarak ayıklayın ve sonuçları uygun SQL türlerine dönüştürün.

cursor.execute("""
    CREATE TABLE #JsonCols (
        ProductID INT IDENTITY, Name NVARCHAR(100), JsonData NVARCHAR(MAX)
    )
""")
cursor.execute("""
    INSERT INTO #JsonCols (Name, JsonData) VALUES (
        'Widget Pro',
        '{"name":"Widget Pro","specs":{"weight":2.5,"dimensions":{"width":10,"height":5}}}'
    )
""")

cursor.execute("""
    SELECT 
        p.ProductID,
        j.name AS ProductName,
        j.weight,
        j.width,
        j.height
    FROM #JsonCols p
    CROSS APPLY OPENJSON(p.JsonData)
    WITH (
        name NVARCHAR(100) '$.name',
        weight DECIMAL(5,2) '$.specs.weight',
        width INT '$.specs.dimensions.width',
        height INT '$.specs.dimensions.height'
    ) j
""")

JSON verilerini değiştir

Bir JSON belgesinde belirli bir yolu tüm değeri yeniden yazmadan güncellemek için kullanın JSON_MODIFY .

JSON değerini güncelleme

Tek bir JSON özelliğini şu JSON_MODIFYşekilde değiştirin:

cursor.execute("""
    CREATE TABLE #JsonMod (
        ProductID INT IDENTITY, Name NVARCHAR(100), JsonData NVARCHAR(MAX)
    )
""")
cursor.execute("""
    INSERT INTO #JsonMod (Name, JsonData) VALUES (
        'Widget Pro',
        '{"specs":{"weight":2.5,"dimensions":{"width":10}},"tags":["electronics"]}'
    )
""")

cursor.execute("""
    UPDATE #JsonMod
    SET JsonData = JSON_MODIFY(JsonData, '$.specs.weight', %(weight)s)
    WHERE ProductID = %(id)s
""", {"weight": 3.0, "id": 1})
conn.commit()

JSON özelliğini ekleyin

Mevcut bir JSON nesnesine yeni bir özellik ekleyin:

cursor.execute("""
    CREATE TABLE #JsonAdd (
        ProductID INT IDENTITY, Name NVARCHAR(100), JsonData NVARCHAR(MAX)
    )
""")
cursor.execute("""
    INSERT INTO #JsonAdd (Name, JsonData) VALUES (
        'Widget Pro', '{"specs":{"weight":2.5}}'
    )
""")

cursor.execute("""
    UPDATE #JsonAdd
    SET JsonData = JSON_MODIFY(JsonData, '$.specs.color', %(color)s)
    WHERE ProductID = %(id)s
""", {"color": "blue", "id": 1})

JSON özelliğini kaldırın

Bir JSON nesnesinden bir özelliği şu şekilde NULLayarlayarak silin:

cursor.execute("""
    CREATE TABLE #JsonRem (
        ProductID INT IDENTITY, Name NVARCHAR(100), JsonData NVARCHAR(MAX)
    )
""")
cursor.execute("""
    INSERT INTO #JsonRem (Name, JsonData) VALUES (
        'Widget Pro', '{"specs":{"weight":2.5,"color":"blue"}}'
    )
""")

cursor.execute("""
    UPDATE #JsonRem
    SET JsonData = JSON_MODIFY(JsonData, '$.specs.color', NULL)
    WHERE ProductID = %(id)s
""", {"id": 1})

JSON array'a ekle

JSON_MODIFY içinde, append yönergesini kullanarak bir JSON dizisinin sonuna yeni bir değer ekleyin:

cursor.execute("""
    CREATE TABLE #JsonAppend (
        ProductID INT IDENTITY, Name NVARCHAR(100), JsonData NVARCHAR(MAX)
    )
""")
cursor.execute("""
    INSERT INTO #JsonAppend (Name, JsonData) VALUES (
        'Widget Pro', '{"tags":["electronics","gadgets"]}'
    )
""")

cursor.execute("""
    UPDATE #JsonAppend
    SET JsonData = JSON_MODIFY(
        JsonData, 
        'append $.tags', 
        %(tag)s
    )
    WHERE ProductID = %(id)s
""", {"tag": "new-arrival", "id": 1})

İlişkisel verileri JSON'a dönüştürme

Bu madde, FOR JSON sorgu sonuçlarını sunucu tarafında bir JSON dizisine dönüştürür.

JSON AUTO İÇİN

Sorgu sonuçlarından JSON oluşturun:

cursor.execute("""
    SELECT TOP 5 o.SalesOrderID, p.LastName AS CustomerName, o.TotalDue
    FROM Sales.SalesOrderHeader o
    JOIN Sales.Customer c ON o.CustomerID = c.CustomerID
    JOIN Person.Person p ON c.PersonID = p.BusinessEntityID
    FOR JSON AUTO
""")

# Result is a single string containing JSON
json_result = cursor.fetchval()
orders = json.loads(json_result)
print(json.dumps(orders, indent=2))

FOR JSON PATH

JSON yapısı üzerinde daha fazla kontrol edin:

cursor.execute("""
    SELECT 
        o.SalesOrderID AS 'order.id',
        o.OrderDate AS 'order.date',
        p.LastName AS 'customer.name',
        e.EmailAddress AS 'customer.email'
    FROM Sales.SalesOrderHeader o
    JOIN Sales.Customer c ON o.CustomerID = c.CustomerID
    JOIN Person.Person p ON c.PersonID = p.BusinessEntityID
    JOIN Person.EmailAddress e ON p.BusinessEntityID = e.BusinessEntityID
    WHERE o.SalesOrderID = %(id)s
    FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
""", {"id": 43659})

json_result = cursor.fetchval()
order = json.loads(json_result)
# Structure: {"order": {"id": 43659, "date": "..."}, "customer": {"name": "...", "email": "..."}}

İç İçe JSON

İç içi JSON dizileri ve nesnelerle veri yapılarını sorgulamak, hiyerarşik JSON çıktısı oluşturmak için alt sorgular kullanılır.FOR JSON

cursor.execute("""
    SELECT TOP 3
        c.CustomerID,
        p.LastName AS CustomerName,
        (SELECT TOP 3 o.SalesOrderID, o.TotalDue
         FROM Sales.SalesOrderHeader o
         WHERE o.CustomerID = c.CustomerID
         FOR JSON PATH) AS Orders
    FROM Sales.Customer c
    JOIN Person.Person p ON c.PersonID = p.BusinessEntityID
    WHERE c.PersonID IS NOT NULL
    FOR JSON PATH
""")

json_result = cursor.fetchval()
customers = json.loads(json_result)
# Each customer has nested Orders array

Python entegrasyon kalıpları

Bu desenler, JSON destekli tablolar üzerinde Python soyutlamalarının nasıl oluşturulacağını gösterir.

JSON ile depo modeli

Python nesnelerini JSON sütunlarına seri olarak serileştirip serilikten çıkaran bir veri erişim katmanı uygulayın; böylece veritabanına tip güvenli bir arayüz sağlar.

from dataclasses import dataclass, asdict
from typing import Optional
import json

@dataclass
class ProductSpecs:
    weight: float
    color: str
    dimensions: dict

@dataclass
class Product:
    id: Optional[int]
    name: str
    specs: ProductSpecs

class ProductRepository:
    def __init__(self, connection):
        self.conn = connection
        cursor = self.conn.cursor()
        cursor.execute("""
            IF OBJECT_ID('#JsonRepo') IS NULL
                CREATE TABLE #JsonRepo (
                    ProductID INT IDENTITY PRIMARY KEY,
                    Name NVARCHAR(100),
                    JsonData NVARCHAR(MAX)
                )
        """)
        self.conn.commit()
    
    def save(self, product: Product) -> int:
        cursor = self.conn.cursor()
        specs_json = json.dumps(asdict(product.specs))
        
        if product.id:
            cursor.execute("""
                UPDATE #JsonRepo SET Name = %(name)s, JsonData = %(json)s
                WHERE ProductID = %(id)s
            """, {"name": product.name, "json": specs_json, "id": product.id})
        else:
            cursor.execute("""
                INSERT INTO #JsonRepo (Name, JsonData)
                OUTPUT INSERTED.ProductID
                VALUES (%(name)s, %(json)s)
            """, {"name": product.name, "json": specs_json})
            product.id = cursor.fetchval()
        
        self.conn.commit()
        return product.id
    
    def get(self, product_id: int) -> Optional[Product]:
        cursor = self.conn.cursor()
        cursor.execute("""
            SELECT ProductID, Name, JsonData FROM #JsonRepo WHERE ProductID = %(id)s
        """, {"id": product_id})
        
        row = cursor.fetchone()
        if row is None:
            return None
        
        specs_data = json.loads(row.JsonData)
        return Product(
            id=row.ProductID,
            name=row.Name,
            specs=ProductSpecs(**specs_data)
        )

Veritabanına bağlanın, sonra depoyu oluşturun ve bir ürünü kaydedip almak için kullanın. save() yöntemi, idNone olduğunda INSERT dalını, aksi takdirde ise UPDATE dalını izler:

conn = mssql_python.connect(connection_string)

repo = ProductRepository(conn)

# id is None, so save() inserts a new row and returns the generated ProductID.
product = Product(
    id=None,
    name="Widget Pro",
    specs=ProductSpecs(weight=2.5, color="black", dimensions={"width": 10, "height": 5})
)
product_id = repo.save(product)
print(f"Saved product {product_id}")

# Read the product back into a typed Product object.
loaded = repo.get(product_id)
print(loaded)

conn.close()

Repository, #JsonRepo öğesini sağladığınız bağlantı kapsamında yerel geçici bir tablo olarak oluşturur; bu nedenle save() ve get() aynı bağlantıyı paylaşmalıdır. Bağlantı kapandığında tablo silinir.

Büyük JSON sonuçlarını verimli bir şekilde yönetin

JSON sonuçları büyük olduğunda, onları birden fazla satır boyunca parçalar halinde getirin.

def fetch_json_in_parts(cursor, query: str, params: dict) -> list:
    """Handle JSON results that might span multiple rows."""
    cursor.execute(query, params)
    
    # FOR JSON might split large results across rows
    json_parts = []
    for row in cursor:
        json_parts.append(row[0])
    
    # Combine parts
    json_string = "".join(json_parts)
    return json.loads(json_string) if json_string else []

# Usage
data = fetch_json_in_parts(cursor, "SELECT TOP 100 * FROM Production.Product FOR JSON AUTO", {})

Sorgu sonuçlarını Python'da JSON'a dönüştürün

İlişkisel sorgu sonuçlarını Python'da JSON formatına dönüştürerek her satırı bir sözlüğe dönüştürür ve ardından JSON'a seri yapar.

def query_to_json(cursor, query: str, params: dict = None) -> str:
    """Execute query and return results as JSON string."""
    cursor.execute(query, params or {})
    columns = [col[0] for col in cursor.description]
    
    rows = []
    for row in cursor:
        rows.append(dict(zip(columns, row)))
    
    return json.dumps(rows, default=str, indent=2)

# Usage
json_output = query_to_json(cursor, "SELECT TOP 5 ProductID, Name, ListPrice FROM Production.Product WHERE ProductSubcategoryID = %(cat)s", {"cat": 1})
print(json_output)

JSON verilerini dizine ekleme

Yolu indekslenebilir hale getirmek için JSON yol ifadesi ile desteklenen hesaplanmış bir sütun oluşturun.

İndeksli hesaplanan sütun

Bir JSON değerini çıkaran ve sıkça sorgulanan JSON yollarında verimli filtreleme için ona bir indeks uygulayan hesaplanmış bir sütun tanımlayın. Aşağıdaki örnek kalıcı bir tablo oluşturur, JSON $.specs.weight yolu üzerinde kalıcı bir hesaplanan sütun ekler ve üzerinde bir indeks oluşturur.

cursor.execute("""
    IF OBJECT_ID('dbo.ProductCatalog', 'U') IS NOT NULL
        DROP TABLE dbo.ProductCatalog
""")
cursor.execute("""
    CREATE TABLE dbo.ProductCatalog (
        ProductID   INT IDENTITY PRIMARY KEY,
        Name        NVARCHAR(100),
        JsonData    NVARCHAR(MAX)
    )
""")

# Insert sample rows with JSON data
rows = [
    ("Widget Pro",   '{"specs":{"weight":2.5,"color":"blue"}}'),
    ("Gadget X",     '{"specs":{"weight":0.8,"color":"red"}}'),
    ("Heavy Duty",   '{"specs":{"weight":9.1,"color":"gray"}}'),
]
cursor.executemany(
    "INSERT INTO dbo.ProductCatalog (Name, JsonData) VALUES (%(name)s, %(json)s)",
    [{"name": n, "json": j} for n, j in rows]
)
conn.commit()

# Add a persisted computed column that extracts weight from JSON
cursor.execute("""
    ALTER TABLE dbo.ProductCatalog
    ADD ProductWeight AS CAST(JSON_VALUE(JsonData, '$.specs.weight') AS DECIMAL(5,2)) PERSISTED
""")

# Index the computed column for efficient range queries
cursor.execute("""
    CREATE INDEX IX_ProductCatalog_Weight
    ON dbo.ProductCatalog (ProductWeight)
""")
conn.commit()

İndekslenmiş hesaplanmış sütun kullanarak sorgu

Doğrudan hesaplanmış sütuna göre filtreleyin. Sorgu motoru, her JSON belgesini taramak ve ayrıştırmak yerine indeksi kullanır.

cursor.execute("""
    SELECT Name, ProductWeight
    FROM dbo.ProductCatalog
    WHERE ProductWeight > %(min_weight)s
    ORDER BY ProductWeight
""", {"min_weight": 1.0})

for row in cursor:
    print(f"{row.Name}: {row.ProductWeight} kg")

# Cleanup
cursor.execute("DROP TABLE dbo.ProductCatalog")
conn.commit()

İlişkisel sütunlar ile JSON depolama arasında seçim yapın

Verilerin sabit bir şeması olduğunda, referans bütünlüğü gerektirdiğinde, JOIN'lara katıldığında veya WHERE cümlelerinde sıkça göründüğünde ilişkisel sütunlar kullanın. Veri seyrek, satırlar arasında değişiyorsa veya esnek yapılandırma veya meta veriyi temsil ettiğinde JSON sütunlarını (nvarchar(max)) kullanın.

Sunucu tarafı ile istemci tarafı JSON işlemciliği ne zaman kullanılır

JSON alanlarını filtrelemek, indekslemek veya toplamak gerektiğinde her satırı istemciye getirmeden Microsoft SQL JSON fonksiyonlarını (JSON_VALUE, JSON_QUERY, OPENJSON) kullanın. Bu seçim, sadece satır alt kümesi kriterlerinize uyduğunda veya JSON yollarında hesaplanmış sütun indeksleri istediğinizde doğrudur.

Tüm belgeleri alıp uygulama mantığında işlerken istemci tarafı Python işleme (json.loads()) kullanın. Bu yaklaşım, tam belgeye ihtiyacınız olduğunda ve veritabanındaki JSON alanlarında filtreleme yapmadığınızda iyi işe yarar.

Belge tarzı iş akışları

Uygulamanız tüm belgeleri depolayıp aldığında, Python tarafı serileştirme kullanın ve JSON sütununu opak depolama olarak kabul edin. Belgeleri Python'da tam JSON blob'larını getirip seri durumdan çıkararak işleyin ve sorgulayın:

import json

# Create the settings table
cursor.execute("""
    CREATE TABLE #Settings (
        UserID INT PRIMARY KEY,
        ConfigJson NVARCHAR(MAX)
    )
""")

# Store a configuration document
config = {
    "theme": "dark",
    "notifications": {"email": True, "sms": False},
    "custom_fields": {"department": "Engineering", "cost_center": "CC-100"}
}

cursor.execute(
    "INSERT INTO #Settings (UserID, ConfigJson) VALUES (%(uid)s, %(cfg)s)",
    {"uid": 1, "cfg": json.dumps(config)}
)

# Retrieve and process in Python
cursor.execute("SELECT ConfigJson FROM #Settings WHERE UserID = %(uid)s", {"uid": 1})
row = cursor.fetchone()
config = json.loads(row.ConfigJson)
print(config["notifications"]["email"])  # True

Sunucu tarafı JSON sorguları

JSON alanlarını filtrelemek, indekslemek veya toplamak için her satırı getirmeden Microsoft SQL JSON fonksiyonlarını kullanın. Bu yaklaşım, tüm satırları bellekte filtrelemek için Python'a yüklemekten daha verimlidir:

  • JSON_VALUE skaler değerleri çıkarır ve hesaplanan sütun indekslerini destekleyebilir.
  • JSON_QUERY nesneleri ve dizileri çıkarır.
  • OPENJSON, JSON'u JOIN'ler ve toplama için satırlara ayırır.
  • JSON_MODIFY Tüm belgeyi yeniden yazmadan belirli yolları güncelliyor.
# Filter by a JSON field server-side
cursor.execute("""
    SELECT UserID, ConfigJson
    FROM #Settings
    WHERE JSON_VALUE(ConfigJson, '$.custom_fields.department') = %(dept)s
""", {"dept": "Engineering"})

Sıkça sorgulanan JSON yolları için, bir indeksle hesaplanmış bir sütun oluşturun:

ALTER TABLE Settings
ADD Department AS JSON_VALUE(ConfigJson, '$.custom_fields.department');

CREATE INDEX IX_Settings_Department ON Settings(Department);

En iyi uygulamalar

JSON sütunlarını güvenilir şekilde kullanmak için bu yönergeleri uygulayın.

JSON'u depolamadan önce doğrulayın

Enjeksiyon saldırılarını önlemek için JSON ve tablo/sütun tanımlayıcılarını kaydetmeden önce doğrulayın.

def store_json_safely(cursor, table: str, json_column: str, data: dict):
    """Store JSON with validation."""
    # Validate identifiers to prevent SQL injection
    import re
    if not re.match(r'^[A-Za-z_][A-Za-z0-9_.]*$', table):
        raise ValueError(f"Invalid table name: {table}")
    if not re.match(r'^[A-Za-z_][A-Za-z0-9_]*$', json_column):
        raise ValueError(f"Invalid column name: {json_column}")

    json_str = json.dumps(data)
    
    # Check if valid JSON in Microsoft SQL
    cursor.execute("SELECT ISJSON(%(json)s)", {"json": json_str})
    if cursor.fetchval() != 1:
        raise ValueError("Invalid JSON")
    
    cursor.execute(f"INSERT INTO {table} ({json_column}) VALUES (%(json)s)", {"json": json_str})

JSON'u fazla kullanma

Kullanıcı tercihleri veya özel alanlar gibi esnek veya seyrek veriler için JSON sütunlarını kullanın. İlişkisel sütunları şu amaçlarla kullanın:

  • Sıkça sorgulanan veriler.
  • Referans bütünlüğü gerektiren veriler.
  • WHERE yan tümcelerinde kullanılan sütunlar.

None/NULL'u doğru şekilde yönetin

Eksik veya isteğe bağlı JSON alanlarını, veri olmayan sütunlar için NULL değerleri ekleyerek yönetin.

cursor.execute("""
    CREATE TABLE #JsonOpt (
        ProductID INT IDENTITY, Name NVARCHAR(100), JsonData NVARCHAR(MAX)
    )
""")
cursor.execute("""
    INSERT INTO #JsonOpt (Name, JsonData) VALUES (
        'Widget Pro', '{"required_field":"value"}'
    )
""")

cursor.execute("""
    SELECT 
        Name,
        JSON_VALUE(JsonData, '$.optional_field') AS OptionalValue
    FROM #JsonOpt
""")

for row in cursor:
    # JSON_VALUE returns NULL if path doesn't exist
    value = row.OptionalValue or "default"
    print(f"{row.Name}: {value}")