【问题标题】:SSIS to run SSRS Reports: works on local but "Network name could not be found" when run as agent job?SSIS 运行 SSRS 报告:在本地工作,但作为代理作业运行时“找不到网络名称”?
【发布时间】:2012-06-06 14:24:50
【问题描述】:

背景信息:我们运行了一些(目前 9 个)核心 SSRS 报告,这些报告参数化程度很高,但重要的是 StartDate、EndDate 和 Department。这些将在每日、每周、每月、每季度、每年和临时(交互式)基础上运行。自动报告将保存到 Sharepoint 中的特定文件夹中。

到目前为止我所做的:将所有报告都放入这样的表格中,这样他们就不会“等待”参数,而是使用相同的三个参数生成报告。因此可以只使用它们的 URL 来调用它们:

http://server/ReportServer?/Folder/Report1&Department=DEPT1&ContactFromDate=01/01/2012&ContactToDate=31/01/2012+23:59:59&rs:Command=Render&rs:Format=PDF

http://server/ReportServer?/Folder/Report5&Department=DEPT8&ContactFromDate=01/04/2012&ContactToDate=06/01/2012+23:59:59&rs:Command=Render&rs:Format=PDF

..等等。

大约有 20 个部门,需要 5 种报告类型中的每一种,因此设置订阅并不是一个真正的选择,而这正是 SSIS 的用武之地。

我创建了一个包,它基本上从 SQL 表中读取报告标题和部门,为每个部门/报告填充 ADO.Net 枚举器,然后运行嵌套的 For..Each 循环并尝试触发 WebRequest 并保存生成的 PDF 到共享点文件夹。这在我的开发人员 PC 上运行良好,但在 SQL Server 上作为作业运行时(通过 SQL Server 中设置的代理)失败并出现“找不到网络名称”错误。

这是我的 Visual Basic 代码:

//Microsoft SQL Server Integration Services Script Task
//Write scripts using Microsoft Visual Basic
//The ScriptMain class is the entry point of the Script Task.

Imports System
Imports System.Data
Imports System.Math
Imports Microsoft.SqlServer.Dts.Runtime
Imports System.ComponentModel
Imports System.Diagnostics


<System.AddIn.AddIn("ScriptMain", Version:="1.0", Publisher:="", Description:="")> _
<System.CLSCompliantAttribute(False)> Partial Public Class ScriptMain
Inherits Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase

Enum ScriptResults
    Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success
    Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
End Enum
Protected Sub SaveFile(ByVal url As String, ByVal localpath As String)
    Dim loRequest As System.Net.HttpWebRequest
    Dim loResponse As System.Net.HttpWebResponse
    Dim loResponseStream As System.IO.Stream
    Dim loFileStream As New System.IO.FileStream(localpath, System.IO.FileMode.Create, System.IO.FileAccess.Write)
    Dim laBytes(256) As Byte
    Dim liCount As Integer = 1
    Try

        loRequest = CType(System.Net.WebRequest.Create(url), System.Net.HttpWebRequest)
        loRequest.Credentials = System.Net.CredentialCache.DefaultCredentials
        loRequest.ImpersonationLevel = Security.Principal.TokenImpersonationLevel.Impersonation 
        loRequest.Timeout = 600000
        loRequest.Method = "GET"
        loResponse = CType(loRequest.GetResponse, System.Net.HttpWebResponse)
        loResponseStream = loResponse.GetResponseStream
        Do While liCount > 0
            liCount = loResponseStream.Read(laBytes, 0, 256)
            loFileStream.Write(laBytes, 0, liCount)
        Loop
        loFileStream.Flush()
        loFileStream.Close()
    Catch ex As Exception
    End Try
    System.Threading.Thread.Sleep(2000) 
End Sub

Public Sub Main()
    Dim strUrl, strUrlSP, strDestination As String

    --New destination for monthly
    strDestination = Dts.Variables("varDestinationPathSP").Value.ToString + "\" + Dts.Variables("varDepartmentName").Value.ToString + "\Monthly\" + Dts.Variables("varCrmReportTitles").Value.ToString + " " + Format(Now, "yyyyMM") + ".pdf"

    --New Url for Monthly reports.
    strUrl = "http://server/ReportServer?/Scheduled+Reporting/" + Dts.Variables("varCrmReportTitles").Value.ToString + "&Department=" + Dts.Variables("varDepartmentCode").Value.ToString + "&ContactFromDate=" + Format(Dts.Variables("varDatPreviousMonthStart").Value, "dd/MMM/yyyy").ToString + "&ContactToDate=" + Format(Dts.Variables("varDatPreviousMonthEnd").Value, "dd/MMM/yyyy").ToString + "+23:59:59&rs:Command=Render&rs:Format=PDF"
    strUrlSP = "http://intranet/ProjectBusinessSystems/ContactManagement/DocumentLibrary/Forms/AllItems.aspx?RootFolder=/ProjectBusinessSystems/ContactManagement/DocumentLibrary/Scheduled+Reports/" + Dts.Variables("varDepartmentName").Value.ToString + "/Monthly"

    strUrl = fnPadSpaces(strUrl)
    strUrlSP = fnPadSpaces(strUrlSP)

    --Set up the file path so the next step can copy to local drive (Testing purposes only)
    Dts.Variables("varFullReportPathToCopy").Value = strDestination
    Dts.Variables("varDestinationURL").Value = strUrlSP

    SaveFile(strUrl, strDestination)
    Dts.TaskResult = ScriptResults.Success

End Sub

Public Function fnPadSpaces(ByVal StringToEncode As String, Optional ByVal UsePlusRatherThanHexForSpace As Boolean = True) As String

    Dim TempAns As String
    Dim CurChr As Integer
    CurChr = 1
    TempAns = ""
    Do Until CurChr - 1 = Len(StringToEncode)
        Select Case Asc(Mid(StringToEncode, CurChr, 1))
            Case 32 -- Replace Spaces
                If UsePlusRatherThanHexForSpace = True Then
                    TempAns = TempAns & "+"
                Else
                    TempAns = TempAns & "%" & Hex(32)
                End If
            Case Else -- Otherwise pass it through
                TempAns = TempAns & Mid(StringToEncode, CurChr, 1)
        End Select

        CurChr = CurChr + 1
    Loop

    fnPadSpaces = TempAns
End Function
End Class

它在 SaveFile(strUrl, strDestination) 行上失败,当它生成 PDF 但未能将其写入共享点文件夹时。基础架构人员向我保证,权限已设置为允许运行 SSIS 作业的帐户写入文件夹,当我在开发盒上的 Vis Studio 中运行该作业时,它一直有效。

varDestinationPath 是这样的:

\\sharepoint\ProjectBusinessSystems\ContactManagement\DocumentLibrary\Some Reports

其中 sharepoint 是服务器名称,而不是别名。

来自日志文件查看器的实际(相当详细的)错误消息如下所示:

Date        06/06/2012 13:52:30
Log     Job History (Scheduled Reports MONTHLY)

Step ID     1
Server      DevServer
Job Name        Scheduled Reports MONTHLY
Step Name       Run Package
Duration        00:00:04
Sql Severity        0
Sql Message ID      0
Operator Emailed        
Operator Net sent       
Operator Paged      
Retries Attempted       0

Message
Executed as user: WinFarm\crmreporter. Microsoft (R) SQL Server Execute Package Utility     Version 10.50.2500.0 for 64-bit  Copyright (C) Microsoft Corporation 2010. All rights reserved.    Started:  13:52:31  Error: 2012-06-06 13:52:34.46     Code: 0x00000001     Source: Script Task - Render Report      Description: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.IO.IOException: The network name cannot be found.       at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)     at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy)     at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy)     at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access)     at ScriptTask_f689e2ad4d3f481a87e3678e2d746c39.vbproj.ScriptMain.SaveFile(String url, String localpath)     at ScriptTask_f689e2ad4d3f481a87e3678e2d746c39.vbproj.ScriptMain.Main()     --- End of inner exception stack trace ---     at System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)     at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)     at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)     at System.RuntimeType.InvokeMember(String name, BindingFlags bindingFlags, Binder binder, Object target, Object[] providedArgs, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParams)     at Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTATaskScriptingEngine.ExecuteScript()  End Error  DTExec: The package execution returned DTSER_FAILURE (1).  Started:  13:52:31  Finished: 13:52:34  Elapsed:  3.183 seconds.  The package execution failed.  The step failed.

任何想法我做错了什么或我应该尝试什么?如果我需要提供更多信息,请询问,我会回复。我确信脚本 99% 已完成,但在我认为的服务器上的某些凭据/权限问题上失败了。 :/

更新:我可以确认代码将写入本地区域 (C:\Temp),并且它还将写入网络共享上的文件夹(\someserver\some 文件夹中包含空格 \etc)所以问题是稍微转向写入共享点文件夹。我们在本机模式下运行 SSRS,所以有没有人知道从通过代理运行的 SQL Server 代理作业写入共享点文件夹时可能导致“找不到网络路径”错误的原因?

还尝试通过文件系统任务移动文件,但即使这样也失败了。 :( 任何想法可能是什么问题?

撞。可能在这里回答我自己的问题,但经过一些调查,我们发现查看 Sharepoint 的 Win2008 服务器没有运行 WebClient 服务。这意味着未安装 WebDAV,因此它无法将共享点库“视为”网络路径(或将驱动器映射到它).. 将安装这些组件并报告回来。但是,如果有人对此有更多信息,将不胜感激!分分钟有点像迷宫里的盲人。 :)

【问题讨论】:

  • 如果您将 sharepoint 排除在外,会发生什么?可以写入本地文件夹吗?
  • 嗨,Blinkx,我可以试试;如何引用本地文件夹?会是 \\localhost\c\temp 还是什么?我不确定是否在 SQL 服务器本身上设置了任何文件共享,并且我对服务器的访问非常有限,这没有多大帮助。 :(
  • 只是一个本地文件夹,如 C:\temp,只是代理帐户可以访问的东西,而不是网络共享或共享点。这有助于确定代理帐户与 SSRS 通信并保存文件输出期与 SharePoint 拒绝连接是否存在问题(这将导致我走上 Kerberos 地狱之路)
  • 对于它的价值,我可以确认提供的代码将与报告服务实例对话并将 PDF 保存到给定位置。这是我这周需要完成的任务。

标签: sql-server sharepoint ssis webdav unc


【解决方案1】:

您知道,也交付到 SharePoint,SSRS 必须配置为 SharePoint 集成模式。这与“标准”配置完全相反。

但这甚至不是重点。当我阅读您的方案时,我想到了订阅,然后您说它们不是一种选择。为什么?但更糟糕的是,您基本上想出了一个实现订阅功能的实现。您及时运行报告并将其保存到文件夹中。我一直这样做,订阅。

好的,我真的不知道你的全部情况,但这里有两件事非常重要:

1 - 用户可以处理非实时数据多长时间?我的意思是,你不期望这么大的报道(至少你让它们在你的描述中听起来真的很大)是“活的”。我很确定您可以将它们缓存几个小时。您的第一个用户会遇到延迟,但下一个用户将受益于之前的执行(只要他们具有相同的参数)

2 - 您可以创建订阅以预加载缓存。我建议您阅读here 中的Preloading the Cache 段落 如果您要缓存参数化报表的多个实例,其中使用不同的参数值来生成不同的报表实例,则此功能特别有用。 (看起来像你的情况)

【讨论】:

  • 您好 Diego,我们不使用订阅,因为我们不想保留多个报告副本,也不想为报告的所有变体设置所需的凭据。这是一场噩梦。 :) 他们在我开始之前确实尝试过,但最终得到了大量的订阅,称为 DEPT1_WEEKLY、DEPT4_MONTHLY 等。然后 DEPT20 出现了,这意味着再设置 5 个订阅。他们还遇到了与在引用子报告的报告中存储凭据有关的问题。因此,SSIS 方式是一种更巧妙的方式,并将订阅信息存储在 SQL 表中。无论如何,这就是理论。 :)
猜你喜欢
  • 2016-02-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多