2

通过 SSMS 调用 REST 服务确实不是一个好主意。

顺便说一句,自从微软创建了存储过程 sp_OAMethod甚至 Red Gate 的 Phil Factor向我们展示了如何使用它,我想试一试。

我想将 OpenStreetMap 中的一些数据直接导入 MSSQL,所以我从这里复制了一个很好的查询,并根据我的意愿对其进行了调整。

在此示例中,我将返回Nelson的所有电影院:

DECLARE @obj AS INT
DECLARE @Uri AS NVARCHAR(4000)
DECLARE @Response AS VARCHAR(8000)

SET @Uri = 'http://overpass-api.de/api/interpreter?data=area[name="Nelson"]->.a;(node(area.a)[amenity=cinema];way(area.a)[amenity=cinema];rel(area.a)[amenity=cinema];);out;'
EXEC sp_OACreate 'MSXML2.ServerXMLHttp.3.0', @obj OUT
EXEC sp_OAMethod @obj, 'open', NULL, 'GET', @Uri, false
EXEC sp_OAMethod @obj, 'send'
EXEC sp_OAGetProperty @obj, 'ResponseText', @Response OUTPUT

SELECT @Response [response] 
EXEC sp_OADestroy @obj

很好很简单,我可以在 Postman 和 SSMS 中看到 REST 调用响应:

在此处输入图像描述

当我尝试从奥克兰这样的大城市检索所有电影院时,问题就开始了:

DECLARE @obj AS INT
DECLARE @Uri AS NVARCHAR(4000)
DECLARE @Response AS VARCHAR(8000)

SET @Uri = 'http://overpass-api.de/api/interpreter?data=area[name="Auckland"]->.a;(node(area.a)[amenity=cinema];way(area.a)[amenity=cinema];rel(area.a)[amenity=cinema];);out;'
EXEC sp_OACreate 'MSXML2.ServerXMLHttp.3.0', @obj OUT
EXEC sp_OAMethod @obj, 'open', NULL, 'GET', @Uri, false
EXEC sp_OAMethod @obj, 'send'
EXEC sp_OAGetProperty @obj, 'ResponseText', @Response OUTPUT

SELECT @Response [response] 
EXEC sp_OADestroy @obj

REST 调用正在检索更多数据,而变量@Response AS VARCHAR(8000)无法保存所有数据:

在此处输入图像描述

当然,我尝试使用DECLARE @Response AS VARCHAR(MAX),但这也无济于事。

不应该VARCHAR(MAX)保存65,535 个字符2GB的数据吗?

我应该改用什么?

有没有办法拆分数据并稍后连接?

编辑:我想我越来越近了:我可以以这种方式使用 OPENJSON ,但我仍然不知道如何构造查询......任何帮助将不胜感激

4

2 回答 2

6

我为自己鼓掌。

我承认,这是一个噩梦般的解决方案,但它可以完成任务。解决方案是设置:

Declare @Response as table(Json_Table nvarchar(max))

这样,我创建了一个数据类型的表,nvarchar(max)现在是的,它可以容纳65,535 个字符,直到2GB的数据。

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

Exec @hr=sp_OACreate 'MSXML2.ServerXMLHTTP.6.0', @Object OUT;
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'
Exec @hr=sp_OAMethod @Object, 'send'
Exec @hr=sp_OAMethod @Object, 'responseText', @Response OUTPUT

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

select * from @Response

EXEC sp_OADestroy @Object

如果您找到更好的解决方案,请发布,将不胜感激。

于 2018-10-07T08:45:59.737 回答
1

错误代码:

DECLARE @str varchar(max)
SET @str = REPLICATE('A', 4000) + REPLICATE('B', 4000) + REPLICATE('C', 4000)
PRINT LEN(@str)

来自SQL Server文档中的 REPLICATE

如果 string_expression 不是 varchar(max) 或 nvarchar(max) 类型,则 REPLICATE 将返回值截断为 8,000 字节。要返回大于 8,000 字节的值,必须将 string_expression 显式转换为适当的大值数据类型。

正确代码:

DECLARE @str varchar(max)
DECLARE @seed varchar(max) = 'A'

SET @str = REPLICATE(@seed, 4000) + REPLICATE(@seed, 4000) + REPLICATE(@seed, 4000)
PRINT LEN(@str)

--12000

有关其他答案,请参阅For Nvarchar(Max) 我在 TSQL 中只得到 4000 个字符?

于 2018-10-03T06:41:49.223 回答