通过作业

时间:2016-08-03 09:35:10

标签: sql-server stored-procedures sql-server-2014

主题:

我每个月都会收到一份报告。报告的创建包括两个步骤:

  1. 从我们的服务中获取XML并将其存储在DB中;
  2. 解析XML并创建文件。
  3. 过去几个月,我在手动模式下创建了报告。现在我想自动化这些东西。 但是这里有一个

    问题:

    第二步(解析XML和文件创建)像魅力一样运行,但第一步我观察到奇怪的行为。

    我得到了存储过程,它获取了XML:

    ALTER PROCEDURE [Structure].[GetXML]
        @LastActDate date,
        @CurActDate date
    AS
    BEGIN
        SET NOCOUNT ON;
    
        begining:
    
        DECLARE @URI varchar(2000),
                @methodName varchar(50),
                @objectID int,
                @hResult int,
                @setTimeouts nvarchar(255),
                @serv nvarchar(255) = 'http://example.com/docs/',
                @result nvarchar(max) = ''
    
        DECLARE @t TABLE(Resp nvarchar(max))
    
        declare @timeStamp nvarchar(50) = convert(nvarchar(50),CURRENT_TIMESTAMP,127)
    
        declare @CurDate date = dateadd(day,0,getdate())
    
        --EXEC @hResult = sp_OACreate 'WinHttp.WinHttpRequest.5.1', @objectID OUT
        EXEC @hResult = sp_OACreate 'MSXML2.XMLHTTP', @ObjectID OUT
    
        SELECT  @URI = @serv + '.newchange?ds='+CONVERT(nvarchar(10),@LastActDate,104)+'&df='+CONVERT(nvarchar(10),@CurActDate,104)+'&pardaily=1',
                @methodName='GET',
                @setTimeouts = 'setTimeouts(9000,90000,900000,9000000)' 
    
        EXEC @hResult = sp_OAMethod @objectID, 'open', null, @methodName, @URI, 'false' 
        EXEC @hResult = sp_OAMethod @objectID, @setTimeouts
        EXEC @hResult = sp_OAMethod @objectID, 'send', null 
    
        INSERT INTO @t
        EXEC sp_OAGetProperty @objectID, 'responseText'
    
        SELECT top 1 @result = Resp 
        FROM @t
    
        if @result is null
        begin
            delete from @t
            exec sp_OAGetErrorInfo @objectID
            exec sp_OADestroy @objectID 
            goto begining
        end
        else
        begin
            INSERT INTO Structure.MonthlyRow 
            SELECT @timeStamp, @result 
        end
    END
    

    当我运行此SP时

    EXEC [Structure].[GetXML] '2016-06-01', '2016-07-01'
    

    我在Structure.MonthlyRow表中排了一行,其中timestampresponse正确(平均长度约为70k符号)

    这是表的创建脚本:

    CREATE TABLE Structure.MonthlyRow(
        [timestamp] nvarchar(50) NOT NULL,
        [RowResp] nvarchar(max) NULL,
     CONSTRAINT [PK_dDayly] PRIMARY KEY CLUSTERED ([timestamp] DESC)) 
    

    如果我创建了一个启动此SP的作业,我会在表格中得到一行结果,结果的长度为 512符号!它是XML的一个适当部分,看起来像是从nvarchar(max)截断到nvarchar(512),但我没有使用长度为512的变量或表列。

    我尝试了什么:

    1. 使用我的帐户在“作业步骤”属性中以身份运行;
    2. 作业按计划或手动启动;
    3. 在SP中添加WITH EXECUTE AS OWNER;
    4. 尝试使用WinHttp.WinHttpRequest.5.1MSXML2.XMLHTTP
    5. 问题:

      可能出现什么问题?为什么我在手动运行SP时获得正确的结果,并且在将SP作为作业步骤运行时仅得到512个响应符号?

      注意:

      是的,我知道从PHP服务中获取XML更好地由PHP,C#甚至PowerShell处理,如果我找不到解决方案,我将使用其中一种。

1 个答案:

答案 0 :(得分:2)

在sp的顶部或sp

String html = "<div class=\"ExternalClass00BD08C9929B4EE8A7A9A6E9CA27A68C\"><p>\u200bTesting by Android<a href=\"/sites/Android/Shared%20Documents/1.txt\">1.txt</a><a href=\"/sites/Android/Shared%20Documents/2.txt\">2.txt</a><br></p></div>"; String title = html.substring(html.indexOf("<p>") + 3, html.indexOf("<a")); String[] splitHtml = html.split("<a"); for(int i = 0; i < splitHtml.length; i++) { if(splitHtml[i].contains("href=")) { String[] hrefSplit = splitHtml[i].split("\""); String url = hrefSplit[1]; String fileName = hrefSplit[2].substring(hrefSplit[2].indexOf(">")+1,hrefSplit[2].indexOf("<")); } } 之前的作业中添加此行
EXEC

问题是作业设置了默认

SET TEXTSIZE 2147483647;

这限制了返回1024个字符的数据( n 字符为512)