2016-02-04 3 views
2

Я ищу, чтобы создать хорошо отформатированный JSON из хранимой процедуры SQL Server.Каковы лучшие практики JSON в SQL Server?

Моя проблема заключается в следующем:

Создание JSON как:

DECLARE @x varchar(20) 
DECLARE @y varchar(20) 

CREATE TABLE #temp 
(
    JSON varchar(max) 
) 

INSERT INTO #temp 
VALUES (
'{' + 
    case when x IS NOT NULL BEGIN 
     '"key1":"' + x + '"' + 
    END 
    case when y IS NOT NULL BEGIN 
     '"key1":"' + y + '"' + 
    END 
'}') 

Каков наилучший способ иметь "s" хорошо отформатированный JSON ?? Я хотел бы максимально минимизировать логику (т. Е. Не иметь ветви для каждой из х * у комбинаций).

Если запятая установлена ​​в конце условий x if, она терпит неудачу, если y равно null. Если запятая ставится перед вставкой y в json, она терпит неудачу, если x равно null.

Есть ли лучший способ достичь этого в SQL Server?

+0

Можете ли вы опубликовать значимый SQL-запрос. Откуда берутся значения «Х». Также какая версия 'SQL Server' вы используете значения –

+0

x из другой таблицы, очевидно, что они имеют значение NULL, но значения не обязательно имеют значение, кроме того, что они действительны varchar (20) s. Независимо от SQL Server? Это менее специфический и более важный вопрос. Есть ли лучший способ заставить JSON использовать SQL при динамическом извлечении значений из другой таблицы? – HedonicHedgehog

+2

Я бы не сделал этого с SQL, если бы не было другого варианта. Вы должны запросить результаты изначально, а затем преобразовать их в json в приложении-потребителе. –

ответ

0

[править на основе комментарий OP в]

Я изменил путь строится в формате JSON, а также обобщил его на любое количество пар ключей => значение:

drop table #tokens 
GO 

CREATE TABLE #tokens 
(
    Key_ VARCHAR(32), 
    Val VARCHAR(255) 
) 

INSERT INTO #tokens VALUES ('key1', 'val1'), ('key1', 'val2'), ('key3', NULL), ('key4', 'val3') 
GO 

DECLARE @JSON VARCHAR(MAX) 

-- add key => pairs along with some newlines to have a decent output 
SELECT 
    @JSON = CASE 
     WHEN @JSON IS NULL AND Key_ IS NOT NULL 
     THEN '"' + Key_ + '":"' + ISNULL(Val, '') + '"' 
     ELSE @JSON + ',' + CHAR(13) + CHAR(10) + '"' + Key_ + '":"' + ISNULL(Val, '') + '"' 
    END 
FROM 
    #tokens AS T 

SELECT '{' + CHAR(13) + CHAR(10) + @JSON + CHAR(13) + CHAR(10) + '}' 

Конечно, другой (что может быть проще для более крупных иерархий данных) заключается в сериализации объектов на языке C#/Java/другого высокого уровня, который поддерживает сериализацию ООП и JSON.

Лично мне нравятся структурированные данные, поскольку они позволяют использовать ограничения базы данных, такие как внешний ключ, уникальные, контрольные ограничения и т. Д. В этом случае я бы советовал хранить данные в нормализованных таблицах по мере возможности и иметь преобразование в прикладном уровне (C#, Java и т. Д.).

Большинство языков позволяют легко сериализовать/десериализовать в/из формата JSON, чтобы можно было свести ваши данные в нормализованные таблицы. Это особенно важно при выполнении некоторых агрегатов против ваших данных, так как гораздо проще (и быстрее) применять эти функции для нормализованных данных.

Подробнее об этой последней теме можно найти here.

+0

Таким образом, проблема с этим ответом такая же, я прошу о помощи, если я не ошибаюсь: Если x равно null, то ваш окончательный вывод будет: {"key1": "Y_VALUE",} JSON не принимает запятые, поэтому это приводит к недействительным JSON – HedonicHedgehog

+0

Я согласен с вашими точками о переходе на более высокий уровень языка - было бы намного проще.Одна из возможных настроек этого решения, использующая взломанный «COALESCE» (который я только помнил из-за того, что вы давно столкнулись с подобной потребностью и появился быстрый поиск SO), выглядит примерно так: 'select @JSON = COALESCE (@JSON + ',', '') + '"' + Key_ + '": "' + ISNULL (Val, '') + '' 'из # токенов'. Я думаю, что это устраняет любые проблемы с запятой. –

Смежные вопросы