将excel上传到sql server的过程

时间:2010-10-13 13:18:11

标签: sql sql-server sql-server-2005

Hallo All,

请帮助确定以下问题的最佳程序。

在用户界面中,有一个上传excel文件的规定。这由管理员完成,每天一次/两次定期。

我用来将excel文件上传到sql server的代码。

select * 
into #temp FROM OPENROWSET('Microsoft.Jet.OLEDB.4.0', 
    'Excel 8.0;Database=D:\Files\29.09.10\working_290910.xls;HDR=YES;IMEX=1', 
    'SELECT * FROM [2XX$]')

上传成功后,我正在使用逻辑并删除所有不必要的记录。最后我将获得一组记录,我将移动到相应的表中。最后,我删除了用于上传的临时表。在这里#temp。

这个程序有很多问题。由于#temp的结构并不总是与excel相同,因此基于对前n个记录中的数据的分析,假设该特定字段的数据类型。对于特定字段,有时它会假设,数据类型为nvarchar(255),有时是文本。因此很少有函数在执行存储过程时在这些特定字段上抛出错误消息。

上次我有类似的问题,LTRIM没有处理文本字段..正如excel假设表#temp中字段的数据类型为文本..

所以我通过创建表

以这种方式修改了代码
CREATE TABLE temp_invoice(
    [Concession Number] varchar(30),
    [Status] char(10),
    [Sort] char(10),
    [Task code text] varchar(60),
    [Task resp#] varchar(10),
    [Person who complete the task] varchar(50),
    [Completed] datetime
) 

这样我就可以修复数据类型,然后从excel中移动数据......

编辑查询: -

insert into temp(Completed)  
    SELECT CASE Completed when '00.00.0000' THEN null else Completed END  
       FROM OPENROWSET  
('Microsoft.Jet.OLEDB.4.0', 'Excel 8.0;Database=D:\Files\12.10.10\MC01_PCTA00012_20101012.xls;HDR=YES;IMEX=1', 'select * from [Tabelle1$]') AS A;

现在我收到基于数据的错误消息。如果在前几行中,完成的字段为'00 .00.000'。然后它的工作正常。如果它在前几行中没有值,则会抛出错误消息。

现在在我的excel文件中,[Completed]字段的数据是00.00.0000,因此错误消息是算术溢出错误转换日期时间数据类型中的表达式。 该声明已被终止。“

如果我删除日期为00.00.0000的记录,那么它的工作正常。但我不能每次都做到这一点。现在我需要找到解决这个问题的方法。

非常感谢你耐心阅读这么长的邮件。我真的不知道,我使用的程序是否正确。我只是改变代码来克服错误......

请为此建议适当的程序。

3 个答案:

答案 0 :(得分:2)

您所描述的内容依赖于非常多的技术。你很幸运得到一条错误信息。在许多情况下,它会默默地跳过一些值并报告成功。在被刻录几次之后,我总是从C#手动加载这些数据。像这样打开你的电子表格:

    ApplicationClass excelApp = new ApplicationClass();
    string workbookPath = string.Format(@"C:\yourfile.xls");
    Workbook workbook = excelApp.Workbooks.Open(lots of parameters here);

    Sheets sheets = workbook.Sheets;
    Worksheet UsSheet = (Worksheet)sheets.get_Item("US");

按照这样的方式完成细胞:

                        Range rowrange = UsSheet.get_Range("A3", "A102");
                        System.Array values = (System.Array) rowrange.Cells.Value2;
                        foreach (object value in values)
                            if (value != null)
                            {
                                string s = value.ToString();
                                //do something here
                            }

答案 1 :(得分:1)

我想你可以将你的选择查询更改为此,如果你允许Completed可以为空,你应该根据你所描述的问题:

SELECT *,
       CASE {Completed Column name}
         when 00.00.0000 THEN null
         else {Completed Column name}
       END
FROM [2XX$]

但是你仍然遇到Jet试图将数据类型错误地分配给列的问题。看一看为什么会这样,以及如何在this SO post中解决这个问题。

答案 2 :(得分:0)

感谢您的所有回复..我发现了一个问题的肮脏技巧,我已经将完成的列数据类型定义为varchar(20)。按原样上传..

CREATE TABLE temp_invoice(
    [Concession Number] varchar(30),
    [Status] char(10),
    [Sort] char(10),
    [Task code text] varchar(60),
    [Task resp#] varchar(10),
    [Person who complete the task] varchar(50),
    [Completed] varchar(20)
) 

INSERT INTO temp_invoice ([Concession Number],[Status],[Sort],[Task code text],[Task resp#],[Person who complete the task],[Completed])
EXEC('SELECT A.[Concession Number],A.[Status],A.[Sort],A.[Task code text],LTRIM(str(A.[Task resp#],10,0)) as [Task resp#],
A.[Person who complete the task], A.[Completed] 
FROM OPENROWSET  
(''Microsoft.Jet.OLEDB.4.0'',''Excel 8.0;Database=' + 'D:\Files\12.10.10\XCTH00759_20101012.xls' + ';HDR=YES;IMEX=1'','+'''select * from [Tabelle1$]'') AS A') ;

上传后,我将值设置为NULL,如果它已完成日期值为'00 .00.0000'。然后最后改变数据类型。

UPDATE temp_invoice SET Completed = NULL
where Completed = '00.00.0000'

ALTER TABLE temp_invoice ALTER COLUMN Completed datetime

因为所有其他方式都在基于数据的阶段失败..