Sql server 如何避免sp_创建限制?
url中的XML长度为4210,当我将长度更改为3970时,Sql server 如何避免sp_创建限制?,sql-server,sql-server-2008,tsql,Sql Server,Sql Server 2008,Tsql,url中的XML长度为4210,当我将长度更改为3970时,@ResponseText返回NULL。sp_是否有限制400?如果是,如果可能避免?根据sqlservercentral.com上的说明,sp_OACreate限制为4000个字符 一种解决方法是将读取内容分成更小的“块”,然后在SQL中集中在一起。下面是来自上述链接的代码片段,尽管它从文件而不是通过HTTP读取XML,但可能会对您有所帮助: Declare @Object as Int; Declare @ResponseText
@ResponseText
返回NULL
。sp_是否有限制400?如果是,如果可能避免?根据sqlservercentral.com上的说明,sp_OACreate限制为4000个字符
一种解决方法是将读取内容分成更小的“块”,然后在SQL中集中在一起。下面是来自上述链接的代码片段,尽管它从文件而不是通过HTTP读取XML,但可能会对您有所帮助:
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
EXECUTE@hResult=sp_OACreate''Scripting.FileSystemObject'',@objFileSystem OUT
如果@hResult 0
开始
EXEC sp_OAGetErrorInfo@objFileSystem、@ErrorSource OUT、@ErrorDesc OUT
设置@ErrorFailPoint=''创建FSO''
后藤
返回
结束
设置@FileNameAndPath=@Path+''\''+@FileName
--读取文件
执行@hResult=sp_OAMethod@objFileSystem,'OpenTextFile',@objTextStream OUT,@FileNameAndPath,1,false,0——用于读取,格式化为ASCII
如果@hResult 0
开始
EXEC sp_OAGetErrorInfo@objFileSystem、@ErrorSource OUT、@ErrorDesc OUT
设置@ErrorFailPoint=''打开响应文件''
去摧毁
返回
结束
设置@ResponseText='''
而@hResult=0
开始
执行@hResult=sp_OAGetProperty@objTextStream、'AtEndOfStream',@YesOrNo输出
如果@hResult 0
开始
EXEC sp_OAGetErrorInfo@objTextStream、@ErrorSource OUT、@ErrorDesc OUT
设置@ErrorFailPoint=''检查AtEndOfStream''
去摧毁
返回
结束
如果@YesOrNo 0
打破
执行@hResult=sp_OAMethod@objTextStream,'Read',@Chunk OUTPUT,4000
如果@hResult 0
开始
EXEC sp_OAGetErrorInfo@objTextStream、@ErrorSource OUT、@ErrorDesc OUT
设置@ErrorFailPoint=''读取区块''
去摧毁
返回
结束
设置@ResponseText=@ResponseText+ISNULL(@Chunk,“”)
结束
执行@hResult=sp_OAMethod@objTextStream,“关闭”
如果@hResult 0
开始
EXEC sp_OAGetErrorInfo@objTextStream、@ErrorSource OUT、@ErrorDesc OUT
设置@ErrorFailPoint=''关闭响应文件''
去摧毁
返回
结束
--记录响应信息
设置@ResponseXml=CAST(@ResponseText为XML)
销毁:
执行sp_OADestroy@objTextStream
财政司司长:
EXEC sp_OADestroy@objFileSystem
尽管你的帖子主题不同,但我认为问题可能出在sp_-OAMethod上,而不是sp_-OACreate本身
此外,应该不惜一切代价避免使用sql代码访问web,但这只是我的观点,因为我不喜欢使用RDBMS“网上冲浪”的想法^^
为了避免sp_方法的局限性,您可以尝试详细说明当前的答案
您的代码应该是这样的:
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
解决方案需要一个具有适当结构和数据类型的临时表来存储远程页面生成的值,这应该允许您获取超过4k的数据。这就是我用来克服此限制的方法。我使用它进行RESTful api通信。我可以接收varchar(最大值),但仍然受到可以发送的数据量的限制。这可能会让你到达你需要的地方。前5个变量是我用于存储过程的参数
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
我使用以下查询来解决这个问题。问题可能不是sp_OACreate或sp_OAMethod,而是返回@ResponseText的方法。将数据插入表变量而不是使用“@ResponseText-OUTPUT”是关键。注意,我将@Response更改为VARCHAR(MAX) 我的查询突然返回null,没有任何更改。将
'MSXML2.XMLHttp'
更改为'MSXML2.ServerXMLHTTP'
后,它又开始工作了。要了解这两者之间的区别,请参阅此和Microsoft
使用nvarchar(max)也返回null如何使用
varbinary(max)
?据我所知,sp_OACreate not recognize(max)和varbinary(max)的响应中也有null mm,可能是从sp_OAMethod
返回的字节数有限制。请您尝试最后一件事:将@ResponseText声明为xml
,xml也为空,可能有任何编码会占用1个字节吗?我可以将utf-8更改为任何编码为什么要使用ActiveX从站点读取数据?在ETL作业中使用SSI更容易、更快、可扩展、更安全,这正是您在这里要做的。T-SQL确实不是调用web服务的合适地方。如果您确实必须这样做,至少在.NET中编写一个UDF来实现这一点。SSI包括XML
和Web服务
任务。避免这些限制的最佳方法是避免像瘟疫一样的sp_OA过程。在2000年之后的所有版本的sql server中,有许多更好的方法可以这样做。@SeanLange您能给我举个例子吗?在CLR过程或SSIS包中,这样做会更好。这看起来像是1998年的。我的意思是sp_OACreate击中cgi bin不是我很久以前见过的事情了。@SeanLange我从来没有使用过CLR过程,你能举个例子说明如何使用CLR从url获取xml吗?@Object、@Result、@Obj
是varchar(8000)类型吗?那么“YourPropertyName”呢?我应该在那里写些什么来获取url的xml?如果您在SQL Server代理作业中使用它,请记住。完成此任务的另一种方法是使用SSIS包导入web api返回的纯csv文件。
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
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