SQL Server y JSON

Una de las maneras más simples de retornar un set de datos en un objeto JSON es por medio de las sentencias FOR JSON AUTO y FOR JSON PATH. Al utilizar una de estas sentencias el resultado del query no será retornado de la manera tradicional, filas y columnas, sino que retornará un objeto tipo JSON.

Ejemplo:

SELECT TOP (2) [BusinessEntityID]
,[NationalIDNumber]
,[LoginID]
,[OrganizationNode]
FROM [AdventureWorks2016].[HumanResources].[Employee]
FOR JSON AUTO

SELECT TOP (2) [BusinessEntityID]
,[NationalIDNumber]
,[LoginID]
,[OrganizationNode]
FROM [AdventureWorks2016].[HumanResources].[Employee]
FOR JSON PATH



[{"BusinessEntityID":1,"NationalIDNumber":"295847284","LoginID":"adventure-works\\ken0"},{"BusinessEntityID":2,"NationalIDNumber":"245797967","LoginID":"adventure-works\\terri0","OrganizationNode":"\/1\/"}]

Importante recordar que los tipos de datos soportados en los objetos tipo JSON son: null, string, number y boolean. Esto es importante mencionarlo debido a la conversión que se realiza en los diferentes tipos de datos de Sql Server:
  • char, nchar, varchar, nvarchar, date, time, datetime, datetime2, datetimeoffset, money, uniqueidentifier => String.
  • Tinyint, int, smallint, bigint, real, float, decimal, numeric => Numeric
  • Bit => Boolean

Ambas sentencias FOR JSON AUTO y FOR JSON PATH permiten especificar tres opciones adicionales:
  1. Root: Adiciona un miembro en la raíz del objeto.
  2. Include_null_values: Incluye los valores nulos en el set de datos del resultado. Se debe especificar esta opción ya que por defecto el set de datos no muestra los valores nulos.
  3. Without_array_wrapper: Elimina los corchetes ([]) que envuelven al set de datos de retorno. Esta opción es excluyente con la opción Root.

La misma consulta anterior pero con la opción Without_array_wrapper:

SELECT TOP (2) [BusinessEntityID]
,[NationalIDNumber]
,[LoginID]
,[OrganizationNode]
FROM [AdventureWorks2016].[HumanResources].[Employee]
FOR JSON AUTO,
WITHOUT_ARRAY_WRAPPER

{"BusinessEntityID":1,"NationalIDNumber":"295847284","LoginID":"adventure-works\\ken0"},{"BusinessEntityID":2,"NationalIDNumber":"245797967","LoginID":"adventure-works\\terri0","OrganizationNode":"\/1\/"}

Ejemplo utilizando la opción Root:

SELECT TOP (2) [BusinessEntityID]
,[NationalIDNumber]
,[LoginID]
,[OrganizationNode]
FROM [AdventureWorks2016].[HumanResources].[Employee]
FOR JSON AUTO,
ROOT('Empleado')

{"Empleado":[{"BusinessEntityID":1,"NationalIDNumber":"295847284","LoginID":"adventure-works\\ken0"},{"BusinessEntityID":2,"NationalIDNumber":"245797967","LoginID":"adventure-works\\terri0","OrganizationNode":"\/1\/"}]}

Sql Server también ofrece la posibilidad de leer un objeto JSON y presentarlo de manera tracional, filas y columnas, para esto se puede utiliza la función OPENJSON. Esta función recibe dos parámetros: el primero es el objeto JSON y el segundo que es opcional, la ruta o el punto en el cuál comenzar el procesamiento del objeto JSON. Si el segundo parámetro no es especifica todo el objeto JSON será procesado.

El set de datos retornado, tendrá un esquema por defecto, este esquema se puede definir utilizando la sentencia WITH.

Ejemplo sin definir un esquema explícitamente:

DECLARE @json AS NVARCHAR(MAX) = N'
{
"Persona":{
"Identificacion":1,
"Nombre":"Marcos",
"Apellido": "Perez Perez",
"Fecha Nacimiento":"1976-10-03",
"Edad":null}
}';
SELECT *
FROM OPENJSON(@json);



Al no especificar un esquema explícitamente, SQL Server retorna 3 columnas, estas son:
  1. Key: Nombre de la entidad del objeto JSON
  2. Value: El valor del objeto JSON
  3. Type: Un valor de tipo de dato tiny integer. Este tiene 6 posibles valores:
    • 0: Null
    • 1: String
    • 2: Number
    • 3: Boolean (true or false)
    • 4: Array
    • 5: Object

La función OPENJSON convierte en tabla el primer nivel del objeto cómo tal. Para retornar las propiedades anidadas del objeto es necesario especificar el segundo parámetro. Ejemplo:



DECLARE @json AS NVARCHAR(MAX) = N'
{
"Persona":{
"Identificacion":1,
"Nombre":"Marcos",
"Apellido": "Perez Perez",
"Fecha Nacimiento":"1976-10-03",
"Edad":null}
}';
SELECT *
FROM OPENJSON(@json, '$.Persona');

El resultado de la consulta es:



Para cuándo el objeto JSON contiene propiedades anidadas, estas serán retornadas cómo un objeto JSON en el set de resultado. Ejemplo:

DECLARE @json AS NVARCHAR(MAX) = N'
{
"Persona":{
"Identificacion":1,
"Nombre":"Marcos",
"Apellido": "Perez Perez",
"Fecha Nacimiento":"1976-10-03",
"Edad":null,
"Estudios": {
"Titulo":"Bachillerato",
"Anio":"2000"}}
}';
SELECT *
FROM OPENJSON(@json, '$.Persona');



Si se desea presentar de manera tradicional los datos de la entidad anidada, esta se debe especificar en la consulta. Ejemplo:

DECLARE @json AS NVARCHAR(MAX) = N'
{
"Persona":{
"Identificacion":1,
"Nombre":"Marcos",
"Apellido": "Perez Perez",
"Fecha Nacimiento":"1976-10-03",
"Edad":null,
"Estudios": {
"Titulo":"Bachillerato",
"Anio":"2000"}}
}';
SELECT *
FROM OPENJSON(@json, '$.Persona.Estudios');





Y si se quiere mostrar en una misma tabla la combinación de ambas entidades, se puede realizar utilizando la función JSON_VALUE(). Ejemplo:

DECLARE @json AS NVARCHAR(MAX) = N'
{
"Persona":[{
"Identificacion":1,
"Nombre":"Marcos",
"Apellido": "Perez Perez",
"Fecha Nacimiento":"1976-10-03",
"Edad":null,
"Estudios": [{
"Titulo":"Bachillerato",
"Anio":"2000"}]}
]}';
SELECT
JSON_VALUE(P.Value, '$.Identificacion') AS Identificacion,
JSON_VALUE(P.Value, '$.Nombre') AS Nombre,
JSON_VALUE(E.Value, '$.Titulo') AS Titulo
FROM OPENJSON(@json, '$.Persona') AS P
CROSS APPLY OPENJSON(P.value, '$.Estudios') as E



Definiendo un esquema
Para definir un esquema se debe especificar la sentencia WITH. Recordar que si no se especifica esta sentencia, SQL Server define un esquema por defecto.

DECLARE @json AS NVARCHAR(MAX) = N'
{
"Persona":{
"Identificacion":1,
"Nombre":"Marcos",
"Apellido": "Perez Perez",
"Fecha Nacimiento":"1976-10-03",
"Edad":null,
"Estudios": {
"Titulo":"Bachillerato",
"Anio":"2000"}}
}';

SELECT *
FROM OPENJSON(@json)
WITH
(
Identificacion NVARCHAR(50) '$.Persona.Identificacion',
Nombre NVARCHAR(100) '$.Persona.Nombre',
Apellido VARCHAR(100) '$.Persona.Apellido'
);


El resultado de la consulta es:




Comentarios

Entradas populares de este blog

Clases POCO y Clases DTO

INTELLITEST

INTERFACES C#