2

假设你有

create schema tmp
go

create table tmp.Properties
(
  ParentId uniqueidentifier not null,
  PropertyName nvarchar(20) not null,
  PropertyValue nvarchar(100) null,

  primary key (ParentId,PropertyName)
)
go

create table tmp.FullData
(
  ParentId uniqueidentifier not null,
  Properties nvarchar(max) null,

  primary key (ParentId)
)
go

declare @id1 uniqueidentifier = 'F1935D6A-D5A6-4FA1-ACF4-BA3858804CEC',
        @id2 uniqueidentifier = 'F1935D6B-D5A6-4FA1-ACF4-BA3858804CEC'

insert into tmp.Properties
values
(@id1, 'FirstName', 'Luke'),
(@id1, 'LastName', 'Skywalker'),
(@id2, 'FirstName', 'Han'),
(@id2, 'LastName', 'Solo')

请考虑:

  • 属性是动态创建的,我无法提前知道 PropertyNames
  • 目前 parents 表包含 1M 和 properties 表包含 23M 记录

如何填写 tmp.FullData:

ParentId                             Properties
------------------------------------ ------------------------------------------------
F1935D6A-D5A6-4FA1-ACF4-BA3858804CEC { "FirstName": "Luke", "LastName": "Skywalker" }
F1935D6B-D5A6-4FA1-ACF4-BA3858804CEC { "FirstName": "Han", "Test1": "Solo" }

我试过了

insert into tmp.FullData (ParentId, Properties)
select distinct ParentId, '{}' from tmp.Properties

update f
set Properties = json_modify(Properties, 'append $.' + p.PropertyName, p.PropertyValue)
from tmp.FullData f
cross join tmp.Properties p

但如你所知/想象

Msg 13610, Level 16, State 2, Line 39
The argument 2 of the "JSON_MODIFY" must be a string literal.

还有其他选择吗?提前致谢

4

1 回答 1

0

跳过更新并直接插入 tmp.FullData:

INSERT INTO tmp.FullData (ParentId, Properties)
SELECT
    ParentId
    ,'{'
     + STUFF((
                 SELECT ',' + '"' + PropertyName + '":"' + PropertyValue + '"'
                 FROM tmp.Properties a
                 WHERE a.ParentId = p.ParentId
                 FOR XML PATH(''), TYPE
             ).value('.', 'VARCHAR(MAX)'), 1, 1, ''
            ) + '}' AS Properties
FROM tmp.Properties p
GROUP BY ParentId;
于 2017-11-29T01:31:25.717 回答