Aracılığıyla paylaş


OPENJSON (Transact-SQL)

Şunlar için geçerlidir: SQL Server 2016 (13.x) ve sonraki sürümleri Azure SQL VeritabanıAzure SQL Yönetilen ÖrneğiAzure Synapse AnalyticsSQL analiz uç noktası Microsoft Fabric'teki Microsoft FabricSQL veritabanında Microsoft Fabric'te

OPENJSON Tablo değerli işlevi JSON metnini ayrıştırır ve JSON girişinden nesneleri ve özellikleri satır ve sütun olarak döndürür. Başka bir deyişle, OPENJSON bir JSON belgesi üzerinde satır kümesi görünümü sağlar. Satır kümesindeki sütunları ve sütunları doldurmak için kullanılan JSON özellik yollarını açıkça belirtebilirsiniz. OPENJSON Bir satır kümesi döndürdüğünden, OPENJSON bir Transact-SQL deyiminin yan tümcesindeFROM, diğer herhangi bir tablo, görünüm veya tablo değerli işlevi kullanabileceğiniz gibi kullanabilirsiniz.

JSON verilerini SQL Server'a aktarmak veya JSON verilerini doğrudan JSON kullanabilen bir uygulama veya hizmet için ilişkisel biçime dönüştürmek için kullanın OPENJSON .

Note

OPENJSON İşlev yalnızca uyumluluk düzeyi 130 veya üzeri altında kullanılabilir. Veritabanı uyumluluk düzeyiniz 130'dan düşükse, SQL Server işlevi bulup çalıştıramaz OPENJSON . Diğer JSON işlevleri tüm uyumluluk düzeylerinde kullanılabilir.

Uyumluluk düzeyini görünümde sys.databases veya veritabanı özelliklerinde de de kontrol edebilirsiniz. Aşağıdaki komutla veritabanının uyumluluk düzeyini değiştirebilirsiniz:

ALTER DATABASE DatabaseName SET COMPATIBILITY_LEVEL = 130

Transact-SQL söz dizimi kuralları

Syntax

OPENJSON( jsonExpression [ , path ] )  [ <with_clause> ]

<with_clause> ::= WITH ( { colName type [ column_path ] [ AS JSON ] } [ ,...n ] )

Tablo değerli işlevi, OPENJSON ilk bağımsız değişken olarak sağlanan jsonExpression'ı ayrıştırır ve ifadedeki JSON nesnelerinden veri içeren bir veya daha fazla satır döndürür. jsonExpression iç içe alt nesneler içerebilir. Bir alt nesneyi jsonExpression içinden ayrıştırmak istiyorsanız, JSON alt nesnesi için bir yol parametresi belirtebilirsiniz.

openjson

OPENJSON TVF söz diziminin diyagramı.

Varsayılan olarak, OPENJSON tablo değerli işlevi anahtar adını, değeri ve key:value bulunan her çiftin türünü içeren üç sütun döndürür. Alternatif olarak, OPENJSON sağlayarak döndüren sonuç kümesinin şemasını açıkça belirtebilirsiniz.

with_clause

OPENJSON TVF'de WITH yan tümcesinin söz dizimi diyagramı.

with_clause, döndürülecek türlerini OPENJSON içeren bir sütun listesi içerir. Varsayılan olarak, OPENJSONjsonExpression içindeki anahtarları with_clause sütun adlarıyla eşleştirir (bu durumda, anahtarları eşleştirir, büyük/küçük harfe duyarlı olduğunu gösterir). Sütun adı bir anahtar adıyla eşleşmiyorsa jsonExpression içindeki bir anahtara başvuran JSON Yol İfadeleri olan isteğe bağlı bir column_path sağlayabilirsiniz.

Arguments

jsonExpression

JSON metni içeren bir Unicode karakter ifadesidir.

OPENJSON, dizi öğelerini veya JSON ifadesindeki nesnenin özelliklerini yineler ve her öğe veya özellik için bir satır döndürür. Aşağıdaki örnek , jsonExpression olarak sağlanan nesnenin her özelliğini döndürür:

DECLARE @json NVARCHAR(2048) = N'{
   "String_value": "John",
   "DoublePrecisionFloatingPoint_value": 45,
   "DoublePrecisionFloatingPoint_value": 2.3456,
   "BooleanTrue_value": true,
   "BooleanFalse_value": false,
   "Null_value": null,
   "Array_value": ["a","r","r","a","y"],
   "Object_value": {"obj":"ect"}
}';

SELECT * FROM OpenJson(@json);

Results:

key value type
String_value John 1
DoublePrecisionFloatingPoint_value 45 2
DoublePrecisionFloatingPoint_value 2.3456 2
BooleanTrue_value true 3
BooleanFalse_value false 3
Null_value NULL 0
Array_value ["a","r","r","a","y"] 4
Object_value {"obj":"ect"} 5
  • DoublePrecisionFloatingPoint_value IEEE-754'e uygundur.

path

jsonExpression içindeki bir nesneye veya diziye başvuran isteğe bağlı bir JSON yol ifadesidir. OPENJSON belirtilen konumdaki JSON metnini arar ve yalnızca başvuruda bulunan parça ayrıştırılır. Daha fazla bilgi için bkz. JSON Yol İfadeleri.

Bir değişkeni yol değeri olarak sağlayabilirsiniz. (Bu, SQL Server 2016 (13.x) ve önceki sürümlerde desteklenmez.)

Aşağıdaki örnek , yolunu belirterek iç içe bir nesne döndürür:

DECLARE @json NVARCHAR(4000) = N'{  
      "path": {  
            "to":{  
                 "sub-object":["en-GB", "en-UK","de-AT","es-AR","sr-Cyrl"]  
                 }  
              }  
 }';

SELECT [key], value
FROM OPENJSON(@json,'$.path.to."sub-object"')

Results

Key Value
0 en-GB
1 en-UK
2 de-AT
3 es-AR
4 sr-Cyrl

Bir JSON dizisini ayrıştırdığında OPENJSON işlev, JSON metnindeki öğelerin dizinlerini anahtar olarak döndürür.

Yol adımlarını JSON ifadesinin özellikleriyle eşleştirmek için kullanılan karşılaştırma büyük/küçük harfe duyarlıdır ve harmanlamadan habersizdir (bin2 karşılaştırması).

Dizi öğesi kimliği

OPENJSON Azure Synapse Analytics'teki sunucusuz SQL havuzundaki işlev, sonuç olarak döndürülen her satırın kimliğini otomatik olarak oluşturabilir. Kimlik sütunu, sütun tanımından sonra JSON yolundaki ifade $.sql:identity() kullanılarak belirtilir. JSON yol ifadesinde bu değere sahip sütun, işlevin ayrıştırdığı JSON dizisindeki her öğe için benzersiz bir 0 tabanlı sayı oluşturur. Kimlik değeri, dizi öğesinin konumunu/dizinini temsil eder.

DECLARE @array VARCHAR(MAX);
SET @array = '[{"month":"Jan", "temp":10},{"month":"Feb", "temp":12},{"month":"Mar", "temp":15},
               {"month":"Apr", "temp":17},{"month":"May", "temp":23},{"month":"Jun", "temp":27}
              ]';

SELECT * FROM OPENJSON(@array)
        WITH (  month VARCHAR(3),
                temp int,
                month_id tinyint '$.sql:identity()') as months

Results

month temp month_id
Jan 10 0
Feb 12 1
Mar 15 2
Apr 17 3
May 23 4
Jun 27 5

Kimlik yalnızca Synapse Analytics'teki sunucusuz SQL havuzunda kullanılabilir.

with_clause

İşlevin döndüreceği çıkış şemasını OPENJSON açıkça tanımlar. İsteğe bağlı with_clause aşağıdaki öğeleri içerebilir:

colName

Çıkış sütununun adı.

Varsayılan olarak, OPENJSON JSON metnindeki bir özelliği eşleştirmek için sütunun adını kullanır. Örneğin, şemada sütunu name belirtirseniz, OPENJSON bu sütunu JSON metnindeki "name" özelliğiyle doldurmaya çalışır. column_path bağımsız değişkenini kullanarak bu varsayılan eşlemeyi geçersiz kılabilirsiniz.

type

Çıkış sütunu için veri türü.

Note

Seçeneğini de kullanıyorsanız AS JSON , sütun veri türü nvarchar(MAX) olmalıdır.

column_path

Belirtilen sütunda döndürülecek özelliği belirten JSON yoludur. Daha fazla bilgi için bu konu başlığında daha önce yer alan yol parametresinin açıklamasına bakın.

Çıkış sütununun adı özelliğin adıyla eşleşmediğinde varsayılan eşleme kurallarını geçersiz kılmak için column_path kullanın.

Yol adımlarını JSON ifadesinin özellikleriyle eşleştirmek için kullanılan karşılaştırma büyük/küçük harfe duyarlıdır ve harmanlamadan habersizdir (bin2 karşılaştırması).

Yollar hakkında daha fazla bilgi için bkz. JSON Yol İfadeleri.

JSON OLARAK

Başvuruda bulunan özelliğin AS JSON bir iç JSON nesnesi veya dizisi içerdiğini belirtmek için sütun tanımındaki seçeneğini kullanın. Seçeneğini belirtirseniz AS JSON , sütunun türü nvarchar(MAX) olmalıdır.

  • Bir sütun için belirtmezseniz AS JSON , işlev belirtilen yolda belirtilen JSON özelliğinden bir skaler değer (örneğin, int, string, true, false) döndürür. Yol bir nesneyi veya diziyi temsil ediyorsa ve özellik belirtilen yolda bulunamıyorsa işlev modda NULL veya lax modda bir hata strict döndürür. Bu davranış işlevin davranışına JSON_VALUE benzer.

  • Bir sütun için belirtirseniz AS JSON , işlev belirtilen yolda belirtilen JSON özelliğinden bir JSON parçası döndürür. Yol bir skaler değeri temsil ediyorsa ve özellik belirtilen yolda bulunamıyorsa, işlev modda döndürür NULLlax veya modda strict bir hata döndürür. Bu davranış işlevin davranışına JSON_QUERY benzer.

Note

Bir JSON özelliğinden iç içe JSON parçası döndürmek istiyorsanız bayrağını AS JSON sağlamanız gerekir. Bu seçenek olmadan, özellik bulunamazsa, OPENJSON başvurulan JSON nesnesi veya dizisi yerine bir NULL değer döndürür veya modda strict bir çalışma zamanı hatası döndürür.

Örneğin, aşağıdaki sorgu bir dizinin öğelerini döndürür ve biçimlendirir:

DECLARE @json NVARCHAR(MAX) = N'[  
  {  
    "Order": {  
      "Number":"SO43659",  
      "Date":"2011-05-31T00:00:00"  
    },  
    "AccountNumber":"AW29825",  
    "Item": {  
      "Price":2024.9940,  
      "Quantity":1  
    }  
  },  
  {  
    "Order": {  
      "Number":"SO43661",  
      "Date":"2011-06-01T00:00:00"  
    },  
    "AccountNumber":"AW73565",  
    "Item": {  
      "Price":2024.9940,  
      "Quantity":3  
    }  
  }
]'  

SELECT *
FROM OPENJSON ( @json )  
WITH (   
              Number   VARCHAR(200)   '$.Order.Number',  
              Date     DATETIME       '$.Order.Date',  
              Customer VARCHAR(200)   '$.AccountNumber',  
              Quantity INT            '$.Item.Quantity',  
              [Order]  NVARCHAR(MAX)  AS JSON  
 )

Results

Number Date Customer Quantity Order
SO43659 2011-05-31T00:00:00 AW29825 1 {"Number":"SO43659","Date":"2011-05-31T00:00:00"}
SO43661 2011-06-01T00:00:00 AW73565 3 {"Numara":"SO43661","Tarih":"2011-06-01T00:00:00"}

Dönüş değeri

İşlevin OPENJSON döndürdüğü sütunlar seçeneğine WITH bağlıdır.

  • Varsayılan şemayla çağırdığınızda OPENJSON (yan tümcesinde WITH açık bir şema belirtmediğinizde) işlev aşağıdaki sütunları içeren bir tablo döndürür:

    • Key. Belirtilen özelliğin adını veya belirtilen dizideki öğenin dizinini içeren bir nvarchar(4000) değeri. Sütunda key BIN2 harmanlaması vardır.

    • Value. Özelliğin değerini içeren bir nvarchar(MAX) değeri. Sütun, valuejsonExpression'dan harmanlamasını devralır.

    • Type. Değerin türünü içeren bir int değeri. Sütun Type yalnızca varsayılan şemayla kullandığınızda OPENJSON döndürülür. Sütun aşağıdaki type değerlerden birine sahiptir:

      Tür sütununun değeri JSON veri türü
      0 null
      1 string
      2 number
      3 true/false
      4 array
      5 object

    Yalnızca birinci düzey özellikler döndürülür. JSON metni düzgün biçimlendirilmemişse deyimi başarısız olur.

  • çağırdığınızda OPENJSON ve yan tümcesinde açık bir şema belirttiğinizde WITH , işlev yan tümcesinde tanımladığınız şemaya WITH sahip bir tablo döndürür.

Note

Key, Valueve Type sütunları yalnızca varsayılan şemayla kullandığınızda OPENJSON döndürülür ve açık bir şemayla kullanılamaz.

Remarks

veya with_clause ikinci bağımsız değişkeninde OPENJSON kullanılan json_path veya lax anahtar sözcüğüyle strict başlayabilir.

  • Modda lax , OPENJSON belirtilen yoldaki nesne veya değer bulunamazsa hata oluşturmaz. Yol bulunamazsa, OPENJSON boş bir sonuç kümesi veya bir NULL değer döndürür.
  • içinde strict, yol bulunamazsa mod OPENJSON bir hata döndürür.

Bu sayfadaki örneklerden bazıları yol modunu lax veya strictöğesini açıkça belirtir. Yol modu isteğe bağlıdır. Açıkça bir yol modu belirtmezseniz, lax mod varsayılandır. Yol modu ve yol ifadeleri hakkında daha fazla bilgi için bkz. JSON Yol İfadeleri.

with_clause sütun adları, JSON metnindeki anahtarlarla eşleştirilir. sütun adını [Address.Country]belirtirseniz, anahtarıyla Address.Countryeşleştirilir. nesnesinin Countryiçinde iç içe yerleştirilmiş bir anahtara Address başvurmak istiyorsanız, sütun yolunda yolu $.Address.Country belirtmeniz gerekir.

json_path alfasayısal karakterler içeren anahtarlar içerebilir. Anahtarlarda özel karakterler varsa , json_path anahtar adından çift tırnak işaretiyle kaçış. Örneğin, $."my key $1".regularKey."key with . dot" aşağıdaki JSON metnindeki değerle 1 eşleşir:

{
  "my key $1": {
    "regularKey":{
      "key with . dot": 1
    }
  }
}

Examples

Örnek 1 - JSON dizisini geçici tabloya dönüştürme

Aşağıdaki örnek, sayıların JSON dizisi olarak tanımlayıcıların listesini sağlar. Sorgu, JSON dizisini bir tanımlayıcı tablosuna dönüştürür ve belirtilen kimliklere sahip tüm ürünleri filtreler.

DECLARE @pSearchOptions NVARCHAR(4000) = N'[1,2,3,4]'

SELECT *
FROM products
INNER JOIN OPENJSON(@pSearchOptions) AS productTypes
 ON product.productTypeID = productTypes.value

Bu sorgu aşağıdaki örnekle eşdeğerdir. Ancak aşağıdaki örnekte, sayıları parametre olarak geçirmek yerine sorguya eklemeniz gerekir.

SELECT *
FROM products
WHERE product.productTypeID IN (1,2,3,4)

Örnek 2 - İki JSON nesnesinden özellikleri birleştirme

Aşağıdaki örnek, iki JSON nesnesinin tüm özelliklerinin birleşimini seçer. İki nesnenin yinelenen bir ad özelliği vardır. Örnek, yinelenen satırı sonuçlardan dışlamak için anahtar değerini kullanır.

DECLARE @json1 NVARCHAR(MAX),@json2 NVARCHAR(MAX)

SET @json1=N'{"name": "John", "surname":"Doe"}'

SET @json2=N'{"name": "John", "age":45}'

SELECT *
FROM OPENJSON(@json1)
UNION ALL
SELECT *
FROM OPENJSON(@json2)
WHERE [key] NOT IN (SELECT [key] FROM OPENJSON(@json1))

Örnek 3 - CROSS APPLY kullanarak satırları tablo hücrelerinde depolanan JSON verileriyle birleştirme

Aşağıdaki örnekte, SalesOrderHeader tabloda JSON biçiminde bir SalesReason dizi SalesOrderReasons içeren bir metin sütunu vardır. SalesOrderReasons Nesneler Kalite ve Üretici gibi özellikler içerir. Örnek, her satış siparişi satırını ilgili satış nedenleriyle birleştiren bir rapor oluşturur. OPENJSON işleci, JSON satış nedenleri dizisini, nedenleri ayrı bir alt tabloda depolanmış gibi genişletir. CROSS APPLY Ardından işleç, her satış siparişi satırını tablo değerli işlevi tarafından OPENJSON döndürülen satırlara birleştirir.

SELECT SalesOrderID,OrderDate,value AS Reason
FROM Sales.SalesOrderHeader
CROSS APPLY OPENJSON(SalesReasons)

Tip

Tek tek alanlarda depolanan JSON dizilerini genişletmeniz ve bunları üst satırlarıyla birleştirmeniz gerektiğinde, genellikle Transact-SQL CROSS APPLY işlecini kullanırsınız. hakkında CROSS APPLYdaha fazla bilgi için from yan tümcesine bakın.

Aynı sorgu, döndürülecek açıkça tanımlanmış bir satır şemasıyla kullanılarak OPENJSON yeniden yazılabilir:

SELECT SalesOrderID, OrderDate, value AS Reason  
FROM Sales.SalesOrderHeader  
     CROSS APPLY OPENJSON (SalesReasons) WITH (value NVARCHAR(100) '$')

Bu örnekte, $ yol dizideki her öğeye başvurur. Döndürülen değeri açıkça atamak istiyorsanız, bu tür bir sorgu kullanabilirsiniz.

Örnek 4 - İlişkisel satırları ve JSON öğelerini CROSS APPLY ile birleştirme

Aşağıdaki sorgu, ilişkisel satırları ve JSON öğelerini aşağıdaki tabloda gösterilen sonuçlarla birleştirir.

SELECT store.title, location.street, location.lat, location.long  
FROM store  
CROSS APPLY OPENJSON(store.jsonCol, 'lax $.location')   
     WITH (street VARCHAR(500) ,  postcode VARCHAR(500) '$.postcode' ,  
     lon int '$.geo.longitude', lat int '$.geo.latitude')  
     AS location

Results

title street posta kodu lon lat
Tüm Gıda Pazarları 17991 Redmond Yolu WA 98052 47.666124 -122.10155
Sears 148. Ave NE WA 98052 47.63024 -122.141246,17

Örnek 5 - JSON verilerini SQL Server'a aktarma

Aşağıdaki örnek, JSON nesnesinin tamamını bir SQL Server tablosuna yükler.

DECLARE @json NVARCHAR(max)  = N'{  
  "id" : 2,  
  "firstName": "John",  
  "lastName": "Smith",  
  "isAlive": true,  
  "age": 25,  
  "dateOfBirth": "2015-03-25T12:00:00",  
  "spouse": null  
  }';  

  INSERT INTO Person  
  SELECT *   
  FROM OPENJSON(@json)  
  WITH (id INT,  
        firstName NVARCHAR(50), lastName NVARCHAR(50),   
        isAlive BIT, age INT,  
        dateOfBirth DATETIME, spouse NVARCHAR(50))

Örnek 6 - JSON içeriğiyle basit örnek

--simple cross apply example
DECLARE @JSON NVARCHAR(MAX) = N'[
{
"OrderNumber":"SO43659",
"OrderDate":"2011-05-31T00:00:00",
"AccountNumber":"AW29825",
"ItemPrice":2024.9940,
"ItemQuantity":1
},
{
"OrderNumber":"SO43661",
"OrderDate":"2011-06-01T00:00:00",
"AccountNumber":"AW73565",
"ItemPrice":2024.9940,
"ItemQuantity":3
}
]'

SELECT root.[key] AS [Order],TheValues.[key], TheValues.[value]
FROM OPENJSON ( @JSON ) AS root
CROSS APPLY OPENJSON ( root.value) AS TheValues