Συχνά έχω την ερώτηση από μαθητές μου αλλά και από συνεργάτες που ήταν συνηθισμένοι με τα SQL Server 2000 DTS όπου υπήρχε η δυνατότητα να κάνουν export αυτά σε VB code module και να τα καλούν μέσα από τις εφαρμογές τους, πως μπορούν να κάνουν το ίδιο ή σχεδόν το ίδιο με τα SSIS packages.
Η απάντηση είναι σχετικά απλή και θα σας την παρουσιάσω σε αυτό το post. Όμως θα πρέπει εξ αρχής να επισημάνω ότι απαιτούνται γνώσεις προγραμματισμού σε .net περιβάλλον άνω του μετρίου.
Επίσης κατά την άποψη μου πρέπει να υπάρχει μια αρκετά καλή εξοικειώσει με το object model των SSIS καθώς αυτό είναι λίγο περίεργο σε σχέση με άλλα, και αυτό πάλι είναι μια προσωπική άποψη που ίσως να μην σας βρει σύμφωνους. Όπως και να έχει όμως η δουλεία μας γίνεται.
Το SSIS Πακέτο
Ας πάρουμε τα πράγματα από την αρχή και ας φτιάξουμε ένα απλό SSIS πακέτο (με το όνομα ThePackage) το οποίο θα κάνει κάτι αρκετά απλό.
Θα έχει ένα Data Flow Task
το οποίο θα έχει ένα OLEDB Data Source που θα διαβάζει τον πίνακα Products από την Northwind database και θα κάνει export τα δεδομένα του πίνακα σε ένα semicolon(;) delimited flat file.
Για να γίνει το παραπάνω θα έχω δύο Connection Managers,
ένα Flat File Connection Manager με το όνομα FlatFile που θα έχει τα στοιχεία για το flat file που θα κάνουμε export και έναν OLEDB Connection Manager που θα συνδέεται στην Northwind database από την οποία θα διαβάζουμε τον πίνακα Products. Το όνομα αυτού είναι Northwind.
Για εκπαιδευτικούς λόγους βάζω ένα variable το οποίο δεν θα το χρησιμοποιήσω πουθενά καθώς το πακέτο που φτιάχνω δεν έχει κάποια απαίτηση τέτοια, αλλά θέλω να σας δείξω πως μπορώ να την γεμίσω από την εφαρμογή μου. Το όνομα της variable είναι AVar.
Το σενάριο μου είναι ότι θέλω να ορίζω κατά την εκτέλεση, από την εφαρμογή μου, του SSIS πακέτου τα connection strings των connection managers αλλά και να θέτω τιμή στην variable.
Η εγκατάσταση του στον SQL Server
Αφού το έχω φτιάξει και το έχω δοκιμάσει ότι δουλεύει μέσα από το BIDS (BI Development Studio aka Visual Studio) θέλω να βγάλω deployment manifest ώστε να μπορώ να το κάνω deploy στο SQL Server που θέλω.
Για να γίνει αυτό πάω πάνω στο SSIS Project στον Solution Explorer και κάνω δεξι κλικ και επιλέγω Properties όπου και μου εμφανίζεται το Property Pages Window. Επιλέγω Deployment Utility από τα Configuration Properties και στα δεξιά εμφανίζονται οι επιλογές αυτού όπου επιλέγω να κάνω true το CreateDeploymentUtility property.
Με την ολοκλήρωση τις διαδικασίας αυτής και αφού κάνω Build to SSIS Project μου, στο φάκελο Deployment ο οποίος υπάρχει μέσα στο Bin folder του folder που έχω φτιάξει το SSIS Project θα έχω τα παρακάτω αρχεία
Παίρνω τα περιεχόμενα του φακέλου αυτού και τα πάω στον SQL Server στον οποίο και θέλω να στήσω το πακέτο που. Αφού γίνει αυτό απλά κάνω double click στο αρχείο με το extention SSISDeploymentManifest και ο SSIS Package Installation Wizard ξεκινάει. Στο βήμα που ακολουθεί επιλέγω να κάνω εγκατάσταση στον SQL Server και όχι στο file system και πατώ Next.
Στο επόμενο βήμα μιας και είμαι πάνω στο SQL Server που θέλω να γίνει η εγκατάσταση κάνω τις εξής επιλογές και πατώ Next.
Στα επόμενα βήματα πατάω απλά Next μέχρι που θα γίνει η εγκατάσταση στον SQL Server.
Αφού αυτή ολοκληρωθεί επιτυχώς τότε μέσα από τον SSMS συνδέομαι στα SSIS και θα δω το πακέτο να είναι εγκατεστημένο.
To Application που θα εκτελεί το SSIS Package
Ας έρθουμε να φτιάξουμε τώρα το application το οποίο θα καλεί το πακέτο που μόλις βάλαμε στον SQL Server. Με το Visual Studio φτιάχνω ένα console application σε C# στο οποίο για να μπορέσω να χρησιμοποιήσω τον SSIS Runtime θα πρέπει να κάνω reference το Microsoft.SQLServer.ManagedDTS assembly.
Ο κώδικας που χρειάζεται να έχω γράψει για να μπορέσω να καλέσω μέσα από την εφαρμογή μου είναι ο παρακάτω
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SqlServer.Dts.Runtime;
namespace CallingSSISPackage
{
class Program
{
static void Main(string[] args)
{
Application app = new Application();
Package pkg = new Package();
pkg = app.LoadFromSqlServer(@"\ThePackage", "SQL2008R2", null, null, null);
Variables vars2 = pkg.Variables;
vars2["AVar"].Value = "20";
ConnectionManager filemgr = pkg.Connections["FlatFile"];
filemgr.ConnectionString = @"c:\temp\products4.txt";
Console.WriteLine(pkg.Connections["FlatFile"].ConnectionString);
ConnectionManager NWDB = pkg.Connections["Northwind"];
NWDB.ConnectionString = @"Data Source=SQL2008R2;
Initial Catalog=Northwind;
Provider=SQLNCLI10.1;
Integrated Security=SSPI;";
Console.WriteLine(pkg.Connections["Northwind"].ConnectionString);
DTSExecResult rv = pkg.Execute();
Console.WriteLine("Package Execution results: {0}",rv.ToString());
Console.Read();
}
}
}
Ας εξηγήσουμε λίγο τι κάνει αυτός.
Δημιουργούμε ένα νέο instance του SSIS Application object.
Application app = new Application();
Φορτώνουμε το πακέτο από τον SQL Server συνδεόμενοι στο SQL Server με Windows integration όσον αφορά το security
Package pkg = new Package();
pkg = app.LoadFromSqlServer(@"\ThePackage", "SQL2008R2", null, null, null);
Θέτουμε τιμή στις διάφορες μεταβλητές (αυτό είναι για εκπαιδευτικούς σκοπούς, δεν κάνει τίποτα η μεταβλητή αυτή μέσα στο πακέτο)
Variables vars2 = pkg.Variables;
vars2["AVar"].Value = "20";
Και το επόμενο είναι ορίσουμε τις τιμές στα connection strings των connection managers που έχω μέσα στο πακέτο μου.
ConnectionManager filemgr = pkg.Connections["FlatFile"];
filemgr.ConnectionString = @"c:\temp\products4.txt";
Console.WriteLine(pkg.Connections["FlatFile"].ConnectionString);
ConnectionManager NWDB = pkg.Connections["Northwind"];
NWDB.ConnectionString = @"Data Source=SQL2008R2;
Initial Catalog=Northwind;
Provider=SQLNCLI10.1;
Integrated Security=SSPI;";
Console.WriteLine(pkg.Connections["Northwind"].ConnectionString);
Τέλος απλά κάνω την εκτέλεση του SSIS πακέτου και δείχνω το status της εκτέλεσης.
DTSExecResult rv = pkg.Execute();
Console.WriteLine("Package Execution results: {0}",rv.ToString());
Εγκαθιστώντας την εφαρμογή πάνω στον SQL Server και εκτελώντας την όλα θα δουλέψουν μια χαρά εφόσον έχω κάνει login στον server με ένα account το οποίο είναι στους local admins της μηχανής και είναι και sysadmin στον SQL Server.
H εκτέλεση της εφαρμογής από έναν σταθμό εργασίας
To ίδιο ισχύει και αν εκτελέσω την εφαρμογή από έναν άλλο σταθμό εργασίας, εφόσον σε αυτόν έχω συνδεθεί με το ίδιο account που χρησιμοποίησα παραπάνω.
Στην περίπτωση όμως που πάω σε ένα σταθμό εργασίας στο οποίο έχω συνδεθεί με ένα απλό χρήστη που δεν είναι admin και απλά έχει δικαιώματα πρόσβασης στον SQL Server και δικαιώματα read στην Northwind database τότε αρχίσει μια μικρή περιπέτεια.
Δοκιμάζοντας να εκτελέσω το πακέτο εμφανίζεται το πρώτο μήνυμα λάθους
Αποφασίζω να πάω και να δώσω πρόσβαση στο συγκεκριμένο χρήστη στην msdb database βάζοντας τον ταυτόχρονα να είναι μέλος του database role που υπάρχει στην msdb db_ssisltduser.
Στην επόμενη εκτέλεση που θα κάνω θα πάρω το επόμενο διαφορετικό μήνυμα λάθους
Η επόμενη κίνηση είναι το συγκεκριμένο χρήστη να του δώσω περισσότερα δικαιώματα όσον αφορά την εκτέλεση των SSIS πακέτων και αυτό γίνεται βάζοντας τον στον msdb database role db_ssisoperator. Αυτό έχει σαν αποτέλεσμα όλα να δουλέψουν ομαλά.
Όλα τα παραπάνω δουλεύουν εφόσον είμαι σε domain environment. Σε διαφορετική περίπτωση θα πρέπει τα accounts να υπάρχουν και στις δύο μηχανές με το ίδιο password.
Υπάρχουν όμως και άλλες περιπτώσεις που πιθανότατα δεν θα μπορείτε να συνδεθείτε στα Integrations Services για μερικές από αυτές μπορείτε να δείτε αυτό, αλλά γενικά αυτές είναι σπάνιες. Εάν πάντως πέσετε σε κάποια από αυτές θα μπορούσα να σας βοηθήσω εφόσον μου αναφέρεται όλες τις λεπτομέρειες για το πώς προσπαθείτε να κάνετε την εκτέλεση αυτή.
Αυτή είναι σε γενικές γραμμές η λύση για το πώς εύκολα μπορείτε να καλέσετε ένα SSIS πακέτο μέσα από την εφαρμογή σας.
/*antonch*/