SSMS:OPENJSON可以使用,但不能直接进行REST调用

时间:2018-10-04 11:39:44

标签: json sql-server rest open-json

this article之后,我正在尝试实现一个查询,该查询可以从REST调用中检索数据并使用OPENJSON解析JSON。

我和邮递员打this URL来检查数据是否正常:

enter image description here

数据在那里。

我复制粘贴JSON,然后在SSMS上测试通话:

DECLARE @json nvarchar(max) = N'{
    "version": 0.6,
    "generator": "Overpass API 0.7.55.4 3079d8ea",
    "osm3s": {
        "timestamp_osm_base": "2018-10-04T10:07:02Z",
        "timestamp_areas_base": "2018-10-04T09:02:02Z",
        "copyright": "The data included in this document is from www.openstreetmap.org. The data is made available under ODbL."
    },
    "elements": [
        {
            "type": "node",
            "id": 501591237,
            "lat": 49.4943882,
            "lon": -117.2910343,
            "tags": {
                "amenity": "cinema",
                "name": "Civic Theatre",
                "website": "http://civictheatre.ca"
            }
        },
        {
            "type": "node",
            "id": 2293276829,
            "lat": -41.2709865,
            "lon": 173.2842196,
            "tags": {
                "amenity": "cinema",
                "name": "Cinema 6"
            }
        }
    ]
}';



SELECT * FROM OPENJSON(@json, N'$.elements')
WITH (   
      [type] nvarchar(max) N'$.type'   ,
      [id]   nvarchar(max) N'$.id',
      [lat]   nvarchar(max) N'$.lat',
      [lon]   nvarchar(max) N'$.lon',
      [amenity]   nvarchar(max) N'$.tags.amenity',
      [name]   nvarchar(max) N'$.tags.name'

)

一切正常,正在运行:我的查询可以解析JSON。

enter image description here

我现在遵循this guide的内容,向我展示如何在 SSMS内进行REST调用,我尝试检索相同URL的数据并实时将其查看到SSMS中:

Declare @Object as Int;
Declare @json as nvarchar(max);


Exec sp_OACreate 'MSXML2.XMLHTTP', @Object OUT;
Exec sp_OAMethod @Object, 'open', NULL, 'get',
                 'http://overpass-api.de/api/interpreter?data=[out:json];area[name=%22Nelson%22]-%3E.a;(node(area.a)[amenity=cinema];way(area.a)[amenity=cinema];rel(area.a)[amenity=cinema];);out;', --Your Web Service Url (invoked)
                 'false'
Exec sp_OAMethod @Object, 'send'
Exec sp_OAMethod @Object, 'responseText', @json OUTPUT

select @json

SELECT * FROM OPENJSON(@json, N'$.elements')
WITH (   
      [type] nvarchar(max) N'$.type'   ,
      [id]   nvarchar(max) N'$.id',
      [lat]   nvarchar(max) N'$.lat',
      [lon]   nvarchar(max) N'$.lon',
      [amenity]   nvarchar(max) N'$.tags.amenity',
      [name]   nvarchar(max) N'$.tags.name'

)

Exec sp_OADestroy @Object

太好了!不起作用!

enter image description here

为什么数据为空? Declare @json as nvarchar(max);正在上一个查询中。为什么不再工作?

如果我输入Declare @json as varchar(8000);,那么它的工作仅是因为我检索的字符数少于8000个,但我不能以这种方式工作。

enter image description here

如果我没记错的话,OPENJSON正是为了避免这种问题而开发的,并加载直到2GB的数据。

我想使用nvarchar(max)并加载大量数据。这是使用OPENJSON的全部要点。

1 个答案:

答案 0 :(得分:1)

完成。

非常感谢@PanagiotisKanavos提出status的建议,以发现错误。

解决方案是使用Declare @json as table(Json_Table nvarchar(max))并将JSON存储到表中而不是变量中。 现在可以存储2GB了!

Declare @Object as Int;
DECLARE @hr  int
Declare @json as table(Json_Table nvarchar(max))

Exec @hr=sp_OACreate 'MSXML2.ServerXMLHTTP.6.0', @Object OUT;
IF @hr <> 0 EXEC sp_OAGetErrorInfo @Object
Exec @hr=sp_OAMethod @Object, 'open', NULL, 'get',
                 'http://overpass-api.de/api/interpreter?data=[out:json];area[name="Auckland"]->.a;(node(area.a)[amenity=cinema];way(area.a)[amenity=cinema];rel(area.a)[amenity=cinema];);out;', --Your Web Service Url (invoked)
                 'false'
IF @hr <> 0 EXEC sp_OAGetErrorInfo @Object
Exec @hr=sp_OAMethod @Object, 'send'
IF @hr <> 0 EXEC sp_OAGetErrorInfo @Object
Exec @hr=sp_OAMethod @Object, 'responseText', @json OUTPUT
IF @hr <> 0 EXEC sp_OAGetErrorInfo @Object

INSERT into @json (Json_Table) exec sp_OAGetProperty @Object, 'responseText'

SELECT * FROM OPENJSON((select * from @json), N'$.elements')
WITH (   
      [type] nvarchar(max) N'$.type'   ,
      [id]   nvarchar(max) N'$.id',
      [lat]   nvarchar(max) N'$.lat',
      [lon]   nvarchar(max) N'$.lon',
      [amenity]   nvarchar(max) N'$.tags.amenity',
      [name]   nvarchar(max) N'$.tags.name'     
)
EXEC sp_OADestroy @Object

enter image description here

这是完成工作的正确方法吗?

不!我不应该使用sp_OAMethod,而应该使用SQLCLR,或者使用PythonPowerShellVB,{{1} }等...

但是,你知道,我也应该少喝啤酒,少买培根,但是... YOLO,不管用什么,只要做就可以。

由于这个,我现在可以创建一个存储过程,该存储过程进行REST调用并将数据自动保存到SQL Server中。我寻找了好几天的解决方案,终于找到了答案here

我希望这会有所帮助,我看到那里有数百人正在搜索此答复。