У меня есть запрос (см. Ниже), который используется для создания вывода в виде XML.Запрос имеет дело с системой метаданных (EAV), которая имеет несколько типов столбцов и данных.
Мне нужна версия этого запроса, чтобы получить вывод в формате JSON
У меня уже была попытка, но столкнулся с проблемами.
1] Мне нужно ЗАКРЫТЬ данные столбца nvarchar (max) как nvarchar (4000), что не идеально, что-то связанное с конкатенацией, я думаю.
2] данные столбцов XML и JSON неправильно отформатированы, чтобы быть действительными в формате JSON.
Я не пробовал использовать OPENJSON или CTE, но готов что-то предпринять.
У меня есть запросв SQL Server 2017 (см. ниже), который использовался для создания XML-данных, и мне нужно изменить его, чтобы вместо этого создавать результаты в виде JSON.Перепробовал кучу вещей, но не совсем смог получить его.Цени любую помощь.
Уже есть попытка запроса для версии JSON, но у нее есть несколько проблем.1] Мне нужно CAST nvarchar как 4000, иначе он обрезает данные (не идеально).2] Не удается получить столбцы типа xml и json для получения правильного вывода.
Не пробовал использовать OPENJSON или CTE, но открыт для идей.
-- structure
DECLARE @metaFields TABLE(
[metaFieldID] [uniqueidentifier] ROWGUIDCOL NOT NULL,
[metasetID] [uniqueidentifier] NOT NULL,
[metaColumnID] [uniqueidentifier] NOT NULL,
[systemRef] [varchar](255) NOT NULL,
[displayType] [varchar](50) NOT NULL
)
DECLARE @metaColumns TABLE (
[metaColumnID] [uniqueidentifier] ROWGUIDCOL NOT NULL,
[storageTable] [varchar](255) NOT NULL,
[storageColumn] [varchar](255) NOT NULL,
[storageType] [varchar](10) NOT NULL,
[storageSize] [smallint] NULL
)
DECLARE @metaDataObjectVersions TABLE (
[metaDataObjectVersionID] [int] NOT NULL,
[xmlVersionData] [xml] NULL
)
DECLARE @metaData TABLE (
[metaDataID] [int] NOT NULL,
[metaDataObjectVersionID] [int] NOT NULL,
[metaColumnID] [uniqueidentifier] NOT NULL,
[numericData] [real] NULL,
[dateData] [datetime] NULL,
[textData] [nvarchar](max) NULL,
[GUIDData] [uniqueidentifier] NULL,
[xmlData] [xml] NULL,
[jsonData] [nvarchar](max) NULL
)
-- data
INSERT INTO @metaFields
([metaFieldID],[metasetID],[metaColumnID],[systemRef],[displayType])
VALUES
('FFFFFFFF-0000-0000-0000-000000000001','AAAAAAAA-0000-0000-0000-000000000001','CCCCCCCC-0000-0000-0000-000000000001','ACTIVE','RADIOBUTTON'),
('FFFFFFFF-0000-0000-0000-000000000002','AAAAAAAA-0000-0000-0000-000000000001','CCCCCCCC-0000-0000-0000-000000000002','CREATED','TEXT'),
('FFFFFFFF-0000-0000-0000-000000000003','AAAAAAAA-0000-0000-0000-000000000001','CCCCCCCC-0000-0000-0000-000000000003','CONTENT','TEXTAREA'),
('FFFFFFFF-0000-0000-0000-000000000004','AAAAAAAA-0000-0000-0000-000000000001','CCCCCCCC-0000-0000-0000-000000000004','TAGS','TEXT'),
('FFFFFFFF-0000-0000-0000-000000000005','AAAAAAAA-0000-0000-0000-000000000001','CCCCCCCC-0000-0000-0000-000000000005','XOPTIONS','SELECTBOX'),
('FFFFFFFF-0000-0000-0000-000000000006','AAAAAAAA-0000-0000-0000-000000000001','CCCCCCCC-0000-0000-0000-000000000006','JOPTIONS','SELECTBOX')
INSERT INTO @metaColumns
([metaColumnID],[storageTable],[storageColumn],[storageType],[storageSize])
VALUES
('CCCCCCCC-0000-0000-0000-000000000001','METADATA','numericData','numeric',NULL),
('CCCCCCCC-0000-0000-0000-000000000002','METADATA','dateData','date',NULL),
('CCCCCCCC-0000-0000-0000-000000000003','METADATA','textData','text',NULL),
('CCCCCCCC-0000-0000-0000-000000000004','METADATA','GUIDData','guid',NULL),
('CCCCCCCC-0000-0000-0000-000000000005','METADATA','xmlData','text',NULL),
('CCCCCCCC-0000-0000-0000-000000000006','METADATA','jsonData','text',NULL)
INSERT INTO @metaDataObjectVersions
([metaDataObjectVersionID],[xmlVersionData])
VALUES
(1,'<data><active>1</active><created>2019-01-01</created><content><html><head><title> HTML Document</title></head><body><p>HTML document</p></body></html></content><tags>37C3879F-CF6E-4A5D-BD3C-FCEA1D9F2233,37C3879F-CF6E-4A5D-BD3C-FCEA1D9F2244</tags><xoptions><rows><row id="37c3879f-cf6e-4a5d-bd3c-fcea1d9f2233"><optionValue>Usage 1</optionValue><sorting>1</sorting><selected>1</selected></row></rows></xoptions><joptions>[{"id": 1,"value": "Option 1","selected": true},{"id": 1,"value": "Option 1","selected": false }]</joptions></data>'),
(2,'<data><active>0</active><content><html><head><title> HTML Document2</title></head><body><p>HTML document2</p></body></html></content><tags>37C3879F-CF6E-4A5D-BD3C-FCEA1D9F4433</tags><xoptions/><joptions>[{"id": 3,"value": "Option 3","selected": true}]</joptions></data>')
INSERT INTO @metaData
([metaDataID],[metaDataObjectVersionID],[metaColumnID],[numericData],[dateData],[textData],[GUIDData],[xmlData],[jsonData])
VALUES
(1,1,'CCCCCCCC-0000-0000-0000-000000000001',1,NULL,NULL,NULL,NULL,NULL),
(2,1,'CCCCCCCC-0000-0000-0000-000000000002',NULL,'2019-01-01',NULL,NULL,NULL,NULL),
(3,1,'CCCCCCCC-0000-0000-0000-000000000003',NULL,NULL,'<html><head><title> HTML Document</title></head><body><p>HTML document</p></body></html>',NULL,NULL,NULL),
(4,1,'CCCCCCCC-0000-0000-0000-000000000004',NULL,NULL,NULL,'37C3879F-CF6E-4A5D-BD3C-FCEA1D9F2233',NULL,NULL),
(5,1,'CCCCCCCC-0000-0000-0000-000000000004',NULL,NULL,NULL,'37C3879F-CF6E-4A5D-BD3C-FCEA1D9F2244',NULL,NULL),
(6,1,'CCCCCCCC-0000-0000-0000-000000000005',NULL,NULL,NULL,NULL,'<rows><row id="37c3879f-cf6e-4a5d-bd3c-fcea1d9f2233"><optionValue>Usage 1</optionValue><sorting>1</sorting><selected>1</selected></row></rows>',NULL),--<rows><row id="37c3879f-cf6e-4a5d-bd3c-fcea1d9f2233"><optionValue>Usage 1</optionValue><sorting>1</sorting><selected>1</selected></row></rows>
(7,1,'CCCCCCCC-0000-0000-0000-000000000006',NULL,NULL,NULL,NULL,NULL,'[{"id": 1,"value": "Option 1","selected": true},{"id": 1,"value": "Option 1","selected": false }]'),
(8,2,'CCCCCCCC-0000-0000-0000-000000000001',0,NULL,NULL,NULL,NULL,NULL),
(9,2,'CCCCCCCC-0000-0000-0000-000000000003',NULL,NULL,'<html><head><title> HTML Document2</title></head><body><p>HTML document2</p></body></html>',NULL,NULL,NULL),
(10,2,'CCCCCCCC-0000-0000-0000-000000000004',NULL,NULL,NULL,'37C3879F-CF6E-4A5D-BD3C-FCEA1D9F4433',NULL,NULL),
(11,2,'CCCCCCCC-0000-0000-0000-000000000005',NULL,NULL,NULL,NULL,NULL,NULL),
(12,2,'CCCCCCCC-0000-0000-0000-000000000006',NULL,NULL,NULL,NULL,NULL,'[{"id": 3,"value": "Option 3","selected": true}]')
-- EXISTING XML QUERY
SELECT metaDataObjectVersionID,
CAST(metaObjectVersionData AS XML) AS versionData
FROM (
SELECT MD.metaDataObjectVersionID,
(
SELECT CAST('<' + LOWER(MF.systemRef) + '>' + LEFT(DATA.col, LEN(DATA.col) - 1) + '</' + LOWER(MF.systemRef) + '>' AS XML)
FROM @metaData MD1
INNER JOIN @metaFields MF ON (MF.metaColumnID = MD1.metaColumnID)
CROSS APPLY (
SELECT CASE (SELECT MC.storageColumn FROM @metaColumns MC WHERE MC.metaColumnID = MD2.metaColumnID)
WHEN 'numericData' THEN ISNULL(CAST(numericData AS NVARCHAR(MAX)), '')
WHEN 'dateData' THEN ISNULL(CAST(dateData AS NVARCHAR(MAX)), '')
WHEN 'textData' THEN ISNULL(CAST(textData AS NVARCHAR(MAX)), '')
WHEN 'guidData' THEN ISNULL(CAST(guidData AS VARCHAR(36)), '')
WHEN 'xmlData' THEN ISNULL(CAST(xmlData AS NVARCHAR(MAX)), '')
WHEN 'jsonData' THEN ISNULL(CAST(jsonData AS NVARCHAR(MAX)), '')
ELSE CAST('' AS VARCHAR(36)) END + ','
FROM @metaData MD2
WHERE MD2.metaDataObjectVersionID = MD1.metaDataObjectVersionID AND MD2.metaColumnID = MD1.metaColumnID
FOR XML PATH('')
) AS DATA(col)
WHERE MD1.metaDataObjectVersionID = MD.metaDataObjectVersionID
GROUP BY MF.systemRef,
DATA.col
FOR XML PATH(''), ROOT('data')
) AS metaObjectVersionData
FROM @metaData MD
GROUP BY MD.metaDataObjectVersionID
) VW
-- JSON QUERY SO FAR
SELECT A.metaDataObjectVersionID, MDOV.xmlVersionData, N'{' + metaObjectVersionData + N'}' AS JSONVersionData
FROM (
SELECT MD.metaDataObjectVersionID,
(
SELECT QUOTENAME(LOWER(MF.systemRef),'"') + ':' + LEFT(DATA.col, LEN(DATA.col))
FROM @metaData MD1
INNER JOIN @metaFields MF ON (MF.metaColumnID = MD1.metaColumnID)
CROSS APPLY (
SELECT CASE (SELECT MC.storageColumn FROM @metaColumns MC WHERE MC.metaColumnID = MD2.metaColumnID)
WHEN 'numericData' THEN CAST(numericData AS NVARCHAR(MAX))
WHEN 'dateData' THEN QUOTENAME(CAST(dateData AS NVARCHAR(MAX)),'"')
WHEN 'textData' THEN QUOTENAME(CAST(textData AS NVARCHAR(4000)),'"')
WHEN 'guidData' THEN QUOTENAME(CAST(guidData AS VARCHAR(36)),'"')
WHEN 'xmlData' THEN QUOTENAME(STRING_ESCAPE(CAST(xmlData AS NVARCHAR(MAX)),'json'),'"')
WHEN 'jsonData' THEN jsonData
ELSE CAST('' AS VARCHAR(36))
END + ','
FROM @metaData MD2
WHERE MD2.metaDataObjectVersionID = MD1.metaDataObjectVersionID AND MD2.metaColumnID = MD1.metaColumnID
FOR XML PATH('')
) AS DATA(col)
WHERE MD1.metaDataObjectVersionID = MD.metaDataObjectVersionID
GROUP BY MF.systemRef,
DATA.col
FOR XML PATH('')
) AS metaObjectVersionData
FROM @metaData MD
GROUP BY MD.metaDataObjectVersionID
) A
JOIN @metaDataObjectVersions MDOV ON A.metaDataObjectVersionID = MDOV.metaDataObjectVersionID
Я хочу выводбыть правильно отформатированным и действительным JSON.Ниже приведен правильный ожидаемый формат:
{
"active": 1,
"content": "<html><head ><title> HTML Document</title></head><body><p>HTML document</p><a href=\"https://www.w3schools.com\">This is a link</a></body></html>",
"created": "Jan 1 2019 12:00AM",
"joptions": [
{
"id": 1,
"value": "Option 1",
"selected": true
},
{
"id": 1,
"value": "Option 1",
"selected": false
}
],
"tags": [
"37C3879F-CF6E-4A5D-BD3C-FCEA1D9F2233",
"37C3879F-CF6E-4A5D-BD3C-FCEA1D9F2244"
],
"xoptions": "<rows><row id=\"37c3879f-cf6e-4a5d-bd3c-fcea1d9f2233\"><optionValue>Usage 1</optionValue> <sorting>1</sorting><selected>1</selected></row></rows>"
}
У меня есть рабочий запрос, но он выглядит немного грязно.Если кто-то может предложить улучшения, пожалуйста, прокомментируйте.
--THIS IS THE QUERY WHICH SEEMS TO WORK!!!
SELECT MDOV.metaDataObjectVersionID,
'{' + STRING_AGG(QUOTENAME(LOWER(MD1.systemRef),'"') + ' : ' +
CASE
WHEN MD1.storageColumn = 'numericData' THEN CASE WHEN CNT > 1 THEN '[' + MD1.numericData + ']' ELSE MD1.numericData END
WHEN MD1.storageColumn = 'dateData' THEN CASE WHEN CNT > 1 THEN '[' + MD1.dateData + ']' ELSE MD1.dateData END
WHEN MD1.storageColumn = 'textData' THEN CASE WHEN CNT > 1 THEN '[' + MD1.textData + ']' ELSE MD1.textData END
WHEN MD1.storageColumn = 'guidData' THEN CASE WHEN CNT > 1 THEN '[' + MD1.guidData + ']' ELSE MD1.guidData END
WHEN MD1.storageColumn = 'xmlData' THEN CASE WHEN CNT > 1 THEN '[' + MD1.xmlData + ']' ELSE MD1.xmlData END
WHEN MD1.storageColumn = 'jsonData' THEN CASE WHEN CNT > 1 THEN '[' + MD1.jsonData + ']' ELSE MD1.jsonData END
END ,',') + '}'
FROM @metaDataObjectVersions MDOV
CROSS APPLY (
SELECT MD2.metaDataObjectVersionID,MF.systemRef,MD2.metaColumnID,MC.storageColumn,
COUNT(*) AS CNT,
STRING_AGG(CONVERT(VARCHAR,numericData), ',') AS numericData,
STRING_AGG('"' + CONVERT(VARCHAR, dateData,121) + '"', ',') AS dateData,
STRING_AGG('"' + CONVERT(CHAR(36),guidData) + '"', ',') AS guidData,
STRING_AGG('"' + STRING_ESCAPE(textData, 'json') + '"', ',') AS textData,
STRING_AGG('"' + STRING_ESCAPE(CONVERT(NVARCHAR(MAX),xmlData), 'json') + '"', ',') AS xmlData,
STRING_AGG('"' + STRING_ESCAPE(jsonData, 'json') + '"', ',') AS jsonData
FROM @metaData MD2
JOIN @metaFields MF ON MD2.metaColumnID = MF.metaColumnID
JOIN @metaColumns MC ON MD2.metaColumnID = MC.metaColumnID
WHERE MD2.metaDataObjectVersionID = MDOV.metaDataObjectVersionID
GROUP BY MD2.metaDataObjectVersionID,MF.systemRef,MD2.metaColumnID,MC.storageColumn
) MD1
GROUP BY MDOV.metaDataObjectVersionID
ORDER BY MDOV.metaDataObjectVersionID