SSMS和sp_OAMethod:是否存在大于VARCHAR(8000)的数据类型?

时间:2018-10-01 09:50:56

标签: rest api ssms sqldatatypes varcharmax

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

顺便说一句,自从Microsoft创建了Stored Procedure sp_OAMethod甚至是Red Gate show us how to use it的Phil Factor以来,我都想尝试一下。

我想将一些数据从OpenStreetMap直接导入到MSSQL,因此我复制了一个很好的查询from here,并根据自己的意愿进行了调整。

在此示例中,我将返回 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呼叫响应:

enter image description here

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

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)无法保存所有数据:

enter image description here

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

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

我应该用什么代替?

有没有办法拆分数据并在以后进行连接?

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

2 个答案:

答案 0 :(得分:1)

错误代码:

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

来自REPLICATE in SQL Server文档

  

如果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) I am only getting 4000 characters in TSQL?

答案 1 :(得分:1)

我在拍拍自己的手。

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

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

通过这种方式,我创建了一个数据类型为nvarchar(max)的表,现在可以了,它可以容纳 65,535个字符,直到 2GB 。< / p>

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

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