gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-02 19:01:18 24 4
gpt4 key购买 nike

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

步骤如下:

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

示例:

enter image description here

  • 在每条记录上迭代 Foreach

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

    示例:从 [GenDet$F3:F3] 中选择 *

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

  • 示例:

    enter image description here

  • 将值插入 SQL 数据库表
  • enter image description here

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

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

    谢谢!

    最佳答案

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

    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, AttributeKey, AttributeValue)

    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"] = "";
    }

    引用

    关于sql - 根据单元格位置将选择性字段从 Excel 批量插入到 SQL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55009040/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com