Мне нужно создать повторяемый процесс для развертывания отчетов служб отчетов SQL Server. Я не сторонник использования Visual Studio или Business Development Studio для этого. Метод сценариев развертывания rs.exe также кажется довольно неуклюжим. Есть ли у кого-нибудь очень элегантный способ развертывания отчетов. Ключевым моментом здесь является то, что я хочу, чтобы процесс был полностью автоматизирован.
Развертывание служб Reporting Services
Ответы (7)
Мы используем 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
Я использовал предоставленный сценарий @David, но мне пришлось добавить код (я напечатайте это как ответ, так как это будет слишком долго для комментария.
Проблема заключается в следующем: если в определении отчета уже есть «общий источник данных», прикрепленный к отчету, это никогда не будет тем же источником данных, что и тот, который был создан в сценарии.
Это также становится очевидным из предупреждения, выдаваемого методом 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 Report DataSources:
rs.SetReportDataSources(targetFolder + "/" + reportName.Substring(0, reportName.Length - 4), dataSourceRefs)
Ну, не очень элегантно. Мы создали наш собственный инструмент, который использует веб-сервис ReportingServices2005. Мы обнаружили, что это самый надежный способ получить то, что мы хотим.
Это не так уж сложно и позволяет вам расширять его для других вещей, таких как создание источников данных и папок по мере необходимости.
Я настоятельно рекомендую RSScripter. Как отмечено в обзоре:
Сценарий служб Reporting Services - это приложение .NET Windows Forms, которое позволяет создавать сценарии и передавать все элементы каталога служб отчетов Microsoft SQL Server, чтобы облегчить их перенос с одного сервера на другой. Его также можно использовать для простого массового перемещения элементов из одной папки служб Reporting Services в другую на том же сервере. В зависимости от выбранных параметров сценария, Reporting Services Scripter может также передавать все свойства элементов каталога, такие как описания, параметры истории, параметры выполнения (включая конкретные и общие расписания отчетов), подписки (обычные и управляемые данными) и параметры отчетов на стороне сервера.
Я знаю, вы говорите, что не поддерживаете Business Development Studio, но я считаю, что встроенные инструменты очень надежны и просты в использовании.
Вы изучали какие-либо решения для непрерывной интеграции, такие как CruiseControl.NET? Если вы можете развернуть отчеты с помощью rs.exe, вы можете настроить автоматический процесс в CruiseControl для создания и развертывания отчетов по таймеру или при изменении отчета.
В нашей среде мы разрабатываем в VS с контролем версий, а затем развертываем в DEV SSRS. После проверки отчета мы используем программу ReportSync для развертывания отчетов от ReportServer DEV до ReportServer PROD. Сценарии RS.EXE по-прежнему актуальны, но я обнаружил, что ReportSync является гораздо более простым и гибким способом продвижения отчета.
ReportSync:
ReportSync - это программа с открытым исходным кодом, которую можно бесплатно загрузить и использовать. Он отлично подходит для массовой загрузки отчетов и даже может передавать отчет с одного сервера на другой.
Как получить скачать программу?
Загрузите файлы исходного кода из Github: Phires / ReportSynch, запустите VS, откройте файл решения (.SLN ), скомпилируйте программу, найдите исполняемый файл (.EXE) в папке C: \ Temp \ reportsync-master \ bin \ Release. Наконец, сохранил .EXE где-нибудь, чтобы вы могли регулярно его использовать.
Как скопировать отчеты SSRS на новый сервер, если я не являюсь владельцем отчетов -> ReportSync ответ от nunespascal
Как развернуть отчет?
- Запустите исполняемый файл, и интерфейс запустится.
- Используйте диалоговые окна
SOURCEиDESTINATION, чтобы выбратьsingle report,multiple reportsилиentire folder of reports. Вы можете любую целевую папку, которую хотите. (ПОДСКАЗКА: вы даже можете настроить таргетинг на один и тот же сервер, если хотите дублировать отчет на том же сервере.) - Сделав свой выбор, нажмите
Sync button - Перейдите на целевой сервер и убедитесь, что изменение вступило в силу, просмотрев Дата изменения.
Этот инструмент был очень удобен, но я заметил некоторые особенности. Например, 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, поэтому подумал, что дам ответ на этот вопрос.