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的记录,那么它的工作正常。但我不能每次都做到这一点。现在我需要找到解决这个问题的方法。
非常感谢你耐心阅读这么长的邮件。我真的不知道,我使用的程序是否正确。我只是改变代码来克服错误......
请为此建议适当的程序。
答案 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
因为所有其他方式都在基于数据的阶段失败..