Data Transformation Services (DTS) is extremely useful in solving a number of problems.In some cases I have used it to solve data problems and in other cases I have used it to solve some tasks that have nothing to do with SQL. One difficulty I found with DTS was managing the different packages that exist on servers. For example, I may have packages A, B and C on Server 1 and packages D, E and F on Server 2, although the packages can be made generic and abstracted so they use common data sets too often I find subtle differences between packages on different servers. For this reason it is nice to have a backup of each package from each server. As you should know backing up packages is important and can be a relatively trivial task but to gather up a group of packages from a variety of servers and store them in one location can be more involved.
At the heart of DTS packages is the MSDB database. All the information pertaining to DTS packages resides in the MSDB database. The table that contains the packages is SYSDTSPACKAGES. This table contains the current version of the DTS package and also the previous versions of the package.
To see this for yourself right click on a DTS package in Enterprise Manager. One of the options in the context menu is versions. Selecting versions will list all the versions of the package stored in the MSDB..SYSDTSPACKAGES table. This is one way to access steps in a package that may have been deleted as the package was modified.
Any time a package is saved and a server is specified the package is stored in the MSDB database of that server. When there are multiple servers and workstations in an organization containing DTS packages the packages can be difficult to manage and backup. If the MSDB database is backed up on each server and workstation in the organization the DTS packages can be recovered if needed.
In order to simplify backing up the packages for my company I created a DTS package to gather all the packages from various servers and store them in a single database. The packages are gathered by querying MSDB on all the servers and using a Data Pump to load them in a central database. I then created a small extraction package so I could output a package from the DTS store to a SQL server.
As an aside, it should be noted that one key to working with MSDB and the SYSDTSPACKAGES table is in order to access the table within DTS packages one may need to do a disconnected edit to access it. I found this information on the site www.sqldts.com. The disconnected edit is avoided here by specifying a query to access the data we need. If, however, you wanted to access the SYSDTSPACKAGES table you would need to use a disconnected edit because it is not possible to access the table via the drop down list in the data pump.
The tasks involved in moving the DTS packages to a central location are as follows. First a database and table need to be created to hold the packages. The packages are transfered via a data pump. A query is used as a source for the data pump so that only the most recent version of the DTS package is extracted. Once the server name is appended to the source query the data can be pumped from the MSDB database on a selected server to the DTS Store.
In order to implement the DTS Store the first step is to create a database and table to hold the desired information. The name of the database I created was DTSStore. In this database I created a table using the following SQL Script:
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[DTSStore]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table [dbo].[DTSStore] GO CREATE TABLE [dbo].[DTSStore] ( [SourceServer] [nvarchar] (128) COLLATE SQL_Latin1_General_CP1_CI_AS NULL , [name] [nvarchar] (128) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL , [id] [uniqueidentifier] NOT NULL , [versionid] [uniqueidentifier] NOT NULL , [description] [nvarchar] (1024) COLLATE SQL_Latin1_General_CP1_CI_AS NULL , [categoryid] [uniqueidentifier] NOT NULL , [createdate] [datetime] NULL , [owner] [nvarchar] (128) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL , [packagedata] [image] NULL , [owner_sid] [varbinary] (85) NOT NULL , [packagetype] [int] NOT NULL , [datecreated] [datetime] NULL ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] GO ALTER TABLE [dbo].[DTSStore] ADD CONSTRAINT [DF_DTSStore_datecreated] DEFAULT (getdate()) FOR [datecreated] GO
NOTE: The database and table storing our DTS packages have the same name (DTSStore) because of the author’s inability to come up with creative names.
This table has almost the same structure as the MSDB..SYSDTSPACKAGES table. There are two additional fields in the DTSStore table: SourceServer and DateCreated. These two fields help identify packages that may have the same name but exist on different servers and also identify the date when a package was extracted from a server. Notice that the DateCreated has a constraint so that the date defaults to the current date and time.
The DTS Package to do the work of acquiring the packages is straightforward. In this case it is nothing more than a data pump between a source server (DTSPackageSource) and a destination server (DTSStore). The destination server is the server that contains the DTSStore database created above. The Get Packages DTS package is shown below.
If we look at the properties of the data pump we will see the following on the source tab.
The source is an SQL query. I have listed the query below because the query cannot be read in the above image.
select @@Servername as SourceServer, dts.* from msdb..sysdtspackages dts inner join (select name, max(CreateDate) as CreateDate from msdb..sysdtspackages Group BY name) BT on BT.Name = dts.Name AND BT.CreateDate = dts.CreateDate order by dts.name
Only the most recent version of each package is collected from the source server. The most recent version is selected by specifying the package with the greatest creation date. I have also added the @@Servername to the select statement so the source server name can be added to the DTSStore for each package.
The destination tab contains the DTSStore as our destination table.
If the store was created using the query above the DTSStore can be used directly, it simply needs to be selected on the destination tab of the data pump.
The source query and the destination match up column for column except for the datecreated. The transformation tab can then map each column directly from the source to the destination. Datecreated does not need to be specified because it has a default value constraint.
At this point everything is complete to copy packages from a source server to the DTS store. By changing the server name properties of the DTSPackageSource object the DTS packages from a variety of servers can be copied to the store. With a little extra work this package could be designed to query a variety of servers and acquire the packages in an automated manner. The package could then be scheduled so the packages would be backed up on a regular basis by backing up a single database.
Using a simlar process it is possible to move the packages from the destination server back to a source server. It is also possible to create a package that will extract a single package. These topics will be covered in a future article or can be explored by the reader.