根据单元格位置将选择性字段从 Excel 批量插入到 SQL

2024-04-26

我有一个 SSIS 包,我必须从 Excel 工作表中选择一些值并将它们插入到 SQL Server 数据库表中,我是通过执行 sql 任务来完成的。

这些是步骤:

  1. 从映射表中选择所有记录,单元格位置是动态的,因此将其保留在 SQL 表中(大约有 3000 个单元格 - 我们必须从 Excel 中的选择性字段中选择值,而不是全部)

例子:

  1. 迭代Foreach在每条记录上

  2. 使用单元格名称和工作表名称创建查询

    例子:Select * from [GenDet$F3:F3]

  3. 执行查询以从 Excel 工作表中获取该单元格的值

例子:

  1. 将值插入到sql数据库表中

它正在工作 - 但问题是它所花费的时间。对于 3000 个字段,处理一个 Excel 文件需要 50 分钟。我必须在一分钟之内完成这件事。

请让我知道实现这一目标的最佳方法。

谢谢你!


正如我在评论中提到的,我认为编写一个 C# 脚本从 Excel 单元格中读取数据并将它们分组到列表或数据表中,然后执行一次批量插入会提高性能

C# 应用程序/脚本任务

所需组件

首先,您必须导入 Excel Interop 程序集:

using Microsoft.Office.Interop.Excel;
using System.Data.SqlClient;

将列标题字母转换为索引

现在您应该定义以下函数,将 Excel 列字母表转换为索引:

private int ParseColHeaderToIndex(string colAdress)
{
    int[] digits = new int[colAdress.Length];
    for (int i = 0; i < colAdress.Length; i++)
    {
        digits[i] = Convert.ToInt32(colAdress[i]) - 64;
    }
    int mul = 1;
    int res = 0;
    for (int pos = digits.Length - 1; pos >= 0; pos--)
    {
        res += digits[pos] * mul;
        mul *= 26;
    }
    return res;
}

SQL批量插入功能

以下函数是对SQL执行批量插入操作

public void InsertToSQLUsingSQLBulk(System.Data.DataTable dt, string connectionstring, string Tablename)
{


    try
    {
        using (var bulkCopy = new SqlBulkCopy(connectionstring, SqlBulkCopyOptions.KeepIdentity))
        {

            foreach (DataColumn col in dt.Columns)
            {
                bulkCopy.ColumnMappings.Add(col.ColumnName, col.ColumnName);
            }

            bulkCopy.BulkCopyTimeout = 600;
            bulkCopy.DestinationTableName = Tablename;
            bulkCopy.WriteToServer(dt);
        }

    }
    catch (Exception ex)
    {
        throw ex;
    }
}

从 Excel 读取到目标 DataTable

以下函数采用 Excel 路径和范围 DataTable 作为参数,并返回具有目标结构的 DataTable(ID、属性键、属性值)

public System.Data.DataTable ReadFromExcel(System.Data.DataTable dtRanges,string strPath)
{

    string num = "0123456789";

    //Declare result datatable  
    System.Data.DataTable destination = new System.Data.DataTable();
    destination.Columns.Add("Id");
    destination.Columns.Add("AttributeKey");
    destination.Columns.Add("AttributeValue");

    //Decalre Interop Objects
     Microsoft.Office.Interop.Excel.Application m_XlApp;
     m_XlApp = new Microsoft.Office.Interop.Excel.Application();
     m_XlApp.Visible = false;
     m_XlApp.DisplayAlerts = false;

     Workbook xlWbs = null;
     xlWbs = m_XlApp.Workbooks.Open(strPath, Type.Missing, Type.Missing, 
                                   Type.Missing, "'", Type.Missing, Type.Missing, 
                                   Type.Missing, Type.Missing, Type.Missing, 
                                   Type.Missing, Type.Missing, Type.Missing, 
                                   Type.Missing, Type.Missing);

    xlWbs.DoNotPromptForConvert = true;
    xlWbs.CheckCompatibility = false;
    xlWbs.Application.DisplayAlerts = false;

    //Loop over worksheets
    foreach (Worksheet xlWks in xlWbs.Worksheets) {

        string Name = xlWks.Name;

        //Assing rows relevant to the current sheet

        foreach (DataRow drRow in dtRanges.AsEnumerable().Where(x => x["Sheet_Name"].ToString() == Name))
        {

            string sheet = drRow["Sheet_Name"].ToString();
            string range = drRow["Location_Value"].ToString();
            string field = drRow["Field_Name"].ToString();
            string id = drRow["Id"].ToString();
            string rangeAlpha = range.Split(':')[0];
            int rowidx = 0;
            int colidx = 0;



            foreach (char chr in num) { 
                rangeAlpha = rangeAlpha.Replace(chr, '\0');
            }

            rowidx = Int32.Parse(range.Split(':')[0].Replace(rangeAlpha, ""));
            colidx = ParseColHeaderToIndex(rangeAlpha);


            DataRow dr = destination.NewRow();

            if (xlWks.Cells[rowidx, colidx] != null && (xlWks.Cells[rowidx, colidx] as Range).Value2 != null)
            {

                dr["AttributeValue"] = (string)(xlWks.Cells[rowidx, colidx] as Range).Value2;
            }
            else
            {
                dr["AttributeValue"] = "";
            }



            dr["AttributeKey"] = drRow["Field_Name"].ToString();
            dr["Id"] = drRow["Id"].ToString();

            destination.Rows.Add(dr);
        }

    }

    xlWbs.Close(false, Type.Missing, Type.Missing);
    m_XlApp.Quit();
    System.Runtime.InteropServices.Marshal.ReleaseComObject(xlWbs);
    System.Runtime.InteropServices.Marshal.ReleaseComObject(m_XlApp);


    return destination;

}

主程序

public void Main(){

    //Initialize ranges table
    System.Data.DataTable ranges = new System.Data.DataTable();
    ranges.Columns.Add("Id");
    ranges.Columns.Add("Field_Name");
    ranges.Columns.Add("Location_Value");
    ranges.Columns.Add("Sheet_Name");

    //Add rows or read them from database using SQLDataAdapter


    //note that the destination table must exists in the database with identical columns of datatable

    System.Data.DataTable destination = ReadFromExcel(ranges, "C:\\1.xlsx", "dbo.destination");

    InsertToSQLUsingSQLBulk(destination, "Pass SQL Server destination connection string here");



}

更新 1 - 提高性能

您可以通过将所有工作表内容放入二维数组中,然后循环数组而不是在 Excel 工作表内循环来提高方法性能。

Excel.Range targetCells = xlWks.UsedRange;
object[,] allValues = (object[,])targetCells.Cells.Value;

...


 if (targetCells.Cells[rowidx, colidx] != null)
 {

     dr["AttributeValue"] = (string)(targetCells.Cells[rowidx, colidx] as Range).Value2;
  }
  else
  {
     dr["AttributeValue"] = "";
  }

参考

  • 使用 Interop 从 Excel 文件中删除空行和空列的最快方法 https://stackoverflow.com/questions/40574084/fastest-method-to-remove-empty-rows-and-columns-from-excel-files-using-interop
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

根据单元格位置将选择性字段从 Excel 批量插入到 SQL 的相关文章

  • 意外的查询结果

    为什么我从 sql server 得到以下结果 SELECT 12 C1 CONVERT int C2 CASE WHEN THEN equal ELSE not equal END C3 Sql Server Fiddle 演示 http
  • SQL返回两行之间的秒差

    这个问题与SQL Server有关 我有下表 id size batch code product code additiontime 1 91 55555 BigD Red 2017 05 15 13 00 00 2 91 55555 B
  • 更改列时快速删除并重新创建多个索引、视图、统计信息

    我的 项目 表中有一个 StoreNumber 列 我想将其更改为 NOT NULL 我最近清理了所有旧数据 以便不存在空条目 但是 当我执行以下语句时 由于对各种视图 索引和统计信息的多重依赖 它失败了 ALTER TABLE Proje
  • 删除 VBA 按钮集合

    我正在使用以下脚本在 Excel 中生成按钮 范围正是我希望放置它的位置 Sub CreateAddButton rng As Range Dim btn As Button With Worksheets User Set btn But
  • st_intersects 与 st_overlaps

    这两个查询有什么区别 select a gid sum length b the geom from polygons as a roads as b where st intersects a the geom b the geom gr
  • 从Excel单元格中提取固定长度的数字

    一些类似名称的线程 但仍然无法解决我的问题 我需要从 Excel 字符串中提取固定长度的 NUMBER 值 在我的场景中为 8 位数字 为此目的提供了以下 Excel 公式 MID A1 FIND SUBSTITUTE SUBSTITUTE
  • 如何获取活跃的Excel实例?

    我有一个 C 应用程序 该应用程序根据用户需求将信息粘贴到 excel 背后的逻辑是这样的 如果没有正在运行的 excel 实例 它会创建一个实例并粘贴到该实例 如果只有一个实例在运行 它会尝试获取该实例并使用它 这是我用来执行此操作的代码
  • 有没有办法使用 Python Pandas 读取所有行,直到遇到空行

    我在 Excel 中有很多行 并且这些行在空行之后填充有垃圾值 有没有办法使用 Python pandas 只读取 Excel 中第一个空行之前的记录 我不知道 read excel 是否可以做到这一点 如果您从 Excel 导入空行 这些
  • 将数据从 R 导出到 Excel

    我试图将从 R 获得的一些结果导出到 Excel 中 但未成功 我尝试过以下代码 write table ALBERTA1 D ALBERTA1 txt sep t write csv ALBERTA1 ALBERTA1 csv your
  • 使用 Dapper 插入时出现 NullReferenceException

    当我运行以下代码时 我收到一个 NullReferenceException 异常 指出对象引用未设置到该对象的实例 我已经使用不太复杂但格式相同的对象成功插入了 dapper 所以我不确定我做错了什么 public void Foo IE
  • 删除数据库中的行后如何重新排序ID

    我正在使用 C 来制作具有 sql 数据库的程序 在数据库中我有一个名为Workers 它有一个自动增量和主键ID column 当我删除一条记录时 ID 之间会出现间隙 删除记录后如何重新排序 ID UPDATE 我要做的就是找到记录后将
  • Python循环遍历Excel工作表,将工作表名称添加到列表中,然后连接所有

    我正在循环遍历 Excel 工作表并将它们附加到列表中 循环完成后 我使用 Pandas 连接到单个数据帧 我遇到的问题是将工作表名称添加到适当的列表中 infile is a filepath variable xls xlrd open
  • python XlsxWriter 设置多个单元格周围的边框

    I need an easy way to set border around multiple cells like so 我发现的只是 1 个单元格的边框 并合并单元格 这不是我需要的 我期待类似的事情 worksheet range
  • 日期语句之间的 JPQL SELECT [关闭]

    Closed 这个问题是无法重现或由拼写错误引起 help closed questions 目前不接受答案 我想将此 SQL 语句转换为等效的 JPQL SELECT FROM events WHERE events date BETWE
  • MYSQL从每个类别中随机选择一条记录

    我有一个数据库Items表看起来像这样 id name category int 有几十万条记录 每个item可以是 7 种不同的之一categories 对应于categories table id category 我想要一个从每个类别
  • SQL 约束以防止根据列的先前值更新列

    是否可以使用检查约束 或其他一些技术 来防止在更新记录时设置与其先前值相矛盾的值 一个例子是 NULL 时间戳 表明发生了某些事情 例如 file exported 一旦文件被导出并且具有非 NULL 值 就不应再将其设置为 NULL 另一
  • Excel VSTO 工作簿新活动

    在 Excel 2007 的一个 Excel 插件项目中 我需要检查创建新工作簿的事件 我还需要捕捉 Workbook Open 事件 我很容易做到这一点 在我在互联网上的研究中 我发现了以下内容 打开任何工作簿时都会引发 Applicat
  • SQL Server 数据库架构版本控制和更新

    对于我的应用程序 我必须支持更新方案 并且数据库可能会受到影响 我希望能够从旧版本更新到最新版本 而无需安装中间版本 例如 假设我有版本 A 最旧的版本 B 中间版本 和 C 新版本 我希望能够将版本 A 直接更新到版本 C 对于应用程序文
  • 如何部署“SQL Server Express + EF”应用程序

    这是我第一次部署使用 SQL Server Express 数据库的应用程序 我首先使用实体 框架模型来联系数据库 我使用 Install Shield 创建了一个安装向导来安装应用程序 这些是我在目标计算机中安装应用程序所执行的步骤 安装
  • SQL 更新 - 更新选定的行

    我正在使用 SQL Server 2008 我有一个名为MYTABLE有两列 ID STATUS 我想编写一个存储过程来返回其记录STATUS是 0 但是这个存储过程必须更新STATUS返回行数为 1 如何在单个查询中执行此选择和更新操作

随机推荐

  • 如何在 swiftui 中使用 .quickLookPreview 修饰符

    我正在尝试使用视图修饰符 quickLookPreview在 iOS 14 macOS 11 macCatalyst 14 中引入 但我收到此错误Value of type some View has no member quickLook
  • 在 Firefox 上使用 popState 平滑滚动和返回按钮 - 需要单击两次

    我正在尝试实现一个小代码 当我单击锚点时 并且锚点名称出现在动画之后 我可以使用它实现平滑滚动 并且如果我按下浏览器的后退按钮 我想返回到页面顶部并更新 URL 不带 anchor 名称 这是代码 function Smooth scrol
  • 无法更新 Android Studio 中的 JDK 位置

    我无法在 Android Studio 中更新 Java JDK 或 Android SDK 路径 要更新默认的 JDK 或 Android SDK 打开Android Studio 转到快速启动 gt 配置 gt 项目默认值 gt 项目结
  • 画布绘制文本定位

    我正在创建一个绘图工具 用户可以在其中向图像添加文本 当通过画布位置将文本绘制到位图时 未正确设置 Paint paint new Paint paint setStyle Paint Style FILL paint setColor C
  • 如何使用没有按钮的 jQuery UI 图标?

    jQuery UI 带有一些很好的图标 没有按钮我该如何使用它们 让我们说一下如何创建链接plus签名并通过更改图标对悬停和单击做出反应 Here http jsfiddle net and7ey gZQzt 是仅添加图标的演示 Upd 1
  • python 遍历文件中的行

    我见过这两种处理文件的方法 file open file txt for line in file do something file open file txt contents file read for line in content
  • 无与伦比的括号宏怪异

    根据 C99 规则预处理以下 3 行的正确输出是什么 define y x x define x a y a x 1 x 2 顺便说一句 linux 下的 cpp 会产生错误消息 但我不明白为什么答案不简单 1 2 假设 cpp 是正确的而
  • 以编程方式自动填充 UAC 详细信息

    有没有办法通过编程方式在 Visa 中自动填写 UAC 登录名和密码 例如 出现UAC提示 您的程序会自动为您填写该信息 例如 一个程序会在 UAC 提示符中使用管理员用户名和密码自动填充该信息 SendKeys 无法将输入键发送到 UAC
  • 如何在 Inno Setup 中为控件卷出设置动画

    我想在我的安装程序中制作控件滚动的动画 你可以看这个视频 https drive google com file d 1H0HKTPXg9BdYD4HQWqCWHlGSTIHlcJa view 您可以使用计时器来为控件设置动画 Code f
  • 知道axios中是否有待处理的请求

    我是 ReactJS 的新手 对于我的 ajax 调用 我尝试使用Axios https github com mzabriskie axios图书馆 太棒了 但现在我想知道是否有办法知道 axios 拦截器中是否有待处理的请求 因为我想显
  • 单击旁边的按钮时如何引用动态创建的标签 [Qt]

    每次按下 添加客户端 按钮时 减号按钮 客户端名称 客户端计数器和加号按钮都会以水平线添加到网格布局中 我想在按下加号 减号按钮时更新计数 QLabel 这是我的代码 include widget h include ui widget h
  • Flask-PyMongo collMod

    我正在尝试使用 PyMongo 更新 TTL 集合 试图运行这个我得到 失败没有这样的命令 索引 client db command collMod url index keyPattern dateCreated 1 expireAfte
  • 什么是二叉搜索树中的“内部节点”?

    我正在互联网上搜索 内部节点 一词的定义 我找不到简洁的定义 我正在查看的每个来源都使用该术语但没有定义它 并且这种用法并不能产生内部节点实际是什么的正确定义 这是我主要看的两个地方 Link https planetmath org Ex
  • Solr 中的多值字段排序

    我有一个 Solr 索引 将每个产品的价格存储在多值字段中 我需要按价格对结果集进行排序 其中价格从低到高 从高到低 我尝试对价格进行排序 它显示错误您无法对 multivalued True 字段进行排序 下面是我的 solr XML
  • Javadoc 错误 - java.lang.reflect.InitationTargetException

    我正在尝试从 yDoc 库生成 uml 图 它基本上使用 Javadoc 来解析 Java 源文件 但是 当我尝试从终端 OS X 执行命令时 出现以下错误 javadoc error In doclet class ydoc doclet
  • C++ - 通过添加字节整数来向前移动 char 指针是否合法/推荐?

    我正在寻找一些方法来将指针推进到压缩档案中的文件开头 我有一个指向已读入内存的文件开头的字符指针 归档目录包含每个文件的偏移量 是否合法 建议这样说 char beginning Imagine this is assigned to th
  • Azure API 管理:原始标头丢失或为空,并且请求被分类为非跨域。未应用 CORS 政策

    我正在使用 Azure API 管理 并且需要使用它来管理三个 API 测试时 GET 方法工作正常 但是 post 方法出现以下错误 原始标头丢失或为空 并且请求被归类为非跨域 未应用 CORS 政策 我进行了搜索并发现了一些 CORS
  • Apache Camel:如何存储变量以供以后使用

    在使用 Spring DSL 玩 Camel 时 我遇到了以下问题 假设预期的消息流如下所示 客户端将带有 XML 正文的 HTTP POST 消息发送给 CAMEL CAMEL 向服务器代理 HTTP POST 消息 并使用稍微调整的 U
  • 从 uiwebview Xcode 获取选定的文本

    我有一个UIWebView从加载文本htmlString 我需要当用户选择文本的一部分并按下按钮时 我将能够提取它以便在其他地方使用它 所以我使用以下代码 The JS File NSString filePath NSBundle mai
  • 根据单元格位置将选择性字段从 Excel 批量插入到 SQL

    我有一个 SSIS 包 我必须从 Excel 工作表中选择一些值并将它们插入到 SQL Server 数据库表中 我是通过执行 sql 任务来完成的 这些是步骤 从映射表中选择所有记录 单元格位置是动态的 因此将其保留在 SQL 表中 大约