Как сделать так, чтобы значения полей таблицы SQL были ключами объекта JSON в SQL? - PullRequest
3 голосов
/ 12 апреля 2019

Я пытался получить объект JSON из моей БД в нужном мне формате, поэтому я запустил следующий SQL-запрос:

SELECT PROJECTS.key_code AS CODE, PROJECTS.name AS Name,
         PROJECTS.date AS Date, PROJECTS.descr AS Description
         FROM PROJECTS LEFT JOIN ACCESS
         ON PROJECTS.key_code = ACCESS.key_code
         WHERE ACCESS.Ukey_code = '5d8hd5' FOR JSON PATH, WITHOUT_ARRAY_WRAPPER;

и результат запроса следующим образом:

{
  "Code": "h5P93G",
  "Name": "Project1 test name",
  "Date": "2017-09-03",
  "Description": "This is a test description 1"
 },
  "Code": "KYJ482",
  "Name": "Project2 test name",
  "Date": "2018-10-25",
  "Description": "This is a test description 2"
}

но на самом деле то, что я хочу, отличается. Объект JSON должен выглядеть следующим образом:

{
  "h5P93G": {
          "Name": "Project1 test name",
          "Date": "2017-09-03",
          "Description": "This is a test description 1"
        },
  "KYJ482": {
          "Name": "Project2 test name",
          "Date": "2018-10-25",
          "Description": "This is a test description 2"
        },
}

Итак, как мне получить этот объект JSON?

1 Ответ

1 голос
/ 13 апреля 2019

Насколько я знаю, вы не можете создать json с именами ключей переменных с select ... for json.

Однако, если вы не возражаете против использования переменных и используете Sql Server 2017 (иначе вы не можете использовать динамические клавиши для json-modify), вы можете сделать это следующим образом:

declare @a nvarchar(max) = '{}'

select
    @a = json_modify(
        @a,
        concat('$.', p.key_code),
        json_query((select p.name, p.[date], p.descr for json path, without_array_wrapper))
    )
from projects as p

select @a

ДБ демо скрипки

Если вы используете более ранние выпуски Sql Server, вы можете просто агрегировать его с помощью любого метода агрегации, который вы можете найти (я использовал string_agg просто для простоты здесь):

select
    concat('{', string_agg(
        concat('"',p.key_code,'":',p.data),
        ','
    ), '}')
from (
    select
        p.key_code,
        (select p.name, p.[date], p.descr for json path, without_array_wrapper) as data
    from projects as p
) as p

ДБ демо скрипки

Вы также можете использовать string_escape для предотвращения ошибок, если ваши ключи могут содержать специальные символы:

select
    ...
        concat('"',string_escape(p.key_code,'json'),'":',p.data),
        ','
    ...

ДБ демо скрипки

...