Вопрос

Мне нужно создать повторяемый процесс развертывания отчетов служб отчетов SQL Server.Я не сторонник использования для этого Visual Studio или Business Development Studio.Метод сценария развертывания rs.exe также кажется довольно неуклюжим.Есть ли у кого-нибудь очень элегантный способ развертывания отчетов.Ключевым моментом здесь является то, что я хочу, чтобы процесс был полностью автоматизирован.

Это было полезно?

Решение

Мы используем rs.exe, как только мы разработали скрипт, нам больше не нужно его трогать, он просто работает.

Вот исходник (я слегка модифицировал его вручную, чтобы удалить конфиденциальные данные без возможности проверить, надеюсь, я ничего не тормозил), он разворачивает отчеты и связанные изображения из подкаталогов для разных языков.Также создается источник данных.

'=====================================================================
'  File:      PublishReports.rss
'
'  Summary: Script that can be used with RS.exe to 
'           publish the reports.
'
'  Rss file spans from beginnig of this comment to end of module
' (except of "End Module").
'=====================================================================

Dim langPaths As String() = {"en", "cs", "pl", "de"}
Dim filePath As String = Environment.CurrentDirectory

Public Sub Main()

    rs.Credentials = System.Net.CredentialCache.DefaultCredentials

    'Create parent folder
    Try
        rs.CreateFolder(parentFolder, "/", Nothing)
        Console.WriteLine("Parent folder created: {0}", parentFolder)
    Catch e As Exception
        Console.WriteLine(e.Message)
    End Try

    PublishLanguagesFromFolder(filePath)

End Sub

Public Sub PublishLanguagesFromFolder(ByVal folder As String)
    Dim Lang As Integer
    Dim langPath As String

    For Lang = langPaths.GetLowerBound(0) To langPaths.GetUpperBound(0)
        langPath = langPaths(Lang)

        'Create the lang folder
        Try
            rs.CreateFolder(langPath, "/" + parentFolder, Nothing)
            Console.WriteLine("Parent lang folder created: {0}", parentFolder + "/" + langPath)
        Catch e As Exception
            Console.WriteLine(e.Message)
        End Try

        'Create the shared data source
        CreateDataSource("/" + parentFolder + "/" + langPath)

        'Publish reports and images
        PublishFolderContents(folder + "\" + langPath, "/" + parentFolder + "/" + langPath)
    Next 'Lang
End Sub

Public Sub CreateDataSource(ByVal targetFolder As String)
    Dim name As String = "data source"

    'Data source definition.
    Dim definition As New DataSourceDefinition
    definition.CredentialRetrieval = CredentialRetrievalEnum.Store
    definition.ConnectString = "data source=" + dbServer + ";initial catalog=" + db
    definition.Enabled = True
    definition.EnabledSpecified = True
    definition.Extension = "SQL"
    definition.ImpersonateUser = False
    definition.ImpersonateUserSpecified = True
    'Use the default prompt string.
    definition.Prompt = Nothing
    definition.WindowsCredentials = False
    'Login information
    definition.UserName = "user"
    definition.Password = "password"

    Try
    'name, folder, overwrite, definition, properties 
        rs.CreateDataSource(name, targetFolder, True, definition, Nothing)
    Catch e As Exception
        Console.WriteLine(e.Message)
    End Try

End Sub

Public Sub PublishFolderContents(ByVal sourceFolder As String, ByVal targetFolder As String)
    Dim di As New DirectoryInfo(sourceFolder)
    Dim fis As FileInfo() = di.GetFiles()
    Dim fi As FileInfo

    Dim fileName As String

    For Each fi In fis
        fileName = fi.Name
        Select Case fileName.Substring(fileName.Length - 4).ToUpper
            Case ".RDL"
                PublishReport(sourceFolder, fileName, targetFolder)
            Case ".JPG", ".JPEG"
                PublishResource(sourceFolder, fileName, "image/jpeg", targetFolder)
            Case ".GIF", ".PNG", ".BMP"
                PublishResource(sourceFolder, fileName, "image/" + fileName.Substring(fileName.Length - 3).ToLower, targetFolder)
        End Select
    Next fi
End Sub

Public Sub PublishReport(ByVal sourceFolder As String, ByVal reportName As String, ByVal targetFolder As String)
    Dim definition As [Byte]() = Nothing
    Dim warnings As Warning() = Nothing

    Try
        Dim stream As FileStream = File.OpenRead(sourceFolder + "\" + reportName)
        definition = New [Byte](stream.Length) {}
        stream.Read(definition, 0, CInt(stream.Length))
        stream.Close()
    Catch e As IOException
        Console.WriteLine(e.Message)
    End Try

    Try
   'name, folder, overwrite, definition, properties 
        warnings = rs.CreateReport(reportName.Substring(0, reportName.Length - 4), targetFolder, True, definition, Nothing)

        If Not (warnings Is Nothing) Then
            Dim warning As Warning
            For Each warning In warnings
                Console.WriteLine(warning.Message)
            Next warning
        Else
            Console.WriteLine("Report: {0} published successfully with no warnings", targetFolder + "/" + reportName)
        End If
    Catch e As Exception
        Console.WriteLine(e.Message)
    End Try
End Sub

Public Sub PublishResource(ByVal sourceFolder As String, ByVal resourceName As String, ByVal resourceMIME As String, ByVal targetFolder As String)
    Dim definition As [Byte]() = Nothing
    Dim warnings As Warning() = Nothing

    Try
        Dim stream As FileStream = File.OpenRead(sourceFolder + "\" + resourceName)
        definition = New [Byte](stream.Length) {}
        stream.Read(definition, 0, CInt(stream.Length))
        stream.Close()
    Catch e As IOException
        Console.WriteLine(e.Message)
    End Try

    Try
    'name, folder, overwrite, definition, MIME, properties 
        rs.CreateResource(resourceName, targetFolder, True, definition, resourceMIME, Nothing)
        Console.WriteLine("Resource: {0} with MIME {1} created successfully", targetFolder + "/" + resourceName, resourceMIME)
    Catch e As Exception
        Console.WriteLine(e.Message)
    End Try
End Sub

Вот пакет для вызова rs.exe:

SET ReportServer=%1
SET DBServer=%2
SET DBName=%3
SET ReportFolder=%4

rs -i PublishReports.rss -s %ReportServer% -v dbServer="%DBServer%" -v db="%DBName%" -v parentFolder="%ReportFolder%" >PublishReports.log 2>&1

pause

Другие советы

я использовал скрипт @Дэйвид предоставлено, но мне пришлось добавить некоторый код (я пишу это как ответ, так как для комментария это было бы слишком долго.

Проблема в:если к отчету в определении отчета уже прикреплен «общий источник данных», это никогда не будет тем же источником данных, что и тот, который создается в скрипте.

Это также становится очевидным из предупреждения, выданного методом CreateReport:

Набор данных относится к общему источнику данных, который не публикуется на сервере отчетов.

Поэтому источник данных впоследствии необходимо указать явно.Я внес следующие изменения в код:

Я добавил глобальную переменную:

Dim dataSourceRefs(0) As DataSource

В конце метода CreateDataSource эта переменная заполняется:

Dim dsr As New DataSourceReference
dsr.Reference = "/" + parentFolder + "/" + db
Dim ds As New DataSource
ds.Item = CType(dsr, DataSourceDefinitionOrReference)
ds.Name = db
dataSourceRefs(0) = ds

А в методе PublishReport этот источник данных устанавливается явно (после вызова CreateReport):

rs.SetItemDataSources(targetFolder + "/" + reportName.Substring(0, reportName.Length - 4), dataSourceRefs)

Обратите внимание, что этот последний вызов относится только к RS 2005 или выше.Если вы хотите загрузить свои отчеты на сервер RS 2000, вам необходимо использовать SetОтчетИсточники данных вместо этого:

rs.SetReportDataSources(targetFolder + "/" + reportName.Substring(0, reportName.Length - 4), dataSourceRefs)

Ну не совсем элегантно.Мы создали собственный инструмент, использующий веб-службу reportservices2005.Мы обнаружили, что это самый надежный способ получить то, что мы хотим.

На самом деле это не так уж и сложно, и вы можете расширить его, чтобы делать другие вещи, например создавать источники данных и папки по мере необходимости.

Я настоятельно рекомендую RSScripter.Как отмечено в обзоре:

Scipter Services Services - это приложение .NET Windows Forms, которое позволяет сценарию и передачу всех элементов каталога каталога отчетов SQL Server SQL SQL SQL, чтобы помочь их передаче с одного сервера на другой.Его также можно использовать для легкости перемещения элементов в массу из одной папки служб отчетности в другую на том же сервере.В зависимости от выбранных параметров сценариев, сценарий служб отчетности также может передавать все свойства элементов каталога, такие как описания, параметры истории, параметры выполнения (включая конкретные отчеты и общие графики), подписки (нормальные и управляемые данными) и параметры отчета на стороне сервера.

Я знаю, вы говорите, что не поддерживаете использование Business Development Studio для этого, но я считаю, что встроенные инструменты очень надежны и просты в использовании.

Рассматривали ли вы какие-либо решения непрерывной интеграции, такие как CruiseControl.NET?Если вы можете развертывать отчеты с помощью rs.exe, вы можете настроить автоматический процесс в CruiseControl для создания и развертывания отчетов по таймеру или при каждом изменении отчета.

В нашей среде мы разрабатываем в VS с контролем версий, а затем развертываем в DEV SSRS.После проверки отчета мы используем программу ReportSync для развертывания отчетов из ReportServer DEV к ReportServer PROD.Скрипты RS.EXE по-прежнему имеют свое место, но я считаю, что ReportSync — гораздо более простой и гибкий способ продвижения отчета.

ОтчетСинхронизация:

ReportSync — это программа с открытым исходным кодом, которую можно бесплатно загрузить и использовать.Он отлично подходит для массовой загрузки отчетов и даже может передавать отчет с одного сервера на другой сервер.


Как получить возможность скачать программу?

Как развернуть отчет?

  1. Запустите исполняемый файл, и интерфейс запустится.
  2. Использовать SOURCE и DESTINATION диалоги на выбор single report, multiple reports, или entire folder of reports.Вы можете выбрать любую целевую папку.(НАМЕКАТЬ:Вы даже можете настроить таргетинг на один и тот же сервер, если хотите продублировать отчет на том же сервере.)
  3. Сделав выбор, нажмите кнопку Sync button
  4. Перейдите на целевой сервер и убедитесь, что изменение вступило в силу, просмотрев дату изменения.

Этот инструмент оказался очень удобным, но я заметил некоторые особенности.Например when I want to update just one report that already exists in the destination, вот что мне нужно выбрать-- [Source:Report> Target:Folder> Sync].ПРЕДУПРЕЖДЕНИЕ:Вы можете подумать, что вам нужно выбрать отчет целевого сервера для его обновления, но я попробовал это, и отчет не обновляется.


Что еще может ReportSync?

  • Существует также Export функция, которая прекрасно работает, позволяя просто сбросить все файлы RDL в папку, к которой я могу получить доступ.Это полезно, если вам нужно перенести сервер, добавить файлы в проект решения VS или сделать что-нибудь еще со всеми файлами.

  • В моем тестировании этой программы не перенести другой контент — подписки, общие источники данных, общие наборы данных.Это применимо только к файлам отчетов.

Я знаю, что этот пост старый, но я наткнулся на него при исследовании сценариев RS.EXE, поэтому решил дать ответ на этот вопрос.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top