当 JSON 为 NULL 时,使用动态 SQL 获取 JSON 属性作为列的问题
Issue with dynamic SQL to get JSON properties as columns when JSON is NULL
我正在尝试 select JSON 属性作为列。需要 selected 的属性存储在其他一些 table
CREATE TABLE [Templates](
[ID] [int] NOT NULL,
[Template] [nvarchar](max)
)
INSERT INTO Templates(ID,Template)
VALUES
(1,'{"FirstName":"foo"}'),
(2,'{"FirstName":"joe","LastName":"dow"}'),
(3,'{"LastName":"smith","Address":"1234 Test Drive"}'),
(4,NULL)
Declare @SQL NVARCHAR(max)
--For brevity purpose i am hardcoding these property names. In reality column names will come from another table
DECLARE @properties NVARCHAR(max) = '[Address],[FirstName],[LastName]'
Set @SQL = '
Select '+ @properties +'
From (
Select T.ID
,j.[Key]
,j.[Value]
From Templates T
Cross Apply OpenJSON(T.Template) AS j
) src
Pivot ( max(value) for [Key] in ('+ @properties +') ) pvt
'
Exec(@SQL)
除了最后一行 Template
为 NULL 之外,上面的代码大部分都有效。 (ID = 4)
预期:查询应 return 4 行,对于最后一行,除 ID 外的所有列都应为空。
CROSS APPLY
需要返回行,但是,Cross Apply OpenJSON(NULL) AS j
returns 没有行。使用 OUTER APPLY
:
' ...
OUTER APPLY OpenJSON(T.Template) AS j
...'
EXEC sp_executesql @SQL;
注意我也使用 sp_executesql
因为你不能参数化 EXEC (@SQL)
我正在尝试 select JSON 属性作为列。需要 selected 的属性存储在其他一些 table
CREATE TABLE [Templates](
[ID] [int] NOT NULL,
[Template] [nvarchar](max)
)
INSERT INTO Templates(ID,Template)
VALUES
(1,'{"FirstName":"foo"}'),
(2,'{"FirstName":"joe","LastName":"dow"}'),
(3,'{"LastName":"smith","Address":"1234 Test Drive"}'),
(4,NULL)
Declare @SQL NVARCHAR(max)
--For brevity purpose i am hardcoding these property names. In reality column names will come from another table
DECLARE @properties NVARCHAR(max) = '[Address],[FirstName],[LastName]'
Set @SQL = '
Select '+ @properties +'
From (
Select T.ID
,j.[Key]
,j.[Value]
From Templates T
Cross Apply OpenJSON(T.Template) AS j
) src
Pivot ( max(value) for [Key] in ('+ @properties +') ) pvt
'
Exec(@SQL)
除了最后一行 Template
为 NULL 之外,上面的代码大部分都有效。 (ID = 4)
预期:查询应 return 4 行,对于最后一行,除 ID 外的所有列都应为空。
CROSS APPLY
需要返回行,但是,Cross Apply OpenJSON(NULL) AS j
returns 没有行。使用 OUTER APPLY
:
' ...
OUTER APPLY OpenJSON(T.Template) AS j
...'
EXEC sp_executesql @SQL;
注意我也使用 sp_executesql
因为你不能参数化 EXEC (@SQL)