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;
        }
    }

posted on 2011-09-30 21:49  zyi  阅读(3130)  评论(0编辑  收藏  举报

导航