将Excel导入到Sql Server数据库时,将数据类型nvarchar转换为数字时出错

本文关键字:转换 nvarchar 数字 出错 数据类型 Sql Server 数据库 Excel 导入 | 更新日期: 2023-09-27 18:09:03

我正在使用控制台应用程序脚本将excel文件导入Sql Server数据库。

    private static void ImportToSql(string ssqlconnectionstring, string query)
    {
        string query = "MERGE Inventory AS target USING (select LocalSKU,ItemName, QOH,ISNULL(Price,0.00),Discontinued,Integer2,Integer3 from @source)  as source ON (source.LocalSKU = target.LocalSKU) WHEN MATCHED THEN UPDATE SET ItemName=source.ItemName,Price=source.Price,Discontinued=source.Discontinued,Integer2=source.Integer2,Integer3=source.QOH;";
        string excelfilepath = Environment.CurrentDirectory + @"'Sheet1.csv";
        // make sure your sheet name is correct, here sheet name is sheet1, so you can change your sheet name if have different
        // string myexceldataquery = "select LocalSKU,ItemName,QOH,Price,Discontinued,Barcode,Integer2,Integer3,SalePrice,SaleOn,Price2 from [sheet1$]";
        string myexceldataquery = "select LocalSKU,ItemName, QOH,Price,Discontinued,Integer2,Integer3 from [sheet1$]";
        try
        {
            // string sexcelconnectionstring = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + excelfilepath + ";Extended Properties=Excel 12.0;";
            string sexcelconnectionstring = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source =" + excelfilepath + "; Extended Properties='"Excel 12.0; HDR=Yes; IMEX=2; ImportMixedTypes=Text;'"";
            //string ssqlconnectionstring = "Data Source=User-PC''Dell;Trusted_Connection=True;DATABASE=TestStore;CONNECTION RESET=FALSE";
            SqlConnection sqlconn = new SqlConnection(ssqlconnectionstring);
            //series of commands to bulk copy data from the excel file into our sql table
            OleDbConnection oledbconn = new OleDbConnection(sexcelconnectionstring);
            OleDbCommand oledbcmd = new OleDbCommand(myexceldataquery, oledbconn);
            oledbconn.Open();
            OleDbDataReader dr = oledbcmd.ExecuteReader();
            SqlCommand sqlcmd = new SqlCommand(@query, sqlconn);
            SqlParameter param;
            param = sqlcmd.Parameters.AddWithValue("@source", dr);
            param.SqlDbType = SqlDbType.Structured;
            param.TypeName = "dbo.DTTOW";
            sqlconn.Open();
            sqlcmd.ExecuteNonQuery();
            sqlconn.Close();
            oledbconn.Close();
            Console.WriteLine(".xlsx file imported succssessfully into database. /r /n ");
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }

当我从excel表中只选择两列LocalSKUQOH

时,此代码有效

当我选择更多的列时,我得到这个错误。"将数据类型nvarchar转换为数字时出错。"

我正在使用用户定义的数据类型:

CREATE TYPE [dbo].[DTTOW] AS TABLE(
  [LocalSKU] [varchar](200) NOT NULL,
  [ItemName] [varchar](200) NULL,
  [QOH] [int] NULL,
  [Price] [decimal](19, 4) NULL,
  [Discontinued] [bit] NULL,
  [Integer2] [int] NULL,
  [Integer3] [int] NULL

)

将Excel导入到Sql Server数据库时,将数据类型nvarchar转换为数字时出错

从结构的SQL DDL的外观来看,在excel文件的某个地方有混乱的价格。您可以运行宏或脚本来查看价格列中的所有单元格是否实际上都是可转换的吗?您可以使用=ISNUMBER()函数。还有一种简单的方法-尝试在Price列的底部编辑=SUM()。我想知道是否有一些"聪明的裤子"卡在"-"或"$"字符中进入价格列的单元格之一。)我担心任何Excel单元格的默认类型在OLE-DB感知中都是nvarachar。

就我个人而言,我会使用Excel互操作来吸收信息,而不是像你这样的隐式转换错误。它有点慢,但肯定可以完成工作,而不必担心Excel的OLE-DB"黑盒"内部可能出了什么问题。

您可以对从excel中选择的查询中的数字类型进行一些清理。对于Price字段,您可以将查询更改为以下内容,通过将非数字值替换为0来保证该列始终是数字。

select iif(isnumeric(Price), Price, 0) as Price from [sheet1$]