Можете ли вы напрямую запросить таблицу базы данных для содержимого JSON - PullRequest
2 голосов
/ 18 июня 2019

Невозможно извлечь полезную информацию из данных JSON, хранящихся в таблице.

У меня есть данные JSON, хранящиеся в таблице SQL Server, к которой я хотел бы получить доступ к одному или двум элементам для проверки значений и т. Д. Моя таблица определенакак показано ниже:

CREATE TABLE [Events].[events](
    [eventID] [int] IDENTITY(1,1) NOT NULL,
    [eventType] [smallint] NOT NULL,
    [eventDate] [datetime] NOT NULL,
    [eventMetaData] [nvarchar](max) NULL,
    CONSTRAINT [PK_events] PRIMARY KEY CLUSTERED 
    (
        [eventID] ASC
    ) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

с данными JSON, содержащимися в столбце eventMetaData.

В столбце eventMetaData хранятся данные следующим образом:

[{
    "jn": "jn1",
    "src": "client123",
    "id": 649
}]

и I 'Я хотел бы попытаться извлечь эту информацию для отображения на странице.

До сих пор я пытался использовать JSON_VALUE и JSON_QUERY методы извлечения требуемой строки, хотя я считаю, что это JSON_VALUE, который мне следует использовать.

SELECT top 10 eventId, eventDate, 
 JSON_VALUE(eventData,'$.jn') AS jn
from events
WHERE ISJSON(eventData)>0
order by eventdate desc

Когда я запускаю это, я получаю eventID & eventDate, но всегда получаю NULL в столбце jn.

В некоторых публикациях приведены примеры данных, находящихся в переменной типа nvarchar (max), и если я добавлю свой JSON в него, он будет работать с моим запросом, но мне действительно нужно, чтобы он пришел из таблицы, поскольку мне нужно отобразить несколько строк для моего клиента.

Из примера, который я опубликовал выше, яЯ хотел бы получить значения eventID, eventDate & jn из запроса, но в тот момент, когда я получаю eventID & eventDate, но всегда получаю NULL в столбце jn.

В конечном итоге я надеюсь получитьдополнительные ключи в столбце JSON, к которым я могу получить доступ и отобразить их конечному пользователю.

Ответы [ 2 ]

1 голос
/ 18 июня 2019

Вы очень близки. Если ваш eventMetaData всегда является массивом JSON с одним элементом, вы можете использовать JSON_VALUE следующим образом:

Таблица:

CREATE TABLE [events] (
    [eventID] [int] IDENTITY(1,1) NOT NULL,
    [eventType] [smallint] NOT NULL,
    [eventDate] [datetime] NOT NULL,
    [eventMetaData] [nvarchar](max) NULL
)

INSERT INTO [events] 
    (eventType, eventDate, eventMetaData)
VALUES 
    (1, '20190618', N'[{"jn": "jn1","src": "client123","id": 649}]')

T-SQL:

SELECT
   JSON_VALUE(eventMetaData, '$[0].jn') jn,
   JSON_VALUE(eventMetaData, '$[0].src') src,
   JSON_VALUE(eventMetaData, '$[0].id') id,
   *
FROM [events]   

Выход:

jn  src         id  eventID eventType   eventDate           eventMetaData
jn1 client123   649 1       1           18/06/2019 00:00:00 [{"jn": "jn1","src": "client123","id": 649}]

Примечания:

Если в массиве JSON больше элементов, используйте OPENJSON с оператором CROSS APPLY:

CREATE TABLE [events] (
    [eventID] [int] IDENTITY(1,1) NOT NULL,
    [eventType] [smallint] NOT NULL,
    [eventDate] [datetime] NOT NULL,
    [eventMetaData] [nvarchar](max) NULL
)

INSERT INTO [events] 
    (eventType, eventDate, eventMetaData)
VALUES 
    (1, '20190618', N'[{"jn": "jn1","src": "client123","id": 649}, {"jn": "jn2","src": "client124","id": 659}]')

SELECT
   j.jn,
   j.src,
   j.id,
   e.*
FROM [events] e
CROSS APPLY OPENJSON(e.eventMetaData) WITH (
   jn nvarchar(3) '$.jn', 
   src nvarchar(50) '$.src', 
   id int '$.id'
) j
1 голос
/ 18 июня 2019

Я тоже не могу заставить работать JSON_VALUE, но OPENJSON работает для меня:

DECLARE @j NVARCHAR(255) = 
    '[{
        "jn": "jn1",
        "src": "client123",
        "id": 649
    }]'

SELECT [jn]
     , [src]
     , [id]
FROM OPENJSON(@j)
WITH (jn NVARCHAR(10) '$.jn'
    , src NVARCHAR(255) '$.src'
    , id INT '$.id'
    )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...