获取 SSIS C# 脚本组件以通过 OleDb 从 Excel 读取:

Get an SSIS C# Script component to read from Excel via OleDb:

我正在尝试构建一个 SSIS 包以从 Excel 读取。我找到了一个非常接近我需要的例子

我的问题是:从一个空白解决方案开始,让 C# 脚本组件从 .xlsx 文件读取所需的最低限度步骤是什么?

这是我的代码:

using System;
using System.Data;
using System.Data.OleDb;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
using Microsoft.SqlServer.Dts.Runtime.Wrapper;

[Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
public class ScriptMain : UserComponent
{    
    public override void CreateNewOutputRows()
    {
        string fileName = @"E:\SFTP\RSS\Results.xlsx";    
        string cstr = "Provider.ACE.OLEDB.12.0;Data Source=" + fileName + ";Extended Properties=\"Excel 12.0;HDR=YES;IMEX=1\"";

        using (OleDbConnection xlConn = new OleDbConnection(cstr))
        {
            xlConn.Open();
            OleDbCommand xlCmd = xlConn.CreateCommand();
            xlCmd.CommandText = "Select top 10 * from Responses";
            xlCmd.CommandType = CommandType.Text;
            using (OleDbDataReader rdr = xlCmd.ExecuteReader())
            {
                while (rdr.Read())
                {
                    for (int i = 2; i < rdr.FieldCount; i++) //loop from 3 column to last
                    {
                        Output0Buffer.AddRow();
                        Output0Buffer.Question = rdr.GetName(i);
                        Output0Buffer.Response = rdr.ToString();
                    }

                }
            }
            xlConn.Close();
        }
    }

}

这些是我遇到的问题和问题: 我是否需要在解决方案级别配置连接管理器?在脚本组件上还是代码中包含我需要的一切?

我使用什么 datatype/function/method 来将单元格读取为数字、日期或字符串?

以下是我遇到的一些错误:

(2,14): error CS0234: The type or namespace name 'Data' does not exist in the namespace 'System' (are you missing an assembly reference?)
(3,14): error CS0234: The type or namespace name 'Data' does not exist in the namespace 'System' (are you missing an assembly reference?)
(4,17): error CS0234: The type or namespace name 'SqlServer' does not exist in the namespace 'Microsoft' (are you missing an assembly reference?)
(5,17): error CS0234: The type or namespace name 'SqlServer' does not exist in the namespace 'Microsoft' (are you missing an assembly reference?)
(8,27): error CS0246: The type or namespace name 'UserComponent' could not be found (are you missing a using directive or an assembly reference?)
 + additional 10 errors

我正在使用:VS2019,SQL Server 2016 SP2,Office 2016。

这是我的 Excel Sheet 的屏幕截图:

它包含对第 3 方呼叫中心提供的调查的回复。有几列可以识别呼叫,然后每列 header 包含问题,列数据是响应。它目前有 189 列,并且随着时间的推移将 grow/change。我的想法是 select 可靠地识别每一行的前 4 列加上每个问答的 1 个附加列,并遍历 sheet 选取每一列 header 和内容,以便可以插入一个table。随着更多列的添加,它们将作为附加行附加。我粘贴的示例代码只显示了 2 列,因为我试图使示例保持简单。

这是我试过的。 1. 将DataFlow 任务添加到Control Flow。

  1. 将脚本组件添加到 DataFlow。

出现提示时select来源。

双击打开编辑器。

Select 连接管理器。单击添加

在新行 select 新连接,

出现添加新的 SSIS 连接管理器。

这就是我卡住的地方。我一直在选择 OLEDB 连接。

  1. 在 OLEDB 连接管理器中我应该做什么 select?

我试过 Access 和 MS Oledb Simple Provider。事情开始在这里解开。鉴于脚本中提供了文件名、路径和 driver 详细信息,连接管理器需要哪些详细信息?

我开始玩代码,但我不知道我在上游所做的工作是否有效或是否正确。所以我想从头开始。我正在寻求帮助来完成设置步骤以到达 C# 点。

感谢大家的回复。

干杯

皮特

除了输出之外,没有什么需要添加到脚本组件 GUI 中(记住要正确设置数据类型。)

不要设置连接管理器,您在代码中这样做是因为您不希望 SSIS 试图找出您的列名,坦率地说,我们不知道第 4 列之后的列名。

这是您的代码。我只改变了一些东西。

public override void CreateNewOutputRows()
    {
        //Change this to your filename you do not need a connection manager
        string fileName = @"E:\SFTP\RSS\Results.xlsx";  
        string SheetName = "Sheet1";  
        string cstr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + fileName + ";Extended Properties=\"Excel 12.0;HDR=YES;IMEX=1\"";

        using (System.Data.OleDb.OleDbConnection xlConn = new System.Data.OleDb.OleDbConnection(cstr))
        {
           xlConn.Open();
           System.Data.OleDb.OleDbCommand xlCmd = xlConn.CreateCommand();
           xlCmd.CommandText = "Select * from [" + SheetName + "$]"; //I assume this is the data you want
           xlCmd.CommandType = CommandType.Text;
           using (System.Data.OleDb.OleDbDataReader rdr = xlCmd.ExecuteReader())
           {
              while (rdr.Read())
              {
                 for (int i = 4; i < rdr.FieldCount; i++) //loop from 5th column to last
                 {
                    //The first 4 columns are static and added to every row
                    Output0Buffer.AddRow();
                    Output0Buffer.UniqueID = Int32.Parse(rdr[0].ToString());
                    Output0Buffer.Year = Int32.Parse(rdr[1].ToString());
                    Output0Buffer.ReportingWave = rdr.GetString(2);
                    Output0Buffer.SubmissionDate = rdr.GetString(3);
                    Output0Buffer.Question = rdr.GetName(i);
                    Output0Buffer.Answer = rdr.GetString(i);
                 }

            }
          }
          xlConn.Close();
       }
    }

此代码成功导入了如下所示的文件: