【问题标题】:Parsing JSON from SQL Server从 SQL Server 解析 JSON
【发布时间】:2021-09-28 12:24:29
【问题描述】:

我有一个包含以下列的表,其中一列是 JSON blob。我不清楚如何将 JSON blob 解析为与其他列一起的一系列列。我知道有一个叫OPENJSON 的东西,但不知道如何将它应用到这个案例中。

ID  |   ORGANIZATION   |  DEVICE_TIME  |   DEVICE   |     DATA 
--------------------------------------------------------------------  
011        015             2021-07-20       015        (JSON COLUMN)
012        016             2021-08-20       016        (JSON COLUMN)

json 字符串示例如下,来自上面的DATA

{
    "device":   {
        "battery_level":    98,
        "rssi": -105,
        "boot_cnt": 5,
        "apn":  "teal",
        "ip_addr":  "10.176.30.171",
        "fw_ver":   "1.00",
        "modem_fw": "mfw_nrf9160_1.3.0",
        "imsi": "234500024531391",
        "imei": "352656101040510",
        "iccid":    "8901990000000534985"
    },
     "data":    {
       "Temperature":   77.563942718505871,
       "Humidity":  29.100597381591797,
       "pressure":  28.883883226248145,
       "air_quality":   37.067466735839844,
       "SoilMoisture":  0.42462845010615713,
       "Lat":   0,
       "Long":  0,
       "Alt":   0
    }
}

【问题讨论】:

  • OPENJSON 返回一个表(可能有多行)。你想要一个标量。你想要 JSON_VALUE。我会尽快发布答案。
  • 根据问题指南,请向我们展示您的尝试以及您遇到的问题。
  • 谢谢 Dale,看来我的问题因为没有正确说明不幸的事实而被否决。该问题已进一步解决,因此希望不会再被否决。

标签: sql json sql-server open-json


【解决方案1】:

openjson 返回一个表(可能有很多行,但不适合您的示例)。

要将某些内容放入列中,您需要一个标量。试试这个例子。是的,您需要明确列出列。

/* Create a sample table */
WITH MySampleTable
AS (
SELECT 1 as col1, 2 as col2, 'Hi There' as col3,
CAST('
{
    "device":   {
        "battery_level":    98,
        "rssi": -105,
        "boot_cnt": 5,
        "apn":  "teal",
        "ip_addr":  "10.176.30.171",
        "fw_ver":   "1.00",
        "modem_fw": "mfw_nrf9160_1.3.0",
        "imsi": "234500024531391",
        "imei": "352656101040510",
        "iccid":    "8901990000000534985"
    },
     "data":    {
       "Temperature":   77.563942718505871,
       "Humidity":  29.100597381591797,
       "pressure":  28.883883226248145,
       "air_quality":   37.067466735839844,
       "SoilMoisture":  0.42462845010615713,
       "Lat":   0,
       "Long":  0,
       "Alt":   0
    }
}
'
AS NVARCHAR(MAX)
) as myjsoncolumn
UNION ALL
SELECT 5,6,'Test','
{
    "device":   {
        "battery_level":    2,
        "rssi": -105,
        "boot_cnt": 5,
        "apn":  "teal"
    },
     "data":    {
       "Humidity":  29.100597381591797,
       "pressure":  28.883883226248145
    }
}
'
)

SELECT *, 
JSON_VALUE(myjsoncolumn,'$.device.battery_level') as battery_level,
JSON_VALUE(myjsoncolumn,'$.data.Temperature') as Temp
FROM MySampleTable

【讨论】:

  • 我如何指向一个表中的列,它有很多行 json 字符串?
  • 该示例适用于具有多行的表。我将对其进行编辑,但请注意,您可以自己尝试一下。
  • 我已编辑答案以从多行表中返回数据。
  • 太棒了。如果您对答案感到满意,请接受。
【解决方案2】:

该语句通常取决于解析的 JSON 数据的结构。在这种情况下,一个可能的选项是具有显式架构的OPENJSON()(带有列定义的WITH 子句),使用适当的数据类型和path 表达式:

JSON 和表格:

DECLARE @json varchar(max) = '{
    "device":   {
        "battery_level":    98,
        "rssi": -105,
        "boot_cnt": 5,
        "apn":  "teal",
        "ip_addr":  "10.176.30.171",
        "fw_ver":   "1.00",
        "modem_fw": "mfw_nrf9160_1.3.0",
        "imsi": "234500024531391",
        "imei": "352656101040510",
        "iccid":    "8901990000000534985"
    },
     "data":    {
       "Temperature":   77.563942718505871,
       "Humidity":  29.100597381591797,
       "pressure":  28.883883226248145,
       "air_quality":   37.067466735839844,
       "SoilMoisture":  0.42462845010615713,
       "Lat":   0,
       "Long":  0,
       "Alt":   0
    }
}'
SELECT *
INTO Data
FROM (VALUES
   ('011', '015', '2021-07-20', '015', @json),
   ('012', '016', '2021-08-20', '016', @json)
) v (ID, ORGANIZATION, DEVICE_TIME, DEVICE, DATA)

声明:

SELECT d.*, j.*
FROM Data d
OUTER APPLY OPENJSON(d.DATA) WITH (
   batery_level int '$.device.battery_level',
   rssi int '$.device.rssi',
   boot_cnt int '$.device.boot_cnt',
   apn varchar(10) '$.device.boot_apn',
   ip_addr varchar(19) '$.device.ip_addr',
   fw_ver varchar(5) '$.device.fw_ver',
   modem_fw varchar(59) '$.device.modem_fw',
   imsi varchar(15) '$.device.imsi',
   imei varchar(15) '$.device.imei',
   iccid varchar(50) '$.device.iccid',
   Temperature numeric(20, 15) '$.data.Temperature',
   Humidity numeric(22, 18) '$.data.Humidity',
   pressure numeric(22, 18) '$.data.pressure',
   air_quality numeric(22, 18) '$.data.air_quality',
   SoilMoisture numeric(22, 18) '$.data.SoilMoisture',
   Lat numeric(9, 6) '$.data.Lat',
   Long numeric(9, 6) '$.data.Long',
   Alt numeric(9, 6) '$.data.Alt'
) j

【讨论】:

  • @Danimov82 如果您认为这个或任何其他答案是您问题的最佳解决方案,您可以accept 它。只能接受一个答案。
猜你喜欢
  • 1970-01-01
  • 2019-08-02
  • 1970-01-01
  • 2018-04-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-29
  • 1970-01-01
相关资源
最近更新 更多