Количество значений запроса и полей назначения не совпадают - C# Задача сценария SSIS - Экспорт результатов SQL Pro c в Excel с использованием колонок Dynami c - PullRequest
0 голосов
/ 10 января 2020

Я пытаюсь написать задачу скрипта в 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
        };

    }
}

1 Ответ

0 голосов
/ 13 января 2020

Я понял это. Я использовал messagebox.show во внутренней части for для l oop, чтобы увидеть, что именно строится, и он добавлял одиночную кавычку в начало оператора каждый раз, когда он видел новый столбец, туда, куда он смотрел как это: '' '' '' '' '[column]', [column2], et c ... '

Исправление включало установку значений столбца в' вместо пробела в начале , затем изменив значения столбцов, добавив ',' в конец внутреннего l oop, прежде чем окончательно обрезать лишние части в конце завершенного оператора. Я предполагаю, что это может быть сделано более чистым способом, но это решило мою проблему тем не менее:

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 += "','";
                            //MessageBox.Show(columnvalues);
                        }
                        columnvalues = columnvalues.TrimEnd('\'');
                        columnvalues = columnvalues.TrimEnd(',');

                        var command = sqlCommandInsert + columnvalues + ")";
                        //MessageBox.Show(command);

                        Excel_OLE_Cmd.CommandText = command;
                        Excel_OLE_Cmd.ExecuteNonQuery();
                    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...