#region Help: Introduction to the script task /* The Script Task allows you to perform virtually any operation that can be accomplished in * a .Net application within the context of an Integration Services control flow. * * Expand the other regions which have "Help" prefixes for examples of specific ways to use * Integration Services features within this script task. */ #endregion #region Namespaces using System; using System.Collections.Generic; using System.Data; //using System.Data.OleDb; using System.Data.SqlClient; using System.IO; using System.Linq; using System.Text; #endregion namespace ST_8b9be16f34c14ea4aeb5d577603fc970 { /// /// ScriptMain is the entry point class of the script. Do not change the name, attributes, /// or parent of this class. /// [Microsoft.SqlServer.Dts.Tasks.ScriptTask.SSISScriptTaskEntryPointAttribute] public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase { #region Help: Using Integration Services variables and parameters in a script /* To use a variable in this script, first ensure that the variable has been added to * either the list contained in the ReadOnlyVariables property or the list contained in * the ReadWriteVariables property of this script task, according to whether or not your * code needs to write to the variable. To add the variable, save this script, close this instance of * Visual Studio, and update the ReadOnlyVariables and * ReadWriteVariables properties in the Script Transformation Editor window. * To use a parameter in this script, follow the same steps. Parameters are always read-only. * * Example of reading from a variable: * DateTime startTime = (DateTime) Dts.Variables["System::StartTime"].Value; * * Example of writing to a variable: * Dts.Variables["User::myStringVariable"].Value = "new value"; * * Example of reading from a package parameter: * int batchId = (int) Dts.Variables["$Package::batchId"].Value; * * Example of reading from a project parameter: * int batchId = (int) Dts.Variables["$Project::batchId"].Value; * * Example of reading from a sensitive project parameter: * int batchId = (int) Dts.Variables["$Project::batchId"].GetSensitiveValue(); * */ #endregion #region Help: Firing Integration Services events from a script /* This script task can fire events for logging purposes. * * Example of firing an error event: * Dts.Events.FireError(18, "Process Values", "Bad value", "", 0); * * Example of firing an information event: * Dts.Events.FireInformation(3, "Process Values", "Processing has started", "", 0, ref fireAgain) * * Example of firing a warning event: * Dts.Events.FireWarning(14, "Process Values", "No values received for input", "", 0); * */ #endregion #region Help: Using Integration Services connection managers in a script /* Some types of connection managers can be used in this script task. See the topic * "Working with Connection Managers Programatically" for details. * * Example of using an ADO.Net connection manager: * object rawConnection = Dts.Connections["Sales DB"].AcquireConnection(Dts.Transaction); * SqlConnection myADONETConnection = (SqlConnection)rawConnection; * //Use the connection in some code here, then release the connection * Dts.Connections["Sales DB"].ReleaseConnection(rawConnection); * * Example of using a File connection manager * object rawConnection = Dts.Connections["Prices.zip"].AcquireConnection(Dts.Transaction); * string filePath = (string)rawConnection; * //Use the connection in some code here, then release the connection * Dts.Connections["Prices.zip"].ReleaseConnection(rawConnection); * */ #endregion //User::DatabaseConnectionName,User::DataImportID,User::ExternalDataSourceID,User::Filename private string dbConnectionName; private Int64 dataImportID; private Int64 externalDataSourceID; private string sourceFilename; private Int64 rowImportCount = 0; SqlConnection dbConnection; FileReader sourceFileReader; List columnMapping = new List(); private const int commitSize = 10000; /// /// This method is called when this script task executes in the control flow. /// Before returning from this method, set the value of Dts.TaskResult to indicate success or failure. /// To open Help, press F1. /// public void Main() { try { SetVariables(); SetupDatabaseConnection(); SetupSourceFileConnection(); BuildColumnMapping(); Transfer(); SetOutputVariables(); this.sourceFileReader.Close(); Dts.TaskResult = (int)ScriptResults.Success; } catch(Exception ex) { FireError(ex.Message); if (ex.InnerException != null) FireError(ex.InnerException.Message); Dts.TaskResult = (int)ScriptResults.Failure; } finally { if (sourceFileReader != null) sourceFileReader.Dispose(); } } private void SetVariables() { //User::DatabaseConnectionName,User::DataImportID,User::ExternalDataSourceID,User::Filename this.dbConnectionName = (string)Dts.Variables["User::DatabaseConnectionName"].Value; this.dataImportID = (Int64)Dts.Variables["User::DataImportID"].Value; this.externalDataSourceID = (Int64)Dts.Variables["User::ExternalDataSourceID"].Value; //27 this.sourceFilename = (string)Dts.Variables["User::Filename"].Value; } private void SetOutputVariables() { Dts.Variables["User::RowImportCount"].Value = Convert.ChangeType(this.rowImportCount, Dts.Variables["User::RowImportCount"].DataType); } void SetupDatabaseConnection() { this.dbConnection = Dts.Connections[this.dbConnectionName].AcquireConnection(Dts.Transaction) as SqlConnection; if (dbConnection.State != ConnectionState.Open) dbConnection.Open(); FireInformation(string.Format("Database Connection Manager: {0}", dbConnectionName)); } void SetupSourceFileConnection() { this.FireInformation(string.Format("Opening {0}", this.sourceFilename)); this.sourceFileReader = new FileReader(this.sourceFilename, this.dataImportID); this.FireInformation(string.Format("Source file has {0} columns.", this.sourceFileReader.FieldCount)); } void BuildColumnMapping() { this.FireInformation("Building column mapping."); using (var cmd = this.dbConnection.CreateCommand()) { // cmd.CommandText = @" // SELECT // EDSM.SourceColumnName, // EDSM.DestinationTableName, // EDSM.DestinationColumnName, // CAST(CASE WHEN C.IS_NULLABLE = 'YES' THEN 1 ELSE 0 END AS bit) DestinationColumnIsNullable, // C.DATA_TYPE DestinationColumnType, // C.CHARACTER_MAXIMUM_LENGTH DestinationColumnCharLength // FROM // ( // SELECT // EDSM.ExternalFieldName SourceColumnName, // LEFT(EDSM.ElementPath, CHARINDEX('.', EDSM.ElementPath) - 1) DestinationTableName, // SUBSTRING(EDSM.ElementPath, CHARINDEX('.', EDSM.ElementPath) + 1, 100) DestinationColumnName // FROM dbo.ExternalDataSourceMapping EDSM // WHERE EDSM.ExternalDataSourceID = @ExternalDataSourceID // ) EDSM // JOIN INFORMATION_SCHEMA.COLUMNS C ON EDSM.DestinationTableName = C.TABLE_NAME AND EDSM.DestinationColumnName = C.COLUMN_NAME // ORDER BY C.ORDINAL_POSITION // "; cmd.CommandText = @" SELECT EDSM.SourceColumnName, EDSM.DestinationTableName, EDSM.DestinationColumnName, CAST(CASE WHEN C.is_nullable = 'YES' THEN 1 ELSE 0 END AS bit) AS DestinationColumnIsNullable, C.DATA_TYPE AS DestinationColumnType, C.CHARACTER_MAXIMUM_LENGTH AS DestinationColumnCharLength FROM ( SELECT EDSM.ExternalFieldName AS SourceColumnName, LEFT(EDSM.ElementPath, strpos(EDSM.ElementPath, '.') - 1) AS DestinationTableName, SUBSTRING(EDSM.ElementPath, strpos(EDSM.ElementPath, '.') + 1, 100) AS DestinationColumnName FROM dbo.ExternalDataSourceMapping EDSM WHERE EDSM.ExternalDataSourceID = @ExternalDataSourceID ) EDSM JOIN information_schema.columns C ON lower(EDSM.DestinationTableName) = C.table_name AND lower(EDSM.DestinationColumnName) = C.column_name ORDER BY C.ordinal_position; "; cmd.CommandType = CommandType.Text; cmd.Parameters.AddWithValue("@ExternalDataSourceID", this.externalDataSourceID); using (var reader = cmd.ExecuteReader()) { while (reader.Read()) { this.columnMapping.Add(new ColumnMapping( sourceColumnName: reader.GetString(0), destinationTableName: reader.GetString(1), destinationColumnName: reader.GetString(2), destinationColumnIsNullable: reader.GetBoolean(3), destinationColumnType: reader.GetString(4), destinationColumnCharLength: reader.GetNullableInt32(5) )); } } } if (this.columnMapping.Count == 0) throw new Exception(string.Format("No source - destination column mapping found for ExternalDataSourceID={0}", this.externalDataSourceID)); } void Transfer() { this.rowImportCount = 0; DateTime end = DateTime.Now; TimeSpan duration = TimeSpan.MinValue; DateTime start = DateTime.Now; using (var bulkCopy = new SqlBulkCopy(this.dbConnection)) { bulkCopy.BatchSize = commitSize; bulkCopy.NotifyAfter = commitSize; bulkCopy.DestinationTableName = this.columnMapping.First().TableName; bulkCopy.SqlRowsCopied += (sender, e) => { this.rowImportCount = e.RowsCopied; FireInformation(string.Format("{0} rows inserted.", e.RowsCopied)); }; bulkCopy.ColumnMappings.Add("DataImportID", "DataImportID"); bulkCopy.ColumnMappings.Add("RowNumber", "RowNumber"); this.columnMapping.ForEach(cm => { if (!string.IsNullOrEmpty(this.sourceFileReader.Headers.Find(h => string.Compare(h, cm.SourceColumnName, true) == 0))) { bulkCopy.ColumnMappings.Add(cm.SourceColumnName, cm.ColumnName); this.sourceFileReader.SetFieldType(cm.SourceColumnName, cm.ColumnType); } }); bulkCopy.WriteToServer(this.sourceFileReader); this.rowImportCount = this.sourceFileReader.RecordsAffected; FireInformation(string.Format("{0} rows inserted.", this.rowImportCount)); } } void FireError(string description, int errorCode = 0, string subComponent = "") { Dts.Events.FireError(errorCode, subComponent, description, "", 0); } void FireInformation(string description, int informationCode = 0, string subComponent = "") { bool fireAgain = true; Dts.Events.FireInformation(informationCode, subComponent, description, "", 0, ref fireAgain); } void FireWarning(string description, int warningCode = 0, string subComponent = "") { Dts.Events.FireWarning(warningCode, subComponent, description, "", 0); } #region ScriptResults declaration /// /// This enum provides a convenient shorthand within the scope of this class for setting the /// result of the script. /// /// This code was generated automatically. /// enum ScriptResults { Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success, Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure }; #endregion } }