Data Transformation Services

Using ActiveX Scripts in DTS

In Data Transformation Services (DTS), you can extend the capabilities of your DTS package by using Microsoft® ActiveX® scripts that implement the objects, properties, methods, and collections of the DTS object model. Using ActiveX scripts, you can:

Microsoft Visual Basic® Scripting Edition (VBScript) and Microsoft JScript® are available with an installation of Microsoft SQL Server™. If you plan to write ActiveX scripts in a language other than VBScript and JScript, be sure the language library for the scripting language you use is installed. For more information, search on "VBScript" and "JScript" in the MSDN® Library at Microsoft Web site.

Writing ActiveX Scripts in DTS

In DTS, you can write the following types of scripts:

Generally, you do not use an ActiveX script task or ActiveX workflow script to operate on data on a row-by-row basis because it is less efficient than using a transformation script. However, it is possible to do so. For example, you could use an ActiveX Script task to create one or more ADO connections and populate a set of text files with data from an ADO recordset.

Important  An ActiveX script in a transformation can affect the execution speed of a DTS package. Therefore, if performance is a priority, use scripting carefully when building a package. For more information, see Enhancing Performance of DTS Packages.

Adding ActiveX Scripts to a DTS Package

You can add scripts to a package in DTS Designer, in the DTS Import/Export Wizard, or programmatically. For more information about adding scripts programmatically, see Adding DTS ActiveX Scripts.

To add transformation scripts:

To add ActiveX Script Tasks:

To add ActiveX workflow scripts:

Scripting Capabilities

The range of functionality you can access from ActiveX scripts covers:

Scripting Examples

The following DTS ActiveX script examples show:

Simple Column Transformation

You have a daily sales table sent to your Accounting department. However, your accounting month is not based on a calendar month. Sales before the 15th day of the month are considered sales for that month. Any sales that take place on the 15th or after are considered sales for the following accounting month.

The following ActiveX Script transformation, written in VBScript, copies all the columns from the source to destination table, for each row of source data, except for the AccountingMonth column. For that column, the Sale_Date is checked to see if the sale took place before or after the 15th, and the AccountingMonth adjusted accordingly.

Function Main()
   DTSDestination("DeptName") = DTSSource("DeptName")
   DTSDestination("Sales") = DTSSource("Sales")
   DTSDestination("Sale_Date") = DTSSource("Sale_Date")
   
' break the day out of the Sale_Date
   theDay = Day(DTSSource("Sale_Date"))

' if the day field is before the 15th, the Accounting Month is the same as
' the current Sale_Date month
   If theDay < 15 then
      DTSDestination("AccountingMonth") = DTSSource("AccountingMonth")
   Else
' if the day is the 15th or later, the sales dollars belong in the next
' Accounting Month 
      theMonth = DTSSource("AccountingMonth") + 1
      ' check if we were in December when we added 1 to the month, and       ' roll it to January 
      If  theMonth > 12 then
         theMonth = 1
      End if
      DTSDestination("AccountingMonth") = theMonth
   End If

   Main = DTSTransformStat_OK

End Function
Concatenating Columns

In the following example, an ActiveX Script transformation, written in VBScript, consolidates the Sales_Month, Sales_Day, and Sales_Year columns from the source table into a single Sales_Date column in the destination table. This script is run on each row in the source data, and can be used in those tasks that operate on a row-by-row basis.

Function Main()
   DTSDestination("CustomerID") = DTSSource("CustomerID")
   DTSDestination("Sales_Date") = Trim(DTSSource("Sales_Month")) _
       + "/" + Trim(DTSSource("Sales_Day")) + "/" +  _
      Trim(DTSSource("Sales_Year"))
   Main = DTSTransformStat_OK
End Function
Transforming Date Data

When importing data from a file to an OLE DB destination table, you can use the VBScript CDate function to convert date data if the date format is in a text or character field and is not in the format required by OLE DB, which is yyyy-mm-dd hh:mm:ss:sss. CDate is useful when the source data is in more than one format. If the source data is in a single format, then consider using the Date Time transformation, which is faster.

Function Main()

   DTSDestination("Total Sales") = DTSSource("Total Sales ")
   DTSDestination("DestColumnDate") = CDATE(DTSSource("SourceColumnDate"))

   Main = DTSTransformStat_OK

End Function
Reading Values from a Text File Using FileSystemObject

In the following VBScript example, the input text file, Start_End_Dates.txt, contains the start and end dates to be read into global variables. The text file is stored on the C:\ drive. The start date is the first line of text and contains "01/01/00" and the second line contains the end date, which is "01/31/00". After the package executes and the script runs, two message boxes are displayed. The first message box shows "The Start Date is: 01/01/00", and the second message box shows "The End Date is: 01/31/00".

' Read start and end dates from a flat file and 
' store the values in dynamically generated global variables
'Function Main()

    dim oFSO
    dim x

'  instantiate the Scripting Object
    set oFSO = CreateObject("Scripting.FileSystemObject")

'   Open the file
    set x = oFSO.OpenTextFile("C:\Start_End_Dates.txt")

'  store the first line, which is the Start Date, in a global variable
    DTSGlobalVariables("StartDate").value = x.Readline
    MsgBox "The Start Date is: " & DTSGlobalVariables("StartDate").value

'  store the second line, which is the End Date, in a global variable
    DTSGlobalVariables("EndDate").value = x.Readline
    MsgBox "The End Date is: " & DTSGlobalVariables("EndDate").value

    x.Close

    Main = DTSTaskExecResult_Success

End Function
Using an ADO Connection and Recordset to Check Records

The following ActiveX script creates a connection to the Northwind database and the employee table and counts the number of employee records. If employee records are found in the table, the script displays the number of employees and sends a success flag back to the package. Otherwise, the script sends a failure flag. Those flags can be used to trigger other tasks. For example, the success flag can signal that the table has records and then execute a Bulk Insert task. You can use the failure flag to execute a Send Mail task informing a database administrator (DBA) that a potential problem exists.

dim myConn
dim myRecordset
dim iRowCount

' instantiate the ADO objects
set myConn = CreateObject("ADODB.Connection")
set myRecordset = CreateObject("ADODB.Recordset")

' set the connection properties to point to the Northwind database,
' using the Customers table
myConn.Open = "Provider=SQLOLEDB.1;Data Source=(local); _
   Initial Catalog=Northwind;user id = 'sa';password=''"

mySQLCmdText = "Select 'rowcount' = Count(*) from Customers"

myRecordset.Open mySQLCmdText, myConn

set Flds = myRecordset.Fields
set iRowCount = Flds("rowcount")

If iRowCount.Value = 0 then
   Main = DTSTaskExecResult_Failure
Else
   MsgBox "The number of customers is: " & iRowCount.Value
   Main = DTSTaskExecResult_Success
End If
Inserting Rows into a Table using an ADO Recordset

The following example contains an ActiveX script written in VBScript that shows how to connect to a source using ADO and how to insert the rows into the destination table. The example uses tables from the Northwind database, and one that you must create, a NewEmployeeTerritory table that contains the EmployeeID and the new TerritoryID that the employee is assigned to. These new territory assignments need to be entered into the EmployeeTerritory table.

To run this example, do the following:

  1. Create a table named NewEmployeeTerritory in the Northwind database that has a schema identical to the EmployeeTerritory table.

  2. Insert the following four records into the NewEmployeeTerritory table:

    EmployeeID    TerritoryID

    1             03801
    1             07960
    3             40222
    9             11747
  3. Create a new DTS package in DTS Designer.

  4. Drag an ActiveX Script task onto the design sheet.

  5. In the ActiveX script box, place the following code between the FUNCTION MAIN() and END FUNCTION statements:
    ' These values were copied from the ADOVBS.INC file.
    '---- CursorTypeEnum Values ----
    Const adOpenForwardOnly = 0
    Const adOpenKeyset = 1
    Const adOpenDynamic = 2
    Const adOpenStatic = 3
    
    '---- CommandTypeEnum Values ----
    Const adCmdUnknown = &H0008
    Const adCmdText = &H0001
    Const adCmdTable = &H0002
    Const adCmdStoredProc = &H0004
    
    dim countr
    
    ' Instantiate the ADO objects.
    set mySourceConn = CreateObject("ADODB.Connection")
    set mySourceRecordset = CreateObject("ADODB.Recordset")
    
    'Set the connection properties to point to Northwind. 
    'Use the NewEmployeeTerritories table.
    mySourceConn.Open = "Provider=SQLOLEDB.1;Data Source=(local); _
        Initial Catalog=Northwind;user id = 'sa';password=''"
    
    mySQLCmdText = "Select * from NewEmployeeTerritories"
    
    'Execute the mySQLCmdText, and put the data into the myRecordset object. 
    mySourceRecordset.Open mySQLCmdText, mySourceConn, adOpenKeyset
    
    If mySourceRecordset.RecordCount < 1 Then
        MsgBox " There are no records found. Return a Failure code"
        Main = DTSTaskExecResult_Failure
    Else
    ' Since we have records to insert into the EmployeeTerritory table, create
    ' a Connection object and do the INSERT.
        dim EmpID, TerrID, myDestSQL
        set myDestConn = CreateObject("ADODB.Connection")
        myDestConn.Open = "Provider=SQLOLEDB.1;Data Source=(local); _
        Initial Catalog=Northwind;user id = 'sa'"
        
        for countr = 1 to mySourceRecordset.RecordCount
            EmpID = mySourceRecordset.Fields("EmployeeID").value
            TerrID = mySourceRecordset.Fields("TerritoryID").value
            ' Put single quotes around the TerrID since it is a varchar and         'needs to have the single quotes when it is in the VALUES list.
            TerrID = "'" & Terrid & "'"
    
            myDestSQL = "INSERT INTO EmployeeTerritories _
            VALUES ( " & EmpID & ","  & Terrid & ")"
            myDestConn.Execute myDestSQL
    
            mySourceRecordset.MoveNext
        Next
    
        Main = DTSTaskExecResult_Success
    
    End If
    
Validating Data

The following ActiveX script, written in VBScript, modifies data on a row-by-row basis. Using the Customers table of the Northwind database as a source, the script moves the data into a new destination table in Northwind. The script validates several columns in the source data and transforms some column data before the row is inserted into the destination. The transformations change the Company Name to uppercase characters, trim leading and trailing spaces from the first name and last name, and fill the Region field with the string "unknown" if it is empty.

' Verify that there is a CompanyName. If there is, process the record. If
' there is not, skip the record.
If DTSSource("CompanyName") <> "" Then
    DTSDestination("CustomerID") = DTSSource("CustomerID")
    ' Uppercase the Company Name
    DTSDestination("CompanyName") = Ucase(DTSSource("CompanyName"))
    ' Trim leading and trailing spaces from the Name 
    DTSDestination("ContactName") = Trim(DTSSource("ContactName"))
    DTSDestination("ContactTitle") = DTSSource("ContactTitle")
    DTSDestination("Address") = DTSSource("Address")
    DTSDestination("City") = DTSSource("City")

    ' Check to see if the region is empty. If it is, fill it with string 
    ' of "unknown".
    If IsNull(DTSSource("Region").value  then
        DTSDestination("Region") = "unknown"
    Else
        DTSDestination("Region") = DTSSource("Region")
        End if

    DTSDestination("PostalCode") = DTSSource("PostalCode")
    DTSDestination("Country") = DTSSource("Country")
    DTSDestination("Phone") = DTSSource("Phone")
    DTSDestination("Fax") = DTSSource("Fax")

    ' This was a successful row. Send an OK status back for this row.
    Main = DTSTransformStat_OK
Else
    ' This row contained data that could not be processed.
    ' Skip it and get another row.
    Main = DTSTransformStat_SkipRow
End If
Using a Global Variable that Contains Columns of Data

This example uses an Execute SQL task to select data from a table, and populate global variables with the data from the first row returned. Each column is stored in its own global variable. The second half of this sample uses ActiveX script to display the data stored in the global variables.

To save row values into global variables

Enterprise Manager

Enterprise Manager

To retrieve row value data

Enterprise Manager

Enterprise Manager

Using a Global Variable that Contains a Rowset

This sample uses an Execute SQL task to retrieve multiple rows from a table, and stores this rowset into a global variable. The second part of the example uses ActiveX scripting to display the rows stored in the global variable.

To save an entire rowset into a global variable

Enterprise Manager

Enterprise Manager

To retrieve the rowset data stored in a global variable

Enterprise Manager

Enterprise Manager

See Also

ActiveX Script Task

Data Driven Query Task

DTS Package Workflow

Transform Data Task

Using Global Variables with DTS Packages