获取一个SSIS C#脚本组件,通过OleDb从Excel读取。

问题描述 投票:0回答:1

我试图建立一个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();
        }
    }

}

这些是我遇到的问题,我的问题是: 我需要在解决方案层面配置连接管理器吗?在脚本组件上还是代码中包含了我需要的所有内容?

我用什么datatypefunctionmethod来读取一个单元格为数字、日期或字符串?

以下是我得到的一些错误。

(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的屏幕截图。

Responses

它包含了一个第三方呼叫中心提供的调查问卷的回复。有几个列来识别呼叫,然后每个列头包含问题,列数据是响应。它目前有189列,并将随着时间的推移而增长变化。我的想法是选择前4列,可靠地识别每行加上1列额外的每一个Q&amp;A,并迭代通过表拿起每个列头和内容,以便可以插入到一个表中。当添加更多的列时,它们就会被追加为额外的行。我粘贴的示例代码只显示了2列,因为我想让这个例子简单一些。

这是我试过的方法.1.在ControlFlow中添加一个DataFlow任务。在控制流中添加一个DataFlow任务。ControlFlow

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

当提示选择源。

双击并打开编辑器。

选择连接管理器。单击 "添加"。

在新行中选择新建连接。

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

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

  1. 在OLEDB连接管理器中,我应该选择什么?

我已经尝试了Access和MS Oledb Simple Provider。事情到这里就开始变得扑朔迷离了。既然脚本中提供了文件名、路径和驱动细节,那么我需要连接管理器的什么细节呢?

我开始玩代码,但我不知道我在上游所做的是否有效或正确。所以我想从头开始。我请求大家帮助我走过设置步骤,以达到C#点。

谢谢大家的回复。

欢呼

皮特

c# sql-server ssis oledb visual-studio-2019
1个回答
1
投票

脚本组件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();
       }
    }

这段代码成功导入了一个文件,这个文件看起来是这样的。

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.