sql >> Base de Datos >  >> RDS >> Sqlserver

Cómo solucionarlo:JSON_VALUE devuelve NULL con cadenas largas (SQL Server)

Si está utilizando JSON_VALUE() para devolver valores que consisten en una cadena larga, es posible que devuelva NULL en lugar del valor real.

O bien, es posible que esté recibiendo un error.

La causa

Este problema ocurre porque JSON_VALUE() devuelve un único valor de texto de tipo nvarchar(4000) .

Al usar JSON_VALUE() para devolver cadenas de más de 4000 caracteres, obtendrá un error o un NULL valor, según el modo de ruta que esté utilizando.

Modo Laxo vs Modo Estricto

Si obtiene un error o NULL dependerá de si usas lax o strict modo.

Cuando el valor es mayor a 4000 caracteres:

  • En lax modo, JSON_VALUE() devuelve nulo.
  • En strict modo, JSON_VALUE() devuelve un error.

Ejemplo del Problema

Aquí hay un ejemplo de código que causa el problema.

Hagamos dos ejemplos; uno en lax modo, y el otro en strict modo.

Modo relajado

DECLARE @json nvarchar(max) = N'{ 
    "article" : {
            "id" : 1,
            "text" : "If you have to return scalar values greater than 4000 characters, use the OPENJSON function instead of JSON_VALUE. This text contains more than 4000 characters, which will cause issues for the JSON_VALUE function in SQL Server. This is because the JSON_VALUE function returns a single text value of type nvarchar(4000). If the value is greater than 4000 characters: In lax mode, JSON_VALUE returns null. In strict mode, JSON_VALUE returns an error. If you have to return scalar values greater than 4000 characters, use the OPENJSON function instead of JSON_VALUE. This text contains more than 4000 characters, which will cause issues for the JSON_VALUE function in SQL Server. This is because the JSON_VALUE function returns a single text value of type nvarchar(4000). If the value is greater than 4000 characters: In lax mode, JSON_VALUE returns null. In strict mode, JSON_VALUE returns an error. If you have to return scalar values greater than 4000 characters, use the OPENJSON function instead of JSON_VALUE. This text contains more than 4000 characters, which will cause issues for the JSON_VALUE function in SQL Server. This is because the JSON_VALUE function returns a single text value of type nvarchar(4000). If the value is greater than 4000 characters: In lax mode, JSON_VALUE returns null. In strict mode, JSON_VALUE returns an error. If you have to return scalar values greater than 4000 characters, use the OPENJSON function instead of JSON_VALUE. This text contains more than 4000 characters, which will cause issues for the JSON_VALUE function in SQL Server. This is because the JSON_VALUE function returns a single text value of type nvarchar(4000). If the value is greater than 4000 characters: In lax mode, JSON_VALUE returns null. In strict mode, JSON_VALUE returns an error. If you have to return scalar values greater than 4000 characters, use the OPENJSON function instead of JSON_VALUE. This text contains more than 4000 characters, which will cause issues for the JSON_VALUE function in SQL Server. This is because the JSON_VALUE function returns a single text value of type nvarchar(4000). If the value is greater than 4000 characters: In lax mode, JSON_VALUE returns null. In strict mode, JSON_VALUE returns an error. If you have to return scalar values greater than 4000 characters, use the OPENJSON function instead of JSON_VALUE. This text contains more than 4000 characters, which will cause issues for the JSON_VALUE function in SQL Server. This is because the JSON_VALUE function returns a single text value of type nvarchar(4000). If the value is greater than 4000 characters: In lax mode, JSON_VALUE returns null. In strict mode, JSON_VALUE returns an error. If you have to return scalar values greater than 4000 characters, use the OPENJSON function instead of JSON_VALUE. This text contains more than 4000 characters, which will cause issues for the JSON_VALUE function in SQL Server. This is because the JSON_VALUE function returns a single text value of type nvarchar(4000). If the value is greater than 4000 characters: In lax mode, JSON_VALUE returns null. In strict mode, JSON_VALUE returns an error. If you have to return scalar values greater than 4000 characters, use the OPENJSON function instead of JSON_VALUE. This text contains more than 4000 characters, which will cause issues for the JSON_VALUE function in SQL Server. This is because the JSON_VALUE function returns a single text value of type nvarchar(4000). If the value is greater than 4000 characters: In lax mode, JSON_VALUE returns null. In strict mode, JSON_VALUE returns an error. If you have to return scalar values greater than 4000 characters, use the OPENJSON function instead of JSON_VALUE. This text contains more than 4000 characters, which will cause issues for the JSON_VALUE function in SQL Server. This is because the JSON_VALUE function returns a single text value of type nvarchar(4000). If the value is greater than 4000 characters: In lax mode, JSON_VALUE returns null. In strict mode, JSON_VALUE returns an error."
    }
}';
SELECT JSON_VALUE(@json, 'lax $.article.text');

Resultado:

+--------------------+
| (No column name)   |
|--------------------|
| NULL               |
+--------------------+

Como se mencionó, en lax modo devuelve NULL .

Modo estricto

DECLARE @json nvarchar(max) = N'{ 
    "article" : {
            "id" : 1,
            "text" : "If you have to return scalar values greater than 4000 characters, use the OPENJSON function instead of JSON_VALUE. This text contains more than 4000 characters, which will cause issues for the JSON_VALUE function in SQL Server. This is because the JSON_VALUE function returns a single text value of type nvarchar(4000). If the value is greater than 4000 characters: In lax mode, JSON_VALUE returns null. In strict mode, JSON_VALUE returns an error. If you have to return scalar values greater than 4000 characters, use the OPENJSON function instead of JSON_VALUE. This text contains more than 4000 characters, which will cause issues for the JSON_VALUE function in SQL Server. This is because the JSON_VALUE function returns a single text value of type nvarchar(4000). If the value is greater than 4000 characters: In lax mode, JSON_VALUE returns null. In strict mode, JSON_VALUE returns an error. If you have to return scalar values greater than 4000 characters, use the OPENJSON function instead of JSON_VALUE. This text contains more than 4000 characters, which will cause issues for the JSON_VALUE function in SQL Server. This is because the JSON_VALUE function returns a single text value of type nvarchar(4000). If the value is greater than 4000 characters: In lax mode, JSON_VALUE returns null. In strict mode, JSON_VALUE returns an error. If you have to return scalar values greater than 4000 characters, use the OPENJSON function instead of JSON_VALUE. This text contains more than 4000 characters, which will cause issues for the JSON_VALUE function in SQL Server. This is because the JSON_VALUE function returns a single text value of type nvarchar(4000). If the value is greater than 4000 characters: In lax mode, JSON_VALUE returns null. In strict mode, JSON_VALUE returns an error. If you have to return scalar values greater than 4000 characters, use the OPENJSON function instead of JSON_VALUE. This text contains more than 4000 characters, which will cause issues for the JSON_VALUE function in SQL Server. This is because the JSON_VALUE function returns a single text value of type nvarchar(4000). If the value is greater than 4000 characters: In lax mode, JSON_VALUE returns null. In strict mode, JSON_VALUE returns an error. If you have to return scalar values greater than 4000 characters, use the OPENJSON function instead of JSON_VALUE. This text contains more than 4000 characters, which will cause issues for the JSON_VALUE function in SQL Server. This is because the JSON_VALUE function returns a single text value of type nvarchar(4000). If the value is greater than 4000 characters: In lax mode, JSON_VALUE returns null. In strict mode, JSON_VALUE returns an error. If you have to return scalar values greater than 4000 characters, use the OPENJSON function instead of JSON_VALUE. This text contains more than 4000 characters, which will cause issues for the JSON_VALUE function in SQL Server. This is because the JSON_VALUE function returns a single text value of type nvarchar(4000). If the value is greater than 4000 characters: In lax mode, JSON_VALUE returns null. In strict mode, JSON_VALUE returns an error. If you have to return scalar values greater than 4000 characters, use the OPENJSON function instead of JSON_VALUE. This text contains more than 4000 characters, which will cause issues for the JSON_VALUE function in SQL Server. This is because the JSON_VALUE function returns a single text value of type nvarchar(4000). If the value is greater than 4000 characters: In lax mode, JSON_VALUE returns null. In strict mode, JSON_VALUE returns an error. If you have to return scalar values greater than 4000 characters, use the OPENJSON function instead of JSON_VALUE. This text contains more than 4000 characters, which will cause issues for the JSON_VALUE function in SQL Server. This is because the JSON_VALUE function returns a single text value of type nvarchar(4000). If the value is greater than 4000 characters: In lax mode, JSON_VALUE returns null. In strict mode, JSON_VALUE returns an error."
    }
}';
SELECT JSON_VALUE(@json, 'strict $.article.text');

Resultado:

Msg 13625, Level 16, State 1, Line 7
String value in the specified JSON path would be truncated.

Como era de esperar, obtenemos un error. Afortunadamente, el error proporciona una pista de lo que salió mal, ya que menciona que el valor de la cadena se truncaría.

Solución

Afortunadamente, el OPENJSON() la función no tiene la misma limitación de 4000 caracteres que JSON_VALUE() tiene en su valor de retorno.

OPENJSON() devuelve valores JSON como nvarchar(max) .

Por lo tanto, podemos usar el siguiente código para resolver el problema.

DECLARE @json nvarchar(max) = N'{ 
    "article" : {
            "id" : 1,
            "text" : "If you have to return scalar values greater than 4000 characters, use the OPENJSON function instead of JSON_VALUE. This text contains more than 4000 characters, which will cause issues for the JSON_VALUE function in SQL Server. This is because the JSON_VALUE function returns a single text value of type nvarchar(4000). If the value is greater than 4000 characters: In lax mode, JSON_VALUE returns null. In strict mode, JSON_VALUE returns an error. If you have to return scalar values greater than 4000 characters, use the OPENJSON function instead of JSON_VALUE. This text contains more than 4000 characters, which will cause issues for the JSON_VALUE function in SQL Server. This is because the JSON_VALUE function returns a single text value of type nvarchar(4000). If the value is greater than 4000 characters: In lax mode, JSON_VALUE returns null. In strict mode, JSON_VALUE returns an error. If you have to return scalar values greater than 4000 characters, use the OPENJSON function instead of JSON_VALUE. This text contains more than 4000 characters, which will cause issues for the JSON_VALUE function in SQL Server. This is because the JSON_VALUE function returns a single text value of type nvarchar(4000). If the value is greater than 4000 characters: In lax mode, JSON_VALUE returns null. In strict mode, JSON_VALUE returns an error. If you have to return scalar values greater than 4000 characters, use the OPENJSON function instead of JSON_VALUE. This text contains more than 4000 characters, which will cause issues for the JSON_VALUE function in SQL Server. This is because the JSON_VALUE function returns a single text value of type nvarchar(4000). If the value is greater than 4000 characters: In lax mode, JSON_VALUE returns null. In strict mode, JSON_VALUE returns an error. If you have to return scalar values greater than 4000 characters, use the OPENJSON function instead of JSON_VALUE. This text contains more than 4000 characters, which will cause issues for the JSON_VALUE function in SQL Server. This is because the JSON_VALUE function returns a single text value of type nvarchar(4000). If the value is greater than 4000 characters: In lax mode, JSON_VALUE returns null. In strict mode, JSON_VALUE returns an error. If you have to return scalar values greater than 4000 characters, use the OPENJSON function instead of JSON_VALUE. This text contains more than 4000 characters, which will cause issues for the JSON_VALUE function in SQL Server. This is because the JSON_VALUE function returns a single text value of type nvarchar(4000). If the value is greater than 4000 characters: In lax mode, JSON_VALUE returns null. In strict mode, JSON_VALUE returns an error. If you have to return scalar values greater than 4000 characters, use the OPENJSON function instead of JSON_VALUE. This text contains more than 4000 characters, which will cause issues for the JSON_VALUE function in SQL Server. This is because the JSON_VALUE function returns a single text value of type nvarchar(4000). If the value is greater than 4000 characters: In lax mode, JSON_VALUE returns null. In strict mode, JSON_VALUE returns an error. If you have to return scalar values greater than 4000 characters, use the OPENJSON function instead of JSON_VALUE. This text contains more than 4000 characters, which will cause issues for the JSON_VALUE function in SQL Server. This is because the JSON_VALUE function returns a single text value of type nvarchar(4000). If the value is greater than 4000 characters: In lax mode, JSON_VALUE returns null. In strict mode, JSON_VALUE returns an error. If you have to return scalar values greater than 4000 characters, use the OPENJSON function instead of JSON_VALUE. This text contains more than 4000 characters, which will cause issues for the JSON_VALUE function in SQL Server. This is because the JSON_VALUE function returns a single text value of type nvarchar(4000). If the value is greater than 4000 characters: In lax mode, JSON_VALUE returns null. In strict mode, JSON_VALUE returns an error."
    }
}';
SELECT text FROM OPENJSON(@json, '$.article') 
WITH (text nvarchar(max) '$.text');

Resultado:

If you have to return scalar values greater than 4000 characters, use the OPENJSON function instead of JSON_VALUE. This text contains more than 4000 characters, which will cause issues for the JSON_VALUE function in SQL Server. This is because the JSON_VALUE function returns a single text value of type nvarchar(4000). If the value is greater than 4000 characters: In lax mode, JSON_VALUE returns null. In strict mode, JSON_VALUE returns an error. If you have to return scalar values greater than 4000 characters, use the OPENJSON function instead of JSON_VALUE. This text contains more than 4000 characters, which will cause issues for the JSON_VALUE function in SQL Server. This is because the JSON_VALUE function returns a single text value of type nvarchar(4000). If the value is greater than 4000 characters: In lax mode, JSON_VALUE returns null. In strict mode, JSON_VALUE returns an error. If you have to return scalar values greater than 4000 characters, use the OPENJSON function instead of JSON_VALUE. This text contains more than 4000 characters, which will cause issues for the JSON_VALUE function in SQL Server. This is because the JSON_VALUE function returns a single text value of type nvarchar(4000). If the value is greater than 4000 characters: In lax mode, JSON_VALUE returns null. In strict mode, JSON_VALUE returns an error. If you have to return scalar values greater than 4000 characters, use the OPENJSON function instead of JSON_VALUE. This text contains more than 4000 characters, which will cause issues for the JSON_VALUE function in SQL Server. This is because the JSON_VALUE function returns a single text value of type nvarchar(4000). If the value is greater than 4000 characters: In lax mode, JSON_VALUE returns null. In strict mode, JSON_VALUE returns an error. If you have to return scalar values greater than 4000 characters, use the OPENJSON function instead of JSON_VALUE. This text contains more than 4000 characters, which will cause issues for the JSON_VALUE function in SQL Server. This is because the JSON_VALUE function returns a single text value of type nvarchar(4000). If the value is greater than 4000 characters: In lax mode, JSON_VALUE returns null. In strict mode, JSON_VALUE returns an error. If you have to return scalar values greater than 4000 characters, use the OPENJSON function instead of JSON_VALUE. This text contains more than 4000 characters, which will cause issues for the JSON_VALUE function in SQL Server. This is because the JSON_VALUE function returns a single text value of type nvarchar(4000). If the value is greater than 4000 characters: In lax mode, JSON_VALUE returns null. In strict mode, JSON_VALUE returns an error. If you have to return scalar values greater than 4000 characters, use the OPENJSON function instead of JSON_VALUE. This text contains more than 4000 characters, which will cause issues for the JSON_VALUE function in SQL Server. This is because the JSON_VALUE function returns a single text value of type nvarchar(4000). If the value is greater than 4000 characters: In lax mode, JSON_VALUE returns null. In strict mode, JSON_VALUE returns an error. If you have to return scalar values greater than 4000 characters, use the OPENJSON function instead of JSON_VALUE. This text contains more than 4000 characters, which will cause issues for the JSON_VALUE function in SQL Server. This is because the JSON_VALUE function returns a single text value of type nvarchar(4000). If the value is greater than 4000 characters: In lax mode, JSON_VALUE returns null. In strict mode, JSON_VALUE returns an error. If you have to return scalar values greater than 4000 characters, use the OPENJSON function instead of JSON_VALUE. This text contains more than 4000 characters, which will cause issues for the JSON_VALUE function in SQL Server. This is because the JSON_VALUE function returns a single text value of type nvarchar(4000). If the value is greater than 4000 characters: In lax mode, JSON_VALUE returns null. In strict mode, JSON_VALUE returns an error.