Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 如何避免sp_创建限制?_Sql Server_Sql Server 2008_Tsql - Fatal编程技术网

Sql server 如何避免sp_创建限制?

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

url中的XML长度为4210,当我将长度更改为3970时,
@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