Обработка SQL Server JSON

#json #sql-server #tsql

#json #sql-сервер #tsql

Вопрос:

Я использую данные JSON как способ хранения сведений о заказе в одном nvarchar столбце таблицы «заказы». Первоначально я использовал «общий» способ создания массива объектов (используя «для пути JSON»), но достаточно скоро обнаружил, что нет способа обновить отдельные объекты массива — только по индексу / позиции — что бесполезно, или заменить всю строку JSON — что безумно. (или есть?).

В любом случае, я подумал, что если я изменю массив объектов в словарь, я смогу обновить один элемент / объект с помощью простой json_modify команды.

Итак, я перешел от этого:

 [
    {
        "File": 350464,
        "Bin": 143601,
        "Status": 1
    },
    {
        "File": 350743,
        "Bin": 143610,
        "Status": 2
    },
    {
        "File": 350956,
        "Bin": 143615,
        "Status": 2
    },
    {
        "File": 351350,
        "Bin": 143498,
        "Status": 1
    }
]
 

Для этого:

 {
    "350517":{"bin":143602,"status":1},
    "350641":{"bin":143607,"status":1},
    "350745":{"bin":143610,"status":2},
    "350805":{"bin":143611,"status":2},
    "358898":{"bin":145461,"status":1}
}
 

Теперь я застрял на другом конце — при попытке прочитать JSON как результат таблицы.
Это то, что я использую:

 SELECT files.*, JSON_VALUE(files.value, '$.bin') [Bin], JSON_VALUE(files.value, '$.status') [Status]
FROM OPENJSON(@json) files
 

И это результат:

 key value   type    Bin Status
350517  {"bin":143602,"status":1}   5   143602  1
350641  {"bin":143607,"status":1}   5   143607  1
350745  {"bin":143610,"status":1}   5   143610  1
350805  {"bin":143611,"status":1}   5   143611  1
358898  {"bin":145461,"status":1}   5   145461  1
 

Наконец-то! Я так близок … как вы видите из приведенных выше результатов, я могу получить данные «bin» и «status» из JSON в столбцы результирующего набора, используя json_value .

Мой вопрос: как я могу получить «ключевые» данные в столбце моего результата? Я вижу это при выборе «*» (как показано выше), но я ненавижу выбирать *. как мне обратиться к нему напрямую? И пока это происходит, откуда берется столбец «тип» и что означает «5»?

Комментарии:

1. Почему бы не использовать нормализованный дизайн в первую очередь? Данные в формате JSON / XML не лучше всего подходят для хранения таких данных в базе данных, и вам даже не нужно пытаться пытаться создать беспорядок, который вы делаете прямо сейчас.

Ответ №1:

Вы пробовали выбирать свое key значение?

 declare @json nvarchar(max) = N'{
    "350517":{"bin":143602,"status":1},
    "350641":{"bin":143607,"status":1},
    "350745":{"bin":143610,"status":2},
    "350805":{"bin":143611,"status":2},
    "358898":{"bin":145461,"status":1}
}';

select
  [key] as [file],
  json_value(value, '$.bin') as [bin],
  json_value(value, '$.status') as [status]
from openjson(@json);
 

Что дает:

файл bin Статус
350517 143602 1
350641 143607 1
350745 143610 2
350805 143611 2
358898 145461 1

Комментарии:

1. ой!. вы правы! я попробовал files.key и json_value(files.key, ‘$’), но не смог добраться только до [key] . приветствую, приятель!

2. А что касается комментария @Larnu — порядок перемещается между несвязанными системами — так что я думаю, что строки json — лучший выбор, не так ли?