0

我正在尝试从公共 APE 获取一些 JSON 数据并将记录插入到我的 SQL Azure 数据库中。API 请求正在工作,JSON 节点中的转换为对象也是如此,但我无法缝合以获取OPENJSON()正确解析 json 数据对象的函数。我收到此错误:

RequestError:JSON 文本格式不正确。在位置 1 发现了意外的字符“o”。

从api获取的json数据为:

{ 
  "data":[{ 
    "from": "2021-09-22T23:00Z",
    "to": "2021-09-22T23:30Z",
    "intensity": {
      "forecast": 105,
      "actual": 91,
      "index": "low"
    }
  },
  { 
    "from": "2021-09-22T23:30Z",
    "to": "2021-09-23T00:00Z",
    "intensity": {
      "forecast": 92,
      "actual": 80,
      "index": "low"
    }
  },
  { 
    "from": "2021-09-23T22:00Z",
    "to": "2021-09-23T22:30Z",
    "intensity": {
      "forecast": 153,
      "actual": null, 
      "index": "low"
    }
  },
  { 
    "from": "2021-09-23T22:30Z",
    "to": "2021-09-23T23:00Z",
    "intensity": {
      "forecast": 150,
      "actual": null, 
      "index": "low"
    }
  }]
}

SQL Azure 节点具有以下代码:

DECLARE @data NVARCHAR(MAX) = N'{{{payload}}}';

INSERT INTO TCarbonIntensity ([from], [to], [forecast], [actual], [index])
    SELECT [from], [to], [forecast], [actual], [index]
    FROM OPENJSON(@data)
    WITH (
        [from] datetime '$.from',
        [to] datetime '$.to',
        [forecast] int '$.intensity.forecast',
        [actual] int '$.intensity.actual',
        [index] nvarchar(5) '$.intensity.index'
    );
4

1 回答 1

0

请尝试以下解决方案。

正如@AlwaysLearning 在评论中已经提到的那样,JSON 的日期时间值格式有问题。这就是为什么需要轻微按摩的原因。

另外,我使用DATETIMEOFFSET(3)数据类型来保留时区。

SQL

-- DDL and sample data population, start
DECLARE @tbl TABLE (ID INT IDENTITY PRIMARY KEY,
        [from] DATETIMEOFFSET(3),
        [to] DATETIMEOFFSET(3),
        [forecast] int,
        [actual] int,
        [index] nvarchar(5)
);
-- DDL and sample data population, end

DECLARE @data NVARCHAR(MAX) =
N'{
    "data": [
        {
            "from": "2021-09-22T23:00Z",
            "to": "2021-09-22T23:30Z",
            "intensity": {
                "forecast": 105,
                "actual": 91,
                "index": "low"
            }
        },
        {
            "from": "2021-09-22T23:30Z",
            "to": "2021-09-23T00:00Z",
            "intensity": {
                "forecast": 92,
                "actual": 80,
                "index": "low"
            }
        },
        {
            "from": "2021-09-23T22:00Z",
            "to": "2021-09-23T22:30Z",
            "intensity": {
                "forecast": 153,
                "actual": null,
                "index": "low"
            }
        },
        {
            "from": "2021-09-23T22:30Z",
            "to": "2021-09-23T23:00Z",
            "intensity": {
                "forecast": 150,
                "actual": null,
                "index": "low"
            }
        }
    ]
}';

INSERT INTO @tbl ([from], [to], [forecast], [actual], [index])
SELECT LEFT([from],16) + ':00Z', LEFT([to],16) + ':00Z', [forecast], [actual], [index]
FROM OPENJSON(@data, '$.data')
WITH (
    [from] VARCHAR(30) '$.from',
    [to] VARCHAR(30) '$.to',
    [forecast] int '$.intensity.forecast',
    [actual] int '$.intensity.actual',
    [index] nvarchar(5) '$.intensity.index'
);

-- test
SELECT * FROM @tbl;

输出

+----+--------------------------------+--------------------------------+----------+--------+-------+
| ID |              from              |               to               | forecast | actual | index |
+----+--------------------------------+--------------------------------+----------+--------+-------+
|  1 | 2021-09-22 23:00:00.000 +00:00 | 2021-09-22 23:30:00.000 +00:00 |      105 | 91     | low   |
|  2 | 2021-09-22 23:30:00.000 +00:00 | 2021-09-23 00:00:00.000 +00:00 |       92 | 80     | low   |
|  3 | 2021-09-23 22:00:00.000 +00:00 | 2021-09-23 22:30:00.000 +00:00 |      153 | NULL   | low   |
|  4 | 2021-09-23 22:30:00.000 +00:00 | 2021-09-23 23:00:00.000 +00:00 |      150 | NULL   | low   |
+----+--------------------------------+--------------------------------+----------+--------+-------+
于 2021-09-24T12:11:54.123 回答