JSON_ARRAY: Choose Whether NULL Elements Are Included

JSON_ARRAY can omit a SQL NULL input or preserve its position as a JSON null element. I choose that policy before comparing array positions. Removing an element changes the relationship between neighboring values.

Gouache painting: two long wooden boards lie parallel
Separate wooden trays of pears and one empty tray space on a sunlit garden counter.

The default omits missing inputs

The first expression supplies an integer, a missing integer and another integer. Its expected array contains one followed by two. The middle SQL NULL input does not produce an element under the default policy.

JSON_ARRAY uses ABSENT ON NULL by default. That differs from the object constructor’s default property policy. I state the option explicitly when reviewing code that uses both constructors.

The missing input is not converted into an empty string or a numeric zero. It is omitted from the array entirely. That is an element-count change rather than a replacement-value choice.

I return complete array strings in separate columns. Extracting just one nonmissing value would hide the changed array shape. The complete result makes the omission policy visible.

SELECT
    JSON_ARRAY(CAST(1 AS int),CAST(NULL AS int),CAST(2 AS int)) AS DefaultArray,
    JSON_ARRAY(CAST(1 AS int),CAST(NULL AS int),CAST(2 AS int) NULL ON NULL) AS KeptNullArray,
    JSON_ARRAY(CAST(N'1' AS nvarchar(8)),CAST(1 AS int)) AS TypedArray,
    JSON_ARRAY(CAST(N'' AS nvarchar(8)),CAST(NULL AS nvarchar(8)) ABSENT ON NULL) AS EmptyTextArray;
Native SSMS grid with four complete JSON arrays comparing NULL omission, inclusion, value types and empty text
Native SSMS results show complete arrays for NULL omission and inclusion, string versus numeric values, and an empty string. Open the result at full size.

Keep a placeholder when positions have meaning

The second expression requests NULL ON NULL. Its expected array contains one, JSON null and two. The final integer therefore remains in the third position.

A receiving interface might associate array positions with a fixed list of fields. Removing a missing element would shift later values into earlier positions. Retaining the null placeholder can preserve that positional contract.

Another interface might define an array as a collection of available observations. Omitting missing inputs could suit that contract. Neither policy is a universal rule for every payload.

I review the receiver’s meaning before optimizing the number of characters. A shorter array can carry different information. The constructor cannot decide which interpretation the application intended.

Keep the slot or drop it

Empty strings and typed numbers remain distinct

The third expression supplies a Unicode text one and an integer one. Its expected array quotes the first element and leaves the second as a JSON number. Those elements have different JSON types.

Digits inside a SQL string do not automatically become a JSON number. Converting every source expression to text would change that contract. Keep the intended SQL types visible before construction.

The final expression supplies empty text followed by a missing text value under ABSENT ON NULL. Its expected array contains one quoted empty string. Empty text remains a supplied value while the SQL NULL input is omitted.

An application can normalize empty strings to NULL before construction if its contract requires that transformation. Such normalization belongs in a separate source rule. The NULL option does not itself declare empty strings missing.

Validate the complete array contract

The constructor handles JSON escaping by its own conversion rules. These examples use simple literals to keep element presence central. Real interface tests should include the characters their source allows.

The demonstrated syntax returns nvarchar(max) array text. It does not request a native json storage type. Payload construction and payload storage are separate decisions.

The function is available in SQL Server 2022 and later. This query uses only typed scalar expressions. It changes no tables, transaction settings or database context.

I keep a missing value between two present values in the test model. A missing value only at the end would make the positional change easier to overlook. The middle case exposes exactly where the last value moves.

When adapting the sample, compare both element count and element type against the receiver’s expectations. Keep empty text, missing input and numeric input as separate cases. A visually similar payload can still change an interface contract.

Decide what an empty slot means to the receiver, then pick the NULL option on purpose.

An omitted element is not a null placeholder, it is a shift in every later position.

Published by Pinal Dave on SQLAuthority. More of my work at pinaldave.com.


Discover more from SQL Authority with Pinal Dave

Subscribe to get the latest posts sent to your email.

SQL Function, SQL Server, SQL Server 2022
Previous Post
SQL SERVER – Mirroring Configured Without Domain – The server network address TCP://SQLServerName:5023 can not be reached or does not exist
Next Post
Reading a Network Trace of a SQL Server Connection

Related Posts

Leave a Reply

Your email address will not be published. Required fields are marked *

Fill out this field
Fill out this field
Please enter a valid email address.