Je dois créer un processus reproductible pour déployer des rapports SQL Server Reporting Services. Je ne suis pas en faveur d'utiliser Visual Studio et / ou Business Development Studio pour ce faire. La méthode rs.exe de scripting des déploiements semble également assez maladroite. Quelqu'un at-il une manière très élégante de pouvoir déployer des rapports? La clé ici est que je veux que le processus soit complètement automatisé.
Réponses
Trop de publicités?Nous utilisons rs.exe, une fois que nous avons développé le script, nous n'avons plus besoin de le toucher, cela fonctionne.
Voici la source (je l'ai légèrement modifiée à la main pour supprimer les données sensibles sans avoir la chance de la tester, j'espère que je n'ai rien freiné), elle déploie des rapports et des images associées à partir de sous-répertoires pour différentes langues. Une source de données est également créée.
'=====================================================================
' 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
Voici le lot pour appeler le 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
J'ai utilisé le script @David fourni, mais j'ai dû ajouter un peu de code (je suis en train de taper ceci comme réponse, car ce serait trop long pour un commentaire.
Le problème est: si il existe déjà un "shared source de données", qui est joint à un rapport dans la définition de rapport, ce n'est jamais la même source de données que celui qui est créé dans le script.
Cela devient évident à partir de l'avertissement émis par le "CreateReport" la méthode:
L'ensemble de données " désigne la source de données partagée ", ce qui n'est pas publié sur le serveur de rapports.
Si la source de données doit être définie de manière explicite par la suite. J'ai fait les modifications de code suivantes:
J'ai ajouté une variable globale:
Dim dataSourceRefs(0) As DataSource
À la fin de la méthode CreateDataSource, cette variable est remplie:
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
Et dans le PublishReport méthode, la source de données devient explicitement défini (après CreateReport a été appelé):
rs.SetItemDataSources(targetFolder + "/" + reportName.Substring(0, reportName.Length - 4), dataSourceRefs)
Notez que ce dernier appel est seulement RS 2005 ou plus. Si vous souhaitez charger vos rapports sur une RS 2000 server, vous devez utiliser le SetRapportSources de données dans la place:
rs.SetReportDataSources(targetFolder + "/" + reportName.Substring(0, reportName.Length - 4), dataSourceRefs)
Enfin pas vraiment élégant. Nous avons créé notre propre outil qui utilise le service Web reportingservices2005. Nous avons trouvé que c'était le moyen le plus fiable d'obtenir ce que nous voulions.
Ce n'est pas vraiment si difficile et vous permet de l'étendre pour faire d'autres choses comme créer des sources de données et des dossiers selon les besoins.
Je recommande fortement RSScripter. Comme noté dans l'aperçu:
Reporting Services Scripteur est un .NET Windows Forms application qui permet de script et de transfert de tous les Microsoft SQL Server Reporting Services les articles du catalogue à l'aide de de les transférer d'un serveur à l' l'autre. Il peut également être utilisé facilement déplacer des éléments sur la masse d'un Reporting Les Services d'un dossier à un autre sur le même serveur. Selon le script les options choisies, Reporting Services Scripter pouvez également transférer tout le catalogue propriétés de l'élément, telles que les Descriptions, L'histoire des options, des options d'Exécution (en ce compris le rapport précis et partagé les horaires), les Abonnements (normal et piloté par les données) et côté serveur de rapports les paramètres.