Вам уже говорили, что имена столбцов набора результатов должны быть известны заранее.
Единственный обходной путь - динамический SQL (создание оператора в виде строки и EXEC()
для получения его результата). Но у этого есть некоторые существенные недостатки (и некоторые преимущества) ...
Вы можете пойти с этим (требуется SQL-Server 2016 +):
A макет-стол
DECLARE @tbl TABLE(AppID VARCHAR(100),ID INT,JSONData NVARCHAR(MAX));
INSERT INTO @tbl VALUES
('5b5cd8',1,N'{"F":"B", "S":"D"}')
,('5b5cd8',2,N'{"F":"C", "S":"K"}')
,('6b9df0',3,N'{"T":"N", "D":"S"}');
- этот запрос извлекает значения, используя JSON_VALUE
- Вам нужно создать одно утверждение для каждого возможного списка столбцов
- Примените WHERE
для фильтрации по соответствующим строкам
SELECT t.AppID
,t.ID
,JSON_VALUE(t.JSONData,'$.F') AS F
,JSON_VALUE(t.JSONData,'$.S') AS S
FROM @tbl t
WHERE t.AppID='5b5cd8'
- Вы можете включить все возможные столбцы
- Это работает без фильтра, но вернет много NULL
SELECT t.AppID
,t.ID
,JSON_VALUE(t.JSONData,'$.F') AS F
,JSON_VALUE(t.JSONData,'$.S') AS S
,JSON_VALUE(t.JSONData,'$.T') AS T
,JSON_VALUE(t.JSONData,'$.D') AS D
FROM @tbl t
- немного чище / лучше читать было OPENJSON()
в связи с WITH
-клаузой
SELECT t.AppID
,t.ID
,JsonColumns.*
FROM @tbl t
CROSS APPLY OPENJSON(t.JSONData) WITH(F CHAR(1)
,S CHAR(1)
,T CHAR(1)
,D CHAR(1)) JsonColumns
Мое предложение: создайте последний как VIEW или (возможно, лучше) iTVF и используйте специальные операторы против этого, по одному на каждый тип структуры.