This script uses the DTS object model to create a simple package, execute the package, and properly check for any errors.
2007-10-02 (first published: 2002-06-20)
15,451 reads
This script uses the DTS object model to create a simple package, execute the package, and properly check for any errors.
#This perl script creates and executes a DTS Package in RAM to move table data #The Package is set to use IAFastLoad which means it will run as fast as #a BCP command. All with the added bonus of no files on disk! #Future enhancement : a feature to write the DTS Package to disk or SQL Server use strict; use Win32::OLE; use Getopt::Std; use Win32::OLE::Const 'Microsoft DTSPackage Object Library'; use Win32::OLE::Const 'Microsoft DTS Custom Tasks Object Library'; use Win32::OLE::Const 'Microsoft DTSDataPump Scripting Object Library'; use Win32::OLE::Variant; my $Err = 0; my $ErrMsg = ""; #Set the arguments my (%Args, $Args); getopts('EU:P:S:D:O:s:d:o:', \%Args); my $SourceServer = $Args{S}; my $SourceDb = $Args{D}; my $SourceObj = $Args{O}; my $DestServer = $Args{s}; my $DestDb = $Args{d}; my $DestObj = $Args{o}; my $UserId = $Args{U}; my $Password = $Args{P}; #Create the Package my $Package = new Win32::OLE 'DTS.Package'; $Package->{Name} = "DataMover"; $Package->{FailOnError} = 1; #Create Connection objects and add them to the Package my $Conn = $Package->Connections->New("SQLOLEDB"); $Conn->{Name} = "Source"; $Conn->{ID} = 1; $Conn->{DataSource} = $SourceServer; $Conn->{Catalog} = $SourceDb; if ($Args{E}) { $Conn->{UseTrustedConnection} = 1; } else { $Conn->{UserId} = $UserId; $Conn->{Password} = $Password; } $Package->Connections->Add($Conn); $Conn=undef; $Conn = $Package->Connections->New("SQLOLEDB"); $Conn->{Name} = "Destination"; $Conn->{ID} = 2; $Conn->{DataSource} = $DestServer; $Conn->{Catalog} = $DestDb; if ($Args{E}) { $Conn->{UseTrustedConnection} = 1; } else { $Conn->{UserId} = $UserId; $Conn->{Password} = $Password; } $Package->Connections->Add($Conn); $Conn=undef; #Create the DataPumpTask with IAFastLoad enabled (blazing fast) my $Task = $Package->Tasks->New("DTSDataPumpTask"); $Task->{Name} = "CopyColumns"; my $CustomTask = $Task->{CustomTask}; $CustomTask->{SourceConnectionID} = 1; $CustomTask->{SourceObjectName} = $SourceObj; $CustomTask->{DestinationConnectionID} = 2; $CustomTask->{DestinationObjectName} = $DestObj; $CustomTask->{UseFastLoad} = 1; $CustomTask->{FastLoadOptions} = 1; #Create the Transformation and add it to the task my $Transform = $CustomTask->Transformations->New("DTSPump.DataPumpTransformCopy"); $Transform->{Name} = "TransformData"; $Transform->{TransformFlags} = DTSTransformFlag_AllowLosslessConversion; $CustomTask->Transformations->Add($Transform); #Add the task to the Package $Package->Tasks->Add($Task); $Task=undef; #Create the Package step and add it to the Package my $Step = $Package->Steps->New(); $Step->{Name} = "Step1"; $Step->{TaskName} = "CopyColumns"; $Step->{ExecuteInMainThread} = 1; $Package->Steps->Add($Step); #$Step=undef; #Execute the Package $Package->Execute(); print Win32::OLE->LastError ."\n"; #Check for Errors ($ErrMsg, $Err) = &StepErrors; if ($Err == -1) { print "$ErrMsg\n"; } else { print "Package Completed Sucessfully\n"; } $Package=undef; exit $Err; #Loop through the steps and look for Errors based on the ExecutionResult sub StepErrors { my $ErrorCode=Variant(VT_I4|VT_BYREF, "-1"); my $Source=Variant(VT_BSTR|VT_BYREF, "<none >"); my $Description=Variant(VT_BSTR|VT_BYREF, "<none >"); foreach my $Steps (in {$Package->{Steps}}) { if ($Steps->{ExecutionStatus} == 4) { if ($Steps->{ExecutionResult} == 1) { $Err = -1; $Steps->GetExecutionErrorInfo($ErrorCode,$Source,$Description); $ErrMsg = "$ErrMsg \n Step $Steps->{Name} failed, Error:\n $ErrorCode \n $Description \n"; } } } return $ErrMsg, $Err; }