Δεν είναι λίγες οι φορές που θέλουμε να αυτοματοποιήσουμε διαδικασίες ή να κάνουμε εργασίες μαζικά χωρίς να μπλέκουμε με το UI στα SQL Server Reporting Services. Για να κάνουμε κάτι τέτοιο πολλές φορές θα χρειαστεί να γράψουμε κάποιο script σε Visual Basic .NET το οποίο θα πρέπει να εκτελεστεί με το rs.exe utility που έχουν τα SSRS.
Εισαγωγή
Για να γραφτεί αυτό το script υπάρχουν αρκετοί editors όμως αυτό που θέλουμε είναι να μπορέσουμε να κάνουμε την συγγραφή αυτή χρησιμοποιώντας όλα τα καλούδια που έχουμε συνηθίσει από το Visual Studio όπως πχ intelligence, debugging κλπ.
Διαβάζοντας τα BOL που αφορούν το rs.exe και όλα τα παρελκόμενα του δεν θα μας οδηγήσει σε έναν ασφαλή τρόπο με τον οποίο θα έχουμε την δυνατότητα να χρησιμοποιήσουμε το Visual Studio σαν εργαλείο συγγραφής του script κώδικα με όλα τα καλούδια που αναφέρθηκαν παραπάνω.
Ακόμα και αν ψάξει κανείς στο internet σχετικά με το θέμα αυτό θα συναντήσει διάφορες προτάσεις που όμως δεν δίνουν την ιδανική λύση. Γενικά είναι ένα θέμα το οποίο έχει μείνει αρκετά αχνό, τουλάχιστον για αυτούς που δεν θα διαβάσουν το συγκεκριμένο post.
Τα προβλήματα
Ας πάρουμε τα πράγματα με μια σειρά. Αρκετοί θα έχουν ψάξει ή θα ψάξουν στο internet για λύση στο συγκεκριμένο πρόβλημα. Θα βρουν αρκετές απαντήσεις για το θέμα που θα τους λένε να φτιάξουν ένα console app σε VB.NET και να κάνουν reference το service των Reporting Services.
Πράγματι αυτό είναι κάτι το οποίο θα έκανε ο κάθε developer. Η συγκεκριμένη προσέγγιση όμως δεν ικανοποιεί καθώς μέσα από εκεί ναι μεν σου δίνει την δυνατότητα να κάνεις χρήση του service και κατά συνέπεια θα έχεις και intelligence, debugging κλπ αλλά…
Αυτό το αλλά κάνει την διαφορά.
Στην περίπτωση αυτή θα πρέπει να χρησιμοποιηθεί και να γίνει αρχικά instantiate το ReportingService2005SoapClient class αν επιλέξουμε να χρησιμοποιήσουμε το reportservice2005.asmx ή το ReportingService2010SoapClient class αν επιλέξουμε να χρησιμοποιήσουμε το reportservice2010.asmx.
Δυστυχώς ναι μεν θα κάνουμε δουλειά και θα γράψουμε το script αλλά όταν θα πάμε να το εκτελέσουμε με το rs.exe θα παρατηρήσουμε αρκετά methods calls θα σκάνε καθώς το signature αυτών είναι διαφορετικό. Πράγμα που σημάνει ότι δεν μπορώ να εξομοιώσω ακριβώς το περιβάλλον του rs.exe.
Είμαι σίγουρος ότι θα βρείτε στον ιστό και άλλες λύσεις που όμως δεν είναι πρακτικές.
Το συγκεκριμένο θέμα με είχε απασχολήσει αρκετές φορές στο παρελθόν και οι τρόποι με τους οποίους έγγραφα τέτοια scripts ήταν απελπιστικοί. Μέχρι που πριν λίγο καιρό με έπιασαν τα διαόλια μου και είπα αρκετά δεν πάει άλλο αυτή η κατάσταση.
Η λύση
Ενώ ήξερα το όλο concept πως παίζει εντούτοις συστηματικά έκανα το ίδιο λάθος δεν έδινα την δέουσα προσοχή στο περιβάλλον που εσωτερικά είχε το rs.exe και εκτελούσε τα scripts αυτά. Γνώριζα ότι αυτό στην ουσία καλεί το Reporting Services Web Service αφού μία από τις παραμέτρους του είναι να του δώσει το url του report server (-s) και με την παράμετρο (-e) μπορείς να ορίζεις αν θα χρησιμοποιήσεις το 2005 ή 2010 web service. Με την πρώτη ματιά αυτό με οδηγούσε πάντα στο λάθος αποτέλεσμα.
Αποφάσισα να κάνω ένα reengineering στο rs.exe καθώς γνώριζα ότι είναι ένα .net app και πραγματικά με το ILSpy έβγαλα άκρη.
Ποια είναι αυτή;
Απλά πρέπει να φτιάξουμε την proxy class για κάποιο από τα web services (2005 – 2010) και αυτή να την βάλεις μέσα στο console app που θα φτιάξεις.
Αυτό για να το κάνεις απλά θα πρέπει να ανοίξεις ένα cmd command, κατά προτιμήσει το Visual Studio Command Prompt στο οποίο να εκτελέσεις το WSDL.EXE και σε αυτό να περάσεις σαν παράμετρο το url του web service, την γλώσσα που θέλεις να βγει ο κώδικας της proxy class, στην περίπτωση μας αυτό είναι μονόδρομος και πρέπει να δηλώσεις VB και την παράμετρο /out: με το path και το αρχείο που θέλεις να παραχθεί.
Για παράδειγμα
wsdl http://yourserver/reportservice2010.asmx /language:vb /out:c:\temp\proxyclassname.vb
Το αρχείο αυτό το κάνεις include στον vb.net console app και ...
Από εκεί και πέρα μπορείς να γράψεις τον κώδικα σου στο module και συγκεκριμένα στην Main sub. Φυσικά θα πρέπει όλες τις παραμέτρους και τυχόν μεταβλητές να τις έχεις μέσα Module σου σαν module variables και ακόμα σαν module variable να δηλώσεις την rs με την οποία έχεις κάνει instantiate το web service. Το όνομα της μεταβλητής για το web service πρέπει να είναι αυτό καθώς εσωτερικά αυτό χρησιμοποιεί το rs.exe
Το επόμενο βήμα είναι να έχει referenced και import τα System.IO και System.Web.Services.Protocols namespaces.
Για την βοήθεια σας παραθέτω τα αρχικά πράγματα που πρέπει να έχει το module ώστε νε επικεντρωθείτε στην κατεξοχήν εργασία που θέλετε να κάνετε.
Με όλα αυτά τα απλά βήματα πλέον έχεις την δυνατότητα να γράψεις σαν άνθρωπος το script σου και να το κάνεις debug.
Startup Code
Imports System.IO
Imports System.Web.Services.Protocols
Module SSRS_RS_UTILITY
'Sample Execution Command of RS.EXE
' rs -i SSRSSampleDeploy.rss
' -s http://localhost/reportserver
' -v var1
' -v var2
' -e Mgmt2010
' -t
Dim rs As New ReportingService2010()
Dim definition As [Byte]() = Nothing
Dim warnings As Warning() = Nothing
Dim var1 As String
Dim var2 As String
Public Sub Main()
' Security Crendetials to Report Server
rs.Credentials = System.Net.CredentialCache.DefaultCredentials
'
' yours code goes here
'
End Sub
End Module