【问题标题】:How to query Json into SQL Server如何将 Json 查询到 SQL Server
【发布时间】:2023-03-10 16:14:02
【问题描述】:

我有问题。我想将一个 JSON 字符串填充到一个表中,但是,它只写给我第一行而不是其余的。我从一个 REST API 获取 JSON。

以下是我的代码和 JSON 文件的摘录

DECLARE @token INT;
DECLARE @ret INT;

DECLARE @url nvarchar(max);
DECLARE @Json2 nvarchar(max);
DECLARE @authheader nvarchar(max);
DECLARE @contentType nvarchar(max);

DECLARE @apiKey_lat nvarchar(max);
DECLARE @apiKey_lot nvarchar(max);
DECLARE @apiKey_start nvarchar(max);
DECLARE @apiKey_end nvarchar(max);

DECLARE @apikey nvarchar(max);


DECLARE @json AS TABLE (Json_Table nvarchar(max))
 

SET @authheader = ''
SET @contentType = 'application/json'




SET @url = ''

EXEC @ret = sp_OACreate 'MSXML2.XMLHTTP', @token OUT;
IF @ret <> 0 RAISERROR ('Unable to open HTTP Connection', 10, 1);


EXEC @ret = sp_OAMethod @token, 'open', NULL, 'GET', @url, 'false';
EXEC @ret = sp_OAMethod @token, 'setRequestHeader', NULL, 'authorization', @authheader;
EXEC @ret = sp_OAMethod @token, 'setRequestHeader', NULL, 'Content-type', @contentType;
EXEC @ret = sp_OAMethod @token, 'send'

EXEC sp_OAGetProperty @token, 'responseText', @Json2 OUTPUT;



INSERT INTO @json (Json_Table) EXEC sp_OAGetProperty @token, 'responseText'

SELECT * FROM @json

SELECT * FROM OPENJSON((SELECT * FROM @json))


WITH (
    [parameter] NVARCHAR(MAX) '$.parameter',
    [lat] NVARCHAR(MAX) '$.lat',
    [lon] NVARCHAR(MAX) '$.lon',
    [dates] NVARCHAR(MAX) '$.date',
    [value] NVARCHAR(MAX) '$.value'
) AS MetaData

这是 JSON 片段:

{"data": [
            {
                "parameter": "t_2m:C",
                "coordinates": [
                    {
                        "lat": 51.123456,
                        "lon": -0.123456,
                        "dates": [
                            {
                                "date": "2021-11-17T12:05:00Z",
                                "value": 10.6
                            },
                            {
                                "date": "2021-11-17T13:05:00Z",
                                "value": 11.4
                            }
                        ]
                    }
                ]
            }
        ]
}

我的输出如下所示:

结果应该是一个表格,其中包含来自 JSON 的 LAT、LON、DATE 和 VALUE 值。

这是一个例子:

enter image description here

编辑: 我也对 Cross Apply 感到厌烦。没用。看起来像这样:

CROSS_APPLY

这是带有交叉应用的代码:

DECLARE @token INT;
DECLARE @ret INT;

DECLARE @url nvarchar(max);
DECLARE @Json2 nvarchar(max);
DECLARE @authheader nvarchar(max);
DECLARE @contentType nvarchar(max);

--Set Parameters
DECLARE @apiKey_lat nvarchar(max);
DECLARE @apiKey_lot nvarchar(max);
DECLARE @apiKey_start nvarchar(max);
DECLARE @apiKey_end nvarchar(max);

DECLARE @apikey nvarchar(max);


DECLARE @json AS TABLE (Json_Table nvarchar(max))

--Set Authentications 

SET @authheader = ''
SET @contentType = 'application/json'




SET @url = ''


EXEC @ret = sp_OACreate 'MSXML2.XMLHTTP', @token OUT;
IF @ret <> 0 RAISERROR ('Unable to open HTTP Connection', 10, 1);

EXEC @ret = sp_OAMethod @token, 'open', NULL, 'GET', @url, 'false';
EXEC @ret = sp_OAMethod @token, 'setRequestHeader', NULL, 'authorization', @authheader;
EXEC @ret = sp_OAMethod @token, 'setRequestHeader', NULL, 'Content-type', @contentType;
EXEC @ret = sp_OAMethod @token, 'send'

EXEC sp_OAGetProperty @token, 'responseText', @Json2 OUTPUT;



INSERT INTO @json (Json_Table) EXEC sp_OAGetProperty @token, 'responseText'

SELECT * FROM @json

SELECT * FROM OPENJSON((SELECT * FROM @json))


WITH (
        [data] NVARCHAR(MAX) AS JSON
) AS MetaData



CROSS APPLY OPENJSON([MetaData].[data])
WITH(
    [parameter] NVARCHAR(MAX),
    [coordinates] NVARCHAR(MAX),
    [lat] NVARCHAR(MAX),
    [lon] NVARCHAR(MAX),
    [dates] NVARCHAR(MAX),
    [value] NVARCHAR(MAX)
) AS Test_Metadata

在 SQL 查询中,缺少其余 API 的 URL 和 Authorization 标头。

【问题讨论】:

  • 你为什么要使用那些古老的OA对象?您在这里实际追求的结果是什么?
  • 另外,您提供的 JSON 无效。您有未关闭的节点和数组。是否应该假设他们是真正的 JSON 也未完成?
  • Stack Overflow 是一个英文网站。内容必须是英文的。这包括 cmets。
  • 我不知道除了 OA 对象还有其他方法。 .结果应该是您有一列用于参数以及纬度和经度以及日期。 JSON 已完成。我这里只复制了一部分。这样就可以看到所有列相关数据。
  • 因此,对于您提供的示例数据(您应该使其有效),您的预期结果是什么。在问题中包括,。至于 OA 对象,它们甚至没有在documentation 中讨论过,所以我不确定您在在哪里阅读它们需要使用它们。这些对象更多是为了与 2000 年代中期的数据库兼容。

标签: sql json sql-server rest


【解决方案1】:

您不应该使用sp_OA 过程,因为它们充满了错误,难以使用,而且只是为了兼容。 SQL Server 不是一种通用的脚本语言,不要这样使用它。

而是使用类似 Powershell 的 Invoke-WebRequest 来下载数据,然后使用 Invoke-SqlCmdInvoke-DbaQuery 将其输入 SQL Server。

如果您将其作为参数@json 传入,您可以执行以下操作以获得您想要的结果:

SELECT
  d.parameter,
  coord.lat,
  coord.lon,
  dates.date,
  dates.value
FROM OPENJSON(@json, '$.data[0]')
  WITH (
    parameter nvarchar(100),
    coordinates nvarchar(max) AS JSON
  ) d
CROSS APPLY OPENJSON(d.coordinates)
  WITH (
    lat decimal(9,7),
    lon decimal(9,7),
    dates nvarchar(max) AS JSON
  ) coord
CROSS APPLY OPENJSON(coord.dates)
  WITH (
    date datetimeoffset,
    value decimal(18,2)
  ) dates;

db<>fiddle

注意coordinatesdates 是如何声明为AS JSON,然后再次使用CROSS APPLY 传递给OPENJSON

【讨论】:

  • 我还有一个问题,如何在表格中包含“参数”:“t_2m:C”?
  • 你需要第三个OPENJSON,已经修改
  • @Joo,如果答案对您有用,那么您应该接受它。所以将来有人可以使用它。
猜你喜欢
  • 2020-01-19
  • 2020-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-22
  • 1970-01-01
  • 2016-03-28
  • 2021-10-18
相关资源
最近更新 更多