Вы не можете разобрать JSON, разделив.SQL Server 2016 и более поздние версии поддерживают JSON, поэтому вы можете извлекать нужные данные, используя такие функции, как JSON_VALUE .
У вас нет , чтобы сделать это,если вы не хотите индексировать и фильтровать эти значения.Возможно, имеет смысл извлечь страну или почтовый индекс, если вы собираетесь фильтровать или группировать результаты, используя их.Адресные строки, с другой стороны, не могут быть запрошены и могут также оставаться в строке JSON.Вы всегда можете извлечь их при необходимости с помощью JSON_VALUE.
Puttin primaryTown
in AddressLine4
выглядит как ошибка.Это является значимым атрибутом, который можно использовать при запросах.Он должен идти на свое поле или вообще не добываться.
SQL Server 2016 и более поздние версии
В любом случае вы можете проанализировать значение JSON с помощью JSON_VALUE
, например:
declare @myTable table(json varchar(max))
insert into @myTable
values
('{"addressLine1": "BjoXCDSaret 15", "addressLine2": "Jppsdeheim","addressLine3": "", "primaryTown": "AKERdwfUS", "addressCountry":
{"isoAlpha2Code": "NO"}}'),
('{"addressLine1": "67 xxxx Road", "primaryTown": "HOxxxCHxxCH",
"zipOrPostalCode": "RM11 1EX", "addressCountry": {"isoAlpha2Code":
"GB"}}'),
('{"primaryTown": "MünXXer", "addressCountry": {"isoAlpha2Code": "DE"}}'),
('{"addressLine1": "28 THE EXCAC", "primaryTown": "PERTH",
"provinceOrState": "WA", "addressCountry": {"isoAlpha2Code": "AU"}}'),
('{"addressLine1": "28 THE ESPLANADE", "primaryTown": "PERTH",
"provinceOrState": "WA", "addressCountry": {"isoAlpha2Code": "AU"}}'),
('{"addressLine1": "76 XXX STREET", "primaryTown": "MAXDFOT",
"provinceOrState": "NSW", "addressCountry": {"isoAlpha2Code": "AU"}}'),
('{"addressLine1": "UNIT 56", "addressLine2": "22 XDFR STREET",
"primaryTown": "MANLY VALE", "provinceOrState": "NSW",
"addressCountry": {"isoAlpha2Code": "AU"}}')
select
JSON_VALUE(json,'$.zipOrPostalCode') as ZipCode,
JSON_VALUE(json,'$.primaryTown') as primaryTown,
JSON_VALUE(json,'$.addressCountry.isoAlpha2Code') as CountryCode
from @mytable
Youмогут использовать одни и те же выражения для создания постоянных вычисляемых столбцов в таблице и индексирования их, тем самым ускоряя запросы, которые необходимо фильтровать по стране или почтовому индексу.
Старые версии
В старых версиях, возможно, самым простым решением было бы создание функции SQLCLR, которая использует JSON.NET для анализа данных и возврата значений.
Другой вариант - преобразовать строку JSON в XML с помощью замены строк и использовать XPATH для получения значений.Это может быть очень сложно, хотя замены зависят от ожидаемых данных, чувствительны к пробелам и могут легко сломаться при работе с вложенными объектами.
Например, этот плоский объект JSON:
declare @json varchar(max)='{"addressLine1": "BjoXCDSaret 15", "addressLine2": "Jppsdeheim", "addressLine3": "", "primaryTown": "AKERdwfUS"}'
Может быть преобразован в XML с несколькими заменами.Обратите внимание, что я исправил различия между пробелами, чтобы между токенами всегда было пространство.В противном случае мне пришлось бы заменить оба ","
и ", "
.
select
cast(
replace(
replace(
replace(
replace(@json,'{"','<it '),
'": "',' ="'),
'", "','" '),
'}',' />')
as xml)
Результат:
<it addressLine1="BjoXCDSaret 15" addressLine2="Jppsdeheim" addressLine3="" primaryTown="AKERdwfUS" />
Теперь это можно запросить с помощью .value :
select
cast(replace(replace(replace(replace(@json,'{"','<it '),'": "',' ="'),'", "','" '),'}',' />') as xml)
.value('(/it/@primaryTown)[1]','varchar(20)')
Это вернет:
AKERdwfUS
Это разрывается с вложенным объектом addressCountry
.Если вы знаете , что содержит текст JSON, вы можете использовать читы и заменять определенные атрибуты, а не только разделители, например:
declare @json varchar(max)='{"addressLine1": "UNIT 56", "addressLine2": "22 XDFR STREET", "primaryTown": "MANLY VALE", "provinceOrState": "NSW", "addressCountry": {"isoAlpha2Code": "AU"}}'
select
cast(
replace(
replace(
replace(
replace(
replace(
replace(@json,'", "addressCountry": {"','"><addressCountry '),
'}}','/></it>'),
'{"','<it '),
'": "',' ="'),
'", "','" ')
,'}',' />')
as xml).value('(/it/addressCountry/@isoAlpha2Code)[1]','varchar(20)')
Возвращает AU
.
Это серьезный обман, который может работать только методом проб и ошибок.В этом случае атрибут addressCountry
и следующие разделители преобразуются в элемент.Ожидается, что }}
появится только в конце строки, поэтому он получает специальную обработку.
Использование клиентского скрипта
Вероятно, проще использовать небольшую программу .NET для чтения данных с использованием JSON.NET и извлечения нужных значений.2М строк не так много, поэтому анализ данных время от времени не будет большой проблемой