Scenario: Download Script
Few days back, I wrote a post
How to Export Data to Multiple Excel Sheets from Single SQL Server Table in SSIS Packagewhich was dividing the data to multiple sheets depending upon distinct value in one of the column.
In this post, we are going to split the rows without using any column value. Think about a situation where you have 3.5 million records and you would like to write 500,000 on each of the excel sheet.
The package should be able to take number of rows per sheet as variable value so we can change anytime we like.
Solution:
We will be using script task in SSIS Package to split large number of records from SQL Server table to Excel Sheets.
Step 1: Create an SSIS Package and Variables
Open SSDT ( SQL Server data tools) and then create an SSIS Package. Create variables as shown below.
ExcelFileName : Provide The name of file you would like to create.
FolderPath : Provide the folder path in which your excel file will be created.
RecordCntPerSheet : This is the variable that will decide that how many records you would like to write to each excel sheet. I set to 3, as I want 3 records per sheet.
TableName: Provide the table name from which you would like to read the records.
Create variables in SSIS Package to create multiple excel sheets after split records from SQL Server Table by using Script Task
Step 2: Create ADO.NET Connection in SSIS Package to use in Script Task
Step 4: Add Script to Script task Editor in SSIS Package to export data to multiple excel sheets from single table
Click Edit Button and it will open Script Task Editor.
Under #region Namespaces, I have added below code
using System.IO;
using System.Data.OleDb;
using System.Data.SqlClient;
Under public void Main() {
I have added below code.
string datetime = DateTime.Now.ToString("yyyyMMddHHmmss");
try
{
//Declare Variables
string ExcelFileName = Dts.Variables["User::ExcelFileName"].Value.ToString();
string FolderPath = Dts.Variables["User::FolderPath"].Value.ToString();
string TableName = Dts.Variables["User::TableName"].Value.ToString();
Int32 RecordCntPerSheet =(Int32)Dts.Variables["User::RecordCntPerSheet"].Value;
string RecordCntPerSheetDecimal = RecordCntPerSheet + ".0";
ExcelFileName = ExcelFileName + "_" + datetime;
OleDbConnection Excel_OLE_Con = new OleDbConnection();
OleDbCommand Excel_OLE_Cmd = new OleDbCommand();
//Construct ConnectionString for Excel
string connstring = "Provider=Microsoft.ACE.OLEDB.12.0;" + "Data Source=" + FolderPath + ExcelFileName
+ ";" + "Extended Properties=\"Excel 12.0 Xml;HDR=YES;\"";
//drop Excel file if exists
File.Delete(FolderPath + "\\" + ExcelFileName + ".xlsx");
//USE ADO.NET Connection from SSIS Package to get data from table
SqlConnection myADONETConnection = new SqlConnection();
myADONETConnection = (SqlConnection)(Dts.Connections["DBConn"].AcquireConnection(Dts.Transaction) as SqlConnection);
//Read distinct Group Values for each Excel Sheet
string query = "select ceiling(count(*)/"+RecordCntPerSheetDecimal+") AS LoopCnt from" + TableName;
decimal LoopCnt = 0;
//Get the Count of Sheets need to be created
SqlCommand cmd = myADONETConnection.CreateCommand();
cmd.CommandText = query;
LoopCnt = (decimal)cmd.ExecuteScalar();
string SheetName = "Sheet";
int startRowCnt=0;
int endRowCnt = RecordCntPerSheet;
for (int sheetloop=1; sheetloop <= LoopCnt; sheetloop++)
{
//Load Data into DataTable from SQL ServerTable
string queryString =";with cte as (Select *, Row_Number() over (order by (Select 1)) AS RowNumber from"+
TableName+") Select * From cte where RowNumber > "+startRowCnt.ToString()+" and RowNumber<="+endRowCnt.ToString();
SqlDataAdapter adapter = new SqlDataAdapter(queryString, myADONETConnection);
DataSet ds = new DataSet();
adapter.Fill(ds);
//Get Header Columns
string TableColumns = "";
// Get the Column List from Data Table so can create Excel Sheet with Header
foreach (DataTable table in ds.Tables)
{
foreach (DataColumn column in table.Columns)
{
TableColumns += column + "],[";
}
}
// Replace most right comma from Columnlist
TableColumns = ("[" + TableColumns.Replace(",", " Text,").TrimEnd(','));
TableColumns = TableColumns.Remove(TableColumns.Length - 2);
//MessageBox.Show(TableColumns);
//Use OLE DB Connection and Create Excel Sheet
Excel_OLE_Con.ConnectionString = connstring;
Excel_OLE_Con.Open();
Excel_OLE_Cmd.Connection = Excel_OLE_Con;
Excel_OLE_Cmd.CommandText = "Create table [" + SheetName +sheetloop.ToString()+ "] (" + TableColumns + ")";
Excel_OLE_Cmd.ExecuteNonQuery();
//Write Data to Excel Sheet from DataTable dynamically
foreach (DataTable table in ds.Tables)
{
String sqlCommandInsert = "";
String sqlCommandValue = "";
foreach (DataColumn dataColumn in table.Columns)
{
sqlCommandValue += dataColumn + "],[";
}
sqlCommandValue = "[" + sqlCommandValue.TrimEnd(',');
sqlCommandValue = sqlCommandValue.Remove(sqlCommandValue.Length - 2);
sqlCommandInsert = "INSERT into [" + SheetName+sheetloop.ToString() + "] (" + sqlCommandValue + ") VALUES(";
int columnCount = table.Columns.Count;
foreach (DataRow row in table.Rows)
{
string columnvalues = "";
for (int i = 0; i < columnCount; i++)
{
int index = table.Rows.IndexOf(row);
columnvalues += "'" + table.Rows[index].ItemArray[i] + "',";
}
columnvalues = columnvalues.TrimEnd(',');
var command = sqlCommandInsert + columnvalues + ")";
Excel_OLE_Cmd.CommandText = command;
Excel_OLE_Cmd.ExecuteNonQuery();
}
}
startRowCnt += RecordCntPerSheet;
endRowCnt += RecordCntPerSheet;
Excel_OLE_Con.Close();
}
Dts.TaskResult = (int)ScriptResults.Success;
}
catch (Exception exception)
{
// Create Log File for Errors
using (StreamWriter sw = File.CreateText(Dts.Variables["User::FolderPath"].Value.ToString() + "\\" +
Dts.Variables["User::ExcelFileName"].Value.ToString() + datetime + ".log"))
{
sw.WriteLine(exception.ToString());
Dts.TaskResult = (int)ScriptResults.Failure;
}
}
Step 5: Save the Script and Run your SSIS Package to load data to multiple Excel Sheets from SQL Server Table by splitting depending upon number of rows
Save the script and close the windows. Your SSIS Package is read to read data from SQL Server table and will split to multiple sheets depending upon the total number of records and RecordsCntPerSheet variable value.
I execute my package after setting the RecordsCntPerSheet value=3. I had total 11 records in my table. It create an excel file with 4 sheets as can be seen below. First three sheets will have three records and 4th will have only 2 records.
How to split large table data to multiple excel sheets by using SSIS Package- Script Task