【问题标题】:Extract values from an SQL column with JSON format从 JSON 格式的 SQL 列中提取值
【发布时间】:2021-07-25 15:27:01
【问题描述】:

我需要从具有 JSON 格式的列中提取值。 这是该列的表中的一个行的示例,这里有两个 operatorKey,但在其他行中可能会有更多:

{
"officeId": "office8685",
"TypeOfOffice": null,
"Telefonnummer": "",
"Operatorer": [
    {
        "OperatorKey": "1",
        "OperatorUserID": {
            "Agency": "Other",
            "AgencySpecified": true,
            "Value": "TM-Oper-1"
        },
        "ContactInformation": {
            "FirstName": "mike",
            "LastName": null,
            "Address": {
                "Street": null,
                "City": null,
                "Province": null,
                "Country": null
            },
            "Phone": null,
            "Fax": null,
            "Email": null, 
        }
    },
    {
        "OperatorKey": "4",
        "OperatorUserID": {
            "Agency": "Other",
            "AgencySpecified": true,
            "Value": "TM-Oper-4"
        },
        "ContactInformation": {
            "FirstName": "xxx",
            "LastName": null,
            "Address": {
                "Street": null,
                "City": null,
                "Province": null,
                "Country": null
            },
            "Phone": null,
            "Fax": null,
            "Email": null,
        }
    }       
]

}

这是我正在尝试读取 JSON 的 SQL 视图,我正在使用 openjsoncross apply 读取值:

Alter view  dbo.vOffice as 
select
      column1,column2
      --,column3 --this column contains values with json format
      ,OfficId,TypeOfOffice,Telefonnummer,Operatorer,OperatorKey,OperatorUserID                          
      ,ContactInformation,Agency,AgencySpecified,[Value],FirstName,LastName                              
      ,[Address],Phone, Fax, Email 
FROM [produktion_dim].[VirkesverdeStandardSCD1]
CROSS APPLY OPENJSON (column3,'$.OfficId') with (
OfficId varchar(4096)   '$.OfficId',TypeOfOffice varchar(4096)  '$.TypeOfOffice',
Telefonnummer varchar(4096) '$.Telefonnummer',Operatorer varchar(4096)  '$.Operatorer')
cross apply openjson(Operatorer, '$')  with(OperatorKey  varchar(4096)  '$.OperatorKey', OperatorUserID varchar(4096) '$.OperatorUserID', ContactInformation     varchar(4096)  '$.ContactInformation')
cross apply openjson(OperatorUserID,'$') with ( Agency varchar(4096) '$.Agency',
AgencySpecified varchar(4096) '$.AgencySpecified',[Value]                           varchar(4096)   '$.Value'   )
cross apply openjson( ContactInformation, '$') with (FirstName                              varchar(4096)   '$.FirstName',LastName varchar(4096)    '$.LastName',[Address] varchar(4096)    '$.Address',Phone   varchar(4096)   '$.Phone',Fax       varchar(4096)   '$.Fax',Email   varchar(4096)   '$.Email')
cross apply openjson([Address],'$') with ( Street varchar(4096) '$.Street',
City varchar(4096)  '$.City',Province varchar(4096) '$.Province',Country    varchar(4096) '$.Country')

但我遇到了错误。您能告诉我在 SQL 视图中缺少什么或应该更改什么吗?

【问题讨论】:

  • 请编辑您的问题以包含您收到的错误消息的完整和完整文本。
  • 这是您正在处理的实际 JSON 吗? SQL Server 不喜欢使用 "Email": null,} 等格式的 JSON - 尝试删除清理多余的逗号,例如 "Email": null}
  • @AlwaysLearning 这是错误消息:JSON 文本格式不正确。在位置 0 发现意外字符“1”。
  • 我无法更改;我们从其他组织获取数据作为 json 文件。
  • 我认为这里没有人可以帮助你。如果发送方只能发送 sorta-JSON,则 SQL Server 无法对其进行排序解析。您确实需要发送方发送格式正确的 JSON 数据。

标签: json sql-server sql-view cross-apply open-json


【解决方案1】:

一旦您可以组织发送方发送正确格式的 JSON 数据,这里有一些提示可以帮助您解析 JSON 数据:

  • openjson(something, '$') with (...) 中的'$' 是多余的,只需使用openjson(something) with (...)
  • JSON 路径查询区分大小写:$.officeId$. OfficeId 不同,两者都不会匹配 '$.OfficId'
  • with (...) 内部,当声明一个列将被另一个openjson() 调用使用时,它需要使用nvarchar(max) 类型并在其定义中包含as json,例如:OperatorUserID nvarchar(max) '$.OperatorUserID' as json

我已编辑您的查询以提取我认为您正在寻找的 JSON 数据...

create table dbo.VirkesverdeStandardSCD1 (
  column3 nvarchar(max)   
);

insert dbo.VirkesverdeStandardSCD1 (column3) values (N'{
    "officeId": "office8685",
    "TypeOfOffice": null,
    "Telefonnummer": "",
    "Operatorer": [
        {
            "OperatorKey": "1",
            "OperatorUserID": {
                "Agency": "Other",
                "AgencySpecified": true,
                "Value": "TM-Oper-1"
            },
            "ContactInformation": {
                "FirstName": "mike",
                "LastName": null,
                "Address": {
                    "Street": null,
                    "City": null,
                    "Province": null,
                    "Country": null
                },
                "Phone": null,
                "Fax": null,
                "Email": null
            }
        },
        {
            "OperatorKey": "4",
            "OperatorUserID": {
                "Agency": "Other",
                "AgencySpecified": true,
                "Value": "TM-Oper-4"
            },
            "ContactInformation": {
                "FirstName": "xxx",
                "LastName": null,
                "Address": {
                    "Street": null,
                    "City": null,
                    "Province": null,
                    "Country": null
                },
                "Phone": null,
                "Fax": null,
                "Email": null
            }
        }
    ]
}');

select
      --column1,column2
      --,column3 --this column contains values with json format
      OfficId,TypeOfOffice,Telefonnummer,Operatorer,OperatorKey,OperatorUserID                          
      ,ContactInformation,Agency,AgencySpecified,[Value],FirstName,LastName                              
      ,[Address],Phone, Fax, Email 
from dbo.VirkesverdeStandardSCD1
cross apply openjson(column3) with (
  OfficId varchar(4096)   '$.officeId',
  TypeOfOffice varchar(4096)  '$.TypeOfOffice',
  Telefonnummer varchar(4096) '$.Telefonnummer',
  Operatorer nvarchar(max) '$.Operatorer' as json
)
cross apply openjson(Operatorer) with (
  OperatorKey varchar(4096) '$.OperatorKey',
  OperatorUserID nvarchar(max) '$.OperatorUserID' as json,
  ContactInformation nvarchar(max) '$.ContactInformation' as json
)
cross apply openjson(OperatorUserID) with (
  Agency varchar(4096) '$.Agency',
  AgencySpecified varchar(4096) '$.AgencySpecified',
  [Value] varchar(4096) '$.Value'
)
cross apply openjson(ContactInformation) with (
  FirstName varchar(4096) '$.FirstName',
  LastName varchar(4096) '$.LastName',
  [Address] nvarchar(max) '$.Address' as json,
  Phone varchar(4096) '$.Phone',
  Fax varchar(4096) '$.Fax',
  Email varchar(4096) '$.Email'
)
cross apply openjson([Address]) with (
  Street varchar(4096) '$.Street',
  City varchar(4096) '$.City',
  Province varchar(4096) '$.Province',
  Country varchar(4096) '$.Country'
);

【讨论】:

  • 我按照建议更改了 SQL,但我不明白您答案的第一部分 'create table.....' 。已经有一个同名的表,从中创建了我的 SQL 视图。你能解释一下我如何使用/将这部分添加到表格中吗?这应该是原始表的一部分还是..?
  • @Florentina 查询的第一部分是为选择查询消费设置一个表和数据。您不需要它,因为您的数据库中已经有了架构和数据。对于可能想要回答这个问题的其他人来说,它确实存在 - 它应该在您问题中提供的代码中,参考:How to create a Minimal, Reproducible Example
猜你喜欢
  • 2019-07-29
  • 2023-04-02
  • 2021-09-16
  • 2022-11-19
  • 1970-01-01
  • 2021-06-08
  • 2022-11-11
  • 1970-01-01
  • 2018-11-21
相关资源
最近更新 更多