Oracle大数据导出到Access
当时最先想到的方法有以下两种:
1.当时以为就是DataTable转Access,写个for循环插入数据就完事了
2.使用链接服务器导入
由于数据量非常大所以只能使用第二种。
开始一直使用Microsoft ODBC for Oracle,语句大致如下
SELECT * into cb_neicuo
FROM [ODBC;DRIVER={Microsoft ODBC for Oracle};SERVER=servername;UID=user;PWD=pass;].user.cb_neicuo;
最后经测试发现该方法查询50万条数据非常快,但是插入数据及慢。3万条数据要15分钟左右,50万条数据等了1小时也没出来,最后放弃了。
而且这个方法还有个缺点,需要Microsoft ODBC for Oracle的驱动支持,客户机器上有这个驱动,也装了odp.net,tns也配置了,但还是不能用估计还要装oracle客户端才行了。安装非常不方便。
后来发现access导入文本文件非常快,50万条记录30s不到就能导完,于是最后先导出到文本文件,再将文本文件转入access。
这里注意select into有局限性,有些数值会转成文本导入,需先用adox创建表;分隔符用默认的逗号不太好,要定义shemans文件
具体代码如下:
public class OracleToJet
{
static public void SQLToJetDB(string sql, string jetFileName,DataTable table)
{
string connstr = string.Format(@"Provider=Microsoft.Jet.OLEDB.4.0;" + @"Data Source={0};Jet OLEDB:Engine Type=5;", jetFileName);
Catalog cat = new CatalogClass();
if (!System.IO.File.Exists(jetFileName))
cat.Create(connstr);
ADODB.Connection cn = new ADODB.Connection();
cn.Open(string.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0}", jetFileName), null, null, -1);
ADOX.Table adoxTable = new ADOX.TableClass();
adoxTable.Name = table.TableName;
foreach (System.Data.DataColumn col in table.Columns)
{
ADOX.Column column = new ADOX.Column();
column.Name = col.ColumnName;
column.Type = TranslateDataTypeToADOXDataType(col.DataType);
column.Attributes = ColumnAttributesEnum.adColNullable;
column.DefinedSize = TranslateDataTypeToADOXlength(col.DataType);
if (col.DataType == typeof(decimal) || col.DataType == typeof(double) || col.DataType == typeof(Single))
{
column.NumericScale = 2;
column.Precision = 18;
}
adoxTable.Columns.Append(column);
}
cat.Tables.Append(adoxTable);
//实例化一个文件流--->与写入文件相关联
FileStream fs = new FileStream("Schema.ini", FileMode.Create);
//实例化一个StreamWriter-->与fs相关联
StreamWriter sw = new StreamWriter(fs);
//开始写入
sw.WriteLine(string.Format("[{0}]",table.TableName + ".txt"));
sw.WriteLine("ColNameHeader=True");
sw.WriteLine("format=TabDelimited");
sw.WriteLine("MaxScanRows=0");
sw.WriteLine("CharacterSet=ANSI");
//清空缓冲区
sw.Flush();
//关闭流
sw.Close();
fs.Close();
Process p = new Process();
p.StartInfo.FileName = "sqluldr2.exe";
p.StartInfo.Arguments = "user=**/**@** query=\"" + sql + "\" field=0x09 record=0x0a head=yes file=" + table.TableName + ".txt";
p.StartInfo.WorkingDirectory = System.Windows.Forms.Application.StartupPath;
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
p.Start();
p.WaitForExit();
ADODB.Command cmd = new ADODB.Command();
cmd.ActiveConnection = cn;
cmd.CommandType = ADODB.CommandTypeEnum.adCmdText;
string s = @"insert into " + table.TableName + " select * from [text;database=" + System.Windows.Forms.Application.StartupPath + "]." + table.TableName + ".txt";
cmd.CommandText = s;
object dummy = Type.Missing;
cmd.Execute(out dummy);
cn.Close();
}
static private ADOX.DataTypeEnum TranslateDataTypeToADOXDataType(Type type)
{
string guid = type.GUID.ToString();
return
guid == typeof(bool).GUID.ToString() ? ADOX.DataTypeEnum.adBoolean :
guid == typeof(byte).GUID.ToString() ? ADOX.DataTypeEnum.adUnsignedTinyInt :
guid == typeof(char).GUID.ToString() ? ADOX.DataTypeEnum.adWChar :
guid == typeof(DateTime).GUID.ToString() ? ADOX.DataTypeEnum.adDate :
guid == typeof(decimal).GUID.ToString() ? ADOX.DataTypeEnum.adDouble :
guid == typeof(double).GUID.ToString() ? ADOX.DataTypeEnum.adDouble :
guid == typeof(Int16).GUID.ToString() ? ADOX.DataTypeEnum.adSmallInt :
guid == typeof(Int32).GUID.ToString() ? ADOX.DataTypeEnum.adInteger :
guid == typeof(Int64).GUID.ToString() ? ADOX.DataTypeEnum.adBigInt :
guid == typeof(SByte).GUID.ToString() ? ADOX.DataTypeEnum.adTinyInt :
guid == typeof(Single).GUID.ToString() ? ADOX.DataTypeEnum.adDouble :
guid == typeof(string).GUID.ToString() ? ADOX.DataTypeEnum.adVarWChar :
guid == typeof(TimeSpan).GUID.ToString() ? ADOX.DataTypeEnum.adDouble :
guid == typeof(UInt16).GUID.ToString() ? ADOX.DataTypeEnum.adUnsignedSmallInt :
guid == typeof(UInt32).GUID.ToString() ? ADOX.DataTypeEnum.adUnsignedInt :
guid == typeof(UInt64).GUID.ToString() ? ADOX.DataTypeEnum.adUnsignedBigInt :
ADOX.DataTypeEnum.adBinary;
}
static private int TranslateDataTypeToADOXlength(Type type)
{
string guid = type.GUID.ToString();
return
guid == typeof(bool).GUID.ToString() ? 0 :
guid == typeof(byte).GUID.ToString() ? 0 :
guid == typeof(char).GUID.ToString() ? 50 :
guid == typeof(DateTime).GUID.ToString() ? 0 :
guid == typeof(decimal).GUID.ToString() ? 0 :
guid == typeof(double).GUID.ToString() ? 0 :
guid == typeof(Int16).GUID.ToString() ? 9 :
guid == typeof(Int32).GUID.ToString() ? 9 :
guid == typeof(Int64).GUID.ToString() ? 9 :
guid == typeof(SByte).GUID.ToString() ? 9 :
guid == typeof(Single).GUID.ToString() ? 0 :
guid == typeof(string).GUID.ToString() ? 100 :
guid == typeof(TimeSpan).GUID.ToString() ? 0 :
guid == typeof(UInt16).GUID.ToString() ? 9 :
guid == typeof(UInt32).GUID.ToString() ? 9 :
guid == typeof(UInt64).GUID.ToString() ? 9 :
0;
}
}