I received a valid JSON string from client side, it contains an array of integer values:
declare @JSON nvarchar(max) = N'{"Comments": "test", "Markets": [3, 151]}'
How to select the market IDs correctly?
If I use a query like this: select * from openjson(@JSON) j
, it returns
The type of Markets is 4, which means an object,
but the query below returns null value:select j.Markets from openjson(@JSON) with(Markets nvarchar(max)) j
My goal is to update Market
table based on these IDs, eg:update Market set Active = 1 where MarketID in (3, 151)
Is there a way to do this?
Any built-in function compatible with SQL server 2016 can be used.
Note:
Thanks to @johnlbevanSELECT VALUE FROM OPENJSON(@JSON, '$.Markets')
works perfectly for this problem.
Just for the completeness, here is how I created the JSON integer array ("Markets": [3, 151]
) from SQL server.
Since there is no array_agg
function out of the box in 2016, I did this:
SELECT (
JSON_QUERY('[' + STUFF(( SELECT ',' + CAST(MarketID AS VARCHAR)
FROM Market
FOR XML PATH('')),1,1,'') + ']' ) AS Markets)
To expand the Markets array alongside other columns you can do this:
SELECT Comments, Market
FROM OPENJSON('{"Comments": "test", "Markets": [3, 151]}')
WITH (Comments nvarchar(32), Markets NVARCHAR(MAX) AS JSON) AS a
CROSS APPLY OPENJSON (a.Markets) WITH (Market INT '$') AS b
Comments
column with type nvarchar(32)
Markets
column with type nvarchar(max)
, then use as json
to say that the contents is json (see https://learn.microsoft.com/en-us/sql/t-sql/functions/openjson-transact-sql#arguments for a more detailed description - search the page for as json
; the key paragraph starts at the 4th occurrence)cross apply
to apply the OPENJSON function to the Markets column so we can fetch values from that property.WITH
statement to map the name Market
to the returned value, and assign it a data type of INT
.However, to just get the list of values needed to do the update, you can do this:
UPDATE Market
SET Active = 1
WHERE MarketID IN
(
SELECT value
FROM OPENJSON('{"Comments": "test", "Markets": [3, 151]}','$.Markets')
);
value
s returned and filter our UPDATE on those, as we would were we dealing with any other subquery.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With