Declare @Object as Int;
Declare @ResponseText as Varchar(8000);
Declare @Url as Varchar(MAX);
set @Url = 'http://mysite.ru/cgi-bin/my_xml.cgi'
Exec sp_OACreate 'MSXML2.XMLHTTP', @Object OUT;
Exec sp_OAMethod @Object, 'open', NULL, 'get', @Url, 'false'
Exec sp_OAMethod @Object, 'send'
Exec sp_OAMethod @Object, 'responseText', @ResponseText OUTPUT
Exec sp_OADestroy @Object
SELECT @ResponseText
网址中的XML长度为4210,@ResponseText
返回NULL
,当我将长度更改为3970时@ResponseText
会返回数据。 sp_OACreate是否限制400?如果可以,可以避免吗?
答案 0 :(得分:2)
尽管您的帖子的主题我认为问题可能是sp_OAMethod而不是sp_OACreate本身。
也应该不惜一切代价避免从sql代码访问网站的恕我直言,但这只是我的意见,因为我不喜欢有RDBMS浏览网页的想法。 ^^
为了规避sp_OAMethod的限制,您可以尝试详细说明msdn上的答案。
你的代码应该是这样的:
Declare @Object as Int;
Declare @ResponseText as Varchar(8000);
Declare @Url as Varchar(MAX);
set @Url = 'http://mysite.ru/cgi-bin/my_xml.cgi'
Exec sp_OACreate 'MSXML2.XMLHTTP', @Object OUT;
Exec sp_OAMethod @Object, 'open', NULL, 'get', @Url, 'false'
Exec sp_OAMethod @Object, 'send'
--Exec sp_OAMethod @Object, 'responseText', @ResponseText OUTPUT
INSERT #temptable ( appropriatefield )
EXEC @Result = sp_OAGetProperty @Obj, 'YourPropertyName'
Exec sp_OADestroy @Object
解决方案需要一个具有适当结构和数据类型的临时表来存储远程页面生成的值,这样可以获得超过4k的数据。
答案 1 :(得分:1)
根据sqlservercentral.com上的this thread,sp_OACreate限制为4000个字符。
解决方法是将读取拆分为较小的“块”,然后在SQL中将它们连接在一起。以下是上述链接中的代码段,虽然它从文件而不是通过HTTP读取XML,但它可能对您有所帮助:
EXECUTE @hResult = sp_OACreate ''Scripting.FileSystemObject'' , @objFileSystem OUT
IF @hResult <> 0
BEGIN
EXEC sp_OAGetErrorInfo @objFileSystem, @ErrorSource OUT, @ErrorDesc OUT
SET @ErrorFailPoint = ''Creating FSO''
GOTO DestroyFSO
RETURN
END
SET @FileNameAndPath = @Path + ''\'' + @FileName
-- Read file
EXECUTE @hResult = sp_OAMethod @objFileSystem, ''OpenTextFile'', @objTextStream OUT, @FileNameAndPath, 1, false, 0--for reading, FormatASCII
IF @hResult <> 0
BEGIN
EXEC sp_OAGetErrorInfo @objFileSystem, @ErrorSource OUT, @ErrorDesc OUT
SET @ErrorFailPoint = ''Opening Reponse File''
GOTO Destroy
RETURN
END
SET @ResponseText = ''''
WHILE @hResult = 0
BEGIN
EXECUTE @hResult = sp_OAGetProperty @objTextStream, ''AtEndOfStream'', @YesOrNo OUTPUT
IF @hResult <> 0
BEGIN
EXEC sp_OAGetErrorInfo @objTextStream, @ErrorSource OUT, @ErrorDesc OUT
SET @ErrorFailPoint = ''Checking AtEndOfStream''
GOTO Destroy
RETURN
END
IF @YesOrNo <> 0
BREAK
EXECUTE @hResult = sp_OAMethod @objTextStream, ''Read'', @Chunk OUTPUT, 4000
IF @hResult <> 0
BEGIN
EXEC sp_OAGetErrorInfo @objTextStream, @ErrorSource OUT, @ErrorDesc OUT
SET @ErrorFailPoint = ''Reading Chunk''
GOTO Destroy
RETURN
END
SET @ResponseText = @ResponseText + ISNULL(@Chunk, '''')
END
EXECUTE @hResult = sp_OAMethod @objTextStream, ''Close''
IF @hResult <> 0
BEGIN
EXEC sp_OAGetErrorInfo @objTextStream, @ErrorSource OUT, @ErrorDesc OUT
SET @ErrorFailPoint = ''Closing Response File''
GOTO Destroy
RETURN
END
-- Record response info
SET @ResponseXml = CAST(@ResponseText AS XML)
Destroy:
EXEC sp_OADestroy @objTextStream
DestroyFSO:
EXEC sp_OADestroy @objFileSystem
答案 2 :(得分:1)
这是我用来克服限制的。我用它来进行RESTful api通信。我可以收到varchar(max)但仍然限制我可以发送的数据量。这可能会让你到达你需要的地方。前5个变量是我用于sproc的参数。
Declare @url as varchar(1024)
Declare @connection_type as varchar(6)='GET' --POST, PUT, GET DELETE
Declare @post_string as varchar(max)=null
Declare @response_text as Varchar(max)
Declare @content_type varchar(254)='application/json'
Declare @oa_object as Int;
Declare @err_code as Int
Declare @result_table Table (xml_result varchar(max))
Select @post_string=dbo.fn_regex_replace('([ ]{2,10})|\r|\n', @post_string,'') --remove carriage returns and multiple spaces
Exec @err_code=sp_OACreate 'MSXML2.ServerXMLHTTP.3.0', @oa_object OUT;
If @err_code<>0
Set @response_text=dbo.fn_oa_error_message(@oa_object)
Else
Begin
Exec @err_code=sp_OAMethod @oa_object, 'open', NULL, @connection_type, @url,'false','d0b1a0aaed2a529356471de4fe99cae2','8e7aa1a91fa68d06cd027914d3aa1140'
If @err_code<>0
Set @response_text='Open '+dbo.fn_oa_error_message(@oa_object)
Else
Begin
Exec @err_code=sp_OAMethod @oa_object, 'setRequestHeader', NULL, 'User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)'
If @err_code<>0
Set @response_text='setRequestHeader:User-Agent '+dbo.fn_oa_error_message(@oa_object)
Else
Begin
Exec @err_code=sp_OAMethod @oa_object, 'setRequestHeader', NULL, 'Content-Type', @content_type
If @err_code<>0
Set @response_text='setRequestHeader:Content-Type '+dbo.fn_oa_error_message(@oa_object)
Else
Begin
Exec @err_code=sp_OAMethod @oa_object, 'send', Null, @post_string
If @err_code<>0
Set @response_text='Send '+dbo.fn_oa_error_message(@oa_object)
Else
Begin
Set @response_text=null--make sure we don't return garbage
INSERT @result_table (xml_result)
Exec @err_code = sp_OAGetProperty @oa_object, 'responseText'
If @err_code<>0
Set @response_text='responseText '+dbo.fn_oa_error_message(@oa_object)
Else
SELECT @response_text=xml_result FROM @result_table
End
End
End
End
End
Exec sp_OADestroy @oa_object
虽然您不需要它,但错误处理程序如下所示。它有助于排除故障。
CREATE FUNCTION
dbo.n_oa_error_message(@oa_object int)
RETURNS varchar(max)
AS
BEGIN
Declare @source varchar(255)
Declare @description varchar(255)
exec sp_OAGetErrorInfo @oa_object, @source OUT, @description OUT
return 'Error: '+IsNull(@description,'no description')
END
答案 3 :(得分:1)
我使用以下查询来解决此问题。问题可能不是sp_OACreate或sp_OAMethod,而是返回@ResponseText的方法。将数据插入表变量而不是使用“@ResponseText OUTPUT”是关键。请注意,我将@Response更改为VARCHAR(MAX)。
DECLARE @TABLEVAR TABLE (responseXml VARCHAR(MAX))
DECLARE @URL VARCHAR(200)
SELECT @URL = 'http://mysite/php-start/callxml.php'
DECLARE @Response NVARCHAR(MAX)
DECLARE @Xml XML
DECLARE @Obj INT
DECLARE @Result INT
EXEC @Result = sp_OACreate 'MSXML2.XMLHttp', @Obj OUT
EXEC @Result = sp_OAMethod @Obj, 'open', NULL, 'GET', @URL, false
EXEC @Result = sp_OAMethod @Obj, 'setRequestHeader', NULL, 'Content-Type', 'application/x-www-form-urlencoded'
EXEC @Result = sp_OAMethod @Obj, SEND, NULL, ''
INSERT INTO @TABLEVAR
EXEC @Result = sp_OAGetProperty @Obj, 'responseXML.xml'--, @Response OUT
EXEC sp_OADestroy @Obj
SELECT @Response = responseXml FROM @TABLEVAR
SELECT @Xml = CONVERT(XML, @Response, 2)
DECLARE @handle INT
EXEC sp_xml_preparedocument @handle OUTPUT, @Xml
SELECT *
FROM OPENXML(@handle, '/data/record', 2)
WITH [dbo].[tblDialogTechTemp]
EXEC sp_xml_removedocument @handle
我的查询突然返回null而不更改任何内容。将
'MSXML2.XMLHttp'
更改为'MSXML2.ServerXMLHTTP'
后,它又开始运作了。要详细了解这两者之间的区别,请参阅此article和Microsoft documentation。