То, что у вас есть JSON, вы знаете это, казалось бы. Начиная с v2016, есть встроенная поддержка JSON, но с v2014 для этого потребуются некоторые хитрые строковые трюки (которые могут легко потерпеть неудачу) ...
Мое предложение состояло в том, чтобы преобразовать JSON в атрибут-центрированный XML:
declare @rawData nvarchar (max) =
'{"request_id":"801707","final_decision":"PASS","derived_Attribute_3":"PASS|Number of Total Active Institutions :3","derived_Attribute_1":"PASS|Number of active MFI :0","derived_Attribute_2":"PASS|Overdue Amount:0.0","derived_Attribute_4":"PASS|Total Exposure + Applied Amount :76384.0","derived_Attribute_5":"PASS|Write off amount:0.0","cbResponseMsg":"Final Decision:PASS || Number of Total Active Institutions :3 || Number of active MFI :0 || Overdue Amount:0.0 || Total Exposure + Applied Amount :76384.0 || Write off amount:0.0"}';
SELECT CAST(REPLACE(REPLACE(REPLACE(REPLACE(@rawData,'{"','<rawData '),'":"','="'),'","','" '),'"}','"/>') AS XML);
Результат:
<rawData request_id="801707"
final_decision="PASS"
derived_Attribute_3="PASS|Number of Total Active Institutions :3"
derived_Attribute_1="PASS|Number of active MFI :0"
derived_Attribute_2="PASS|Overdue Amount:0.0"
derived_Attribute_4="PASS|Total Exposure + Applied Amount :76384.0"
derived_Attribute_5="PASS|Write off amount:0.0"
cbResponseMsg="Final Decision:PASS || Number of Total Active Institutions :3 || Number of active MFI :0 || Overdue Amount:0.0 || Total Exposure + Applied Amount :76384.0 || Write off amount:0.0" />
Теперь мы можем использовать запрос для получения значения каждого отдельного атрибута.
SELECT B.*
FROM (VALUES(CAST(REPLACE(REPLACE(REPLACE(REPLACE(@rawData,'{"','<rawData '),'":"','="'),'","','" '),'"}','"/>') AS XML)))A(CastedToXml)
CROSS APPLY(VALUES(CastedToXml.value('(/rawData/@request)[1]','int')
,CastedToXml.value('(/rawData/@final_decision)[1]','varchar(100)')
,CastedToXml.value('(/rawData/@derived_Attribute_1)[1]','varchar(1000)')
,CastedToXml.value('(/rawData/@derived_Attribute_2)[1]','varchar(1000)')
,CastedToXml.value('(/rawData/@derived_Attribute_3)[1]','varchar(1000)')
,CastedToXml.value('(/rawData/@derived_Attribute_4)[1]','varchar(1000)')
,CastedToXml.value('(/rawData/@derived_Attribute_5)[1]','varchar(1000)')
,CastedToXml.value('(/rawData/@cbResponseMsg)[1]','varchar(1000)'))
)B(request,final_decision,derived_Attribute_1,derived_Attribute_2,derived_Attribute_3,derived_Attribute_4,derived_Attribute_5,cbResponseMsg);
Это позволяет использовать простые строковые методы для каждой извлеченной строки.
Последний запрос
Это приводит нас к последнему запросу. Посмотрите, как я использую REVERSE()
, чтобы вернуть прочитанные элементы справа налево. Это позволяет искать первый :
и использовать LEFT()
, чтобы отрезать эту часть. Для окончательного результата мы также должны использовать REVERSE()
на обрезанной строке.
SELECT B.request_id
,B.final_decision
,REVERSE(LEFT(B.derived_Attribute_1,CHARINDEX(':',B.derived_Attribute_1)-1)) AS derived_Attribute_1
,REVERSE(LEFT(B.derived_Attribute_2,CHARINDEX(':',B.derived_Attribute_2)-1)) AS derived_Attribute_2
,REVERSE(LEFT(B.derived_Attribute_3,CHARINDEX(':',B.derived_Attribute_3)-1)) AS derived_Attribute_3
,REVERSE(LEFT(B.derived_Attribute_4,CHARINDEX(':',B.derived_Attribute_4)-1)) AS derived_Attribute_4
,REVERSE(LEFT(B.derived_Attribute_5,CHARINDEX(':',B.derived_Attribute_5)-1)) AS derived_Attribute_5
,B.cbResponseMsg
FROM (VALUES(CAST(REPLACE(REPLACE(REPLACE(REPLACE(@rawData,'{"','<rawData '),'":"','="'),'","','" '),'"}','"/>') AS XML)))A(CastedToXml)
CROSS APPLY(VALUES(CastedToXml.value('(/rawData/@request_id)[1]','int')
,CastedToXml.value('(/rawData/@final_decision)[1]','varchar(100)')
,REVERSE(CastedToXml.value('(/rawData/@derived_Attribute_1)[1]','varchar(1000)'))
,REVERSE(CastedToXml.value('(/rawData/@derived_Attribute_2)[1]','varchar(1000)'))
,REVERSE(CastedToXml.value('(/rawData/@derived_Attribute_3)[1]','varchar(1000)'))
,REVERSE(CastedToXml.value('(/rawData/@derived_Attribute_4)[1]','varchar(1000)'))
,REVERSE(CastedToXml.value('(/rawData/@derived_Attribute_5)[1]','varchar(1000)'))
,CastedToXml.value('(/rawData/@cbResponseMsg)[1]','varchar(1000)'))
)B(request_id,final_decision,derived_Attribute_1,derived_Attribute_2,derived_Attribute_3,derived_Attribute_4,derived_Attribute_5,cbResponseMsg);
Результат
+------------+----------------+---------------------+---------------------+---------------------+---------------------+---------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| request_id | final_decision | derived_Attribute_1 | derived_Attribute_2 | derived_Attribute_3 | derived_Attribute_4 | derived_Attribute_5 | cbResponseMsg |
+------------+----------------+---------------------+---------------------+---------------------+---------------------+---------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| 801707 | PASS | 0 | 0.0 | 3 | 76384.0 | 0.0 | Final Decision:PASS || Number of Total Active Institutions :3 || Number of active MFI :0 || Overdue Amount:0.0 || Total Exposure + Applied Amount :76384.0 || Write off amount:0.0 |
+------------+----------------+---------------------+---------------------+---------------------+---------------------+---------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+