Я пытаюсь написать задачу скрипта в SSIS, которая запускает процедуру SQL на основе переменной, определяет имя и количество столбцов из результатов, а затем экспортирует их в таблицу Excel. Это основано на сайте / видео TechBrothersIT: http://www.techbrothersit.com/2016/03/how-to-create-excel-file-dynamically_21.html
Ошибка "System.Data.OleDb.OleDbException (0x80040E14): Количество значений запроса и полей назначения не являются одни и те же." происходит после запуска процедуры, когда он пытается вставить в таблицу, которую он строит. Я пытался найти ответ, но пока не видел, чтобы кто-нибудь использовал такие динамические столбцы c, поэтому все ответы, в которых говорится, что вы указываете свои столбцы для частей INSERT и VALUES, не применяются (из того, что я могу скажи).
При выполнении процедуры возвращаются шесть столбцов: филиал, клиент, часы, валовая оплата, W C премиум, GP $. Использование messagebox.show после динамической сборки в команду для создания таблицы подтверждает, что оно использует эти значения с правильным написанием и заключено в квадратные скобки. Из-за этого я считаю, что моя проблема в части ЗНАЧЕНИЯ, но я не могу понять это.
Что я здесь не так делаю?
using System;
using System.Data;
using Microsoft.SqlServer.Dts.Runtime;
using System.Windows.Forms;
using System.IO;
using System.Data.OleDb;
using System.Data.SqlClient;
namespace ST_0493a2bda5424767ac07ca96649a95e2
{
[Microsoft.SqlServer.Dts.Tasks.ScriptTask.SSISScriptTaskEntryPointAttribute]
public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
{
public void Main()
{
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 StoredProcedureName = Dts.Variables["User::StoredProcedureName"].Value.ToString();
string SheetName = Dts.Variables["User::SheetName"].Value.ToString();
string StartDate = Dts.Variables["User::StartDate"].Value.ToString();
string EndDate = Dts.Variables["User::EndDate"].Value.ToString();
string DBName = Dts.Variables["User::DBName"].Value.ToString();
string ServerName = Dts.Variables["User::ServerName"].Value.ToString();
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
+ ".xlsx;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("Data Source="+ServerName+";Initial Catalog="+DBName+";Integrated Security=true");
//Load Data into DataTable from SQL ServerTable
string queryString = "EXEC " + StoredProcedureName + " '" + StartDate + "', '" + EndDate + "', @RunInSSIS=1";
SqlDataAdapter adapter = new SqlDataAdapter(queryString, myADONETConnection);
DataSet ds = new DataSet();
adapter.Fill(ds);
//MessageBox.Show(queryString);
//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(",", " NVARCHAR(255),").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 + " (" + 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 + "(" + 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.Replace("'", "''") + "',";
}
columnvalues = columnvalues.TrimEnd(',');
var command = sqlCommandInsert + columnvalues + ")";
Excel_OLE_Cmd.CommandText = command;
Excel_OLE_Cmd.ExecuteNonQuery();
}
}
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;
}
}
}
enum ScriptResults
{
Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
};
}
}