mysql如何植入到oracle_分享MSSQL、MySql、Oracle的大数据批量导入方法及编程手法细节...

1:MSSQL

SQL语法篇:

BULK INSERT

[ database_name . [ schema_name ] . | schema_name . ] [ table_name | view_name ]

FROM 'data_file'

[ WITH

(

[ [ , ] BATCHSIZE = batch_size ]

[ [ , ] CHECK_CONSTRAINTS ]

[ [ , ] CODEPAGE = { 'ACP' | 'OEM' | 'RAW' | 'code_page' } ]

[ [ , ] DATAFILETYPE =

{ 'char' | 'native'| 'widechar' | 'widenative' } ]

[ [ , ] FIELDTERMINATOR = 'field_terminator' ]

[ [ , ] FIRSTROW = first_row ]

[ [ , ] FIRE_TRIGGERS ]

[ [ , ] FORMATFILE = 'format_file_path' ]

[ [ , ] KEEPIDENTITY ]

[ [ , ] KEEPNULLS ]

[ [ , ] KILOBYTES_PER_BATCH = kilobytes_per_batch ]

[ [ , ] LASTROW = last_row ]

[ [ , ] MAXERRORS = max_errors ]

[ [ , ] ORDER ( { column [ ASC | DESC ] } [ ,...n ] ) ]

[ [ , ] ROWS_PER_BATCH = rows_per_batch ]

[ [ , ] ROWTERMINATOR = 'row_terminator' ]

[ [ , ] TABLOCK ]

[ [ , ] ERRORFILE = 'file_name' ]

)]

SQL示例:

bulk insert 表名 from 'D:\mydata.txt'

with

(fieldterminator=',',

rowterminator='\n',

check_constraints)

select * from 表名

由于C#提供了SqlBulkCopy,所以非DBA的我们,更多会通过程序来调用:

C#代码篇:

C#代码调用示例及细节,以下代码摘录自CYQ.Data:

using (SqlBulkCopy sbc = new SqlBulkCopy(con, (keepID ? SqlBulkCopyOptions.KeepIdentity : SqlBulkCopyOptions.Default) |SqlBulkCopyOptions.FireTriggers, sqlTran))

{

sbc.BatchSize= 100000;

sbc.DestinationTableName=SqlFormat.Keyword(mdt.TableName, DalType.MsSql);

sbc.BulkCopyTimeout=AppConfig.DB.CommandTimeout;foreach (MCellStruct column inmdt.Columns)

{

sbc.ColumnMappings.Add(column.ColumnName, column.ColumnName);

}

sbc.WriteToServer(mdt);

}

有5个细节:

1:事务:

如果只是单个事务,构造函数可以是链接字符串。

如果需要和外部合成一个事务(比如先删除,再插入,这在同一个事务中)

就需要自己构造Connection对象和Transaction,在上下文中传递来处理。

2:插入是否引发触发器

通过SqlBulkCopyOptions.FireTriggers 引入

3:其它:批量数、超时时间、是否写入主键ID。

可能引发的数据库Down机的情况:

在历史的过程中,我遇到过的一个大坑是:

当数据的长度过长,数据的字段过短,产生数据二进制截断时,数据库服务竟然停掉了(也许是特例,也许不是)。

所以小心使用,尽力做好对外部数据做好数据长度验证。

2:MySql

关于MySql的批量,这是一段悲催的往事,有几个坑,直到今天,才发现并解决了。

SQL语法篇:

LOAD DATA [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE 'data.txt'

[REPLACE | IGNORE]

INTO TABLE tbl_name

[FIELDS

[TERMINATED BY 'string']

[[OPTIONALLY] ENCLOSED BY 'char']

[ESCAPED BY 'char' ]

]

[LINES

[STARTING BY 'string']

[TERMINATED BY 'string']

]

[IGNORE number LINES]

[(col_name_or_user_var,...)]

[SET col_name = expr,...)]

示例篇:

LOAD DATA LOCAL INFILE 'C:\\Users\\cyq\\AppData\\Local\\Temp\\BulkCopy.csv' INTO TABLE `BulkCopy` CHARACTER SET utf8 FIELDS TERMINATED BY '$,$' LINES TERMINATED BY '

' (`ID`,`Name`,`CreateTime`,`Sex`)

虽然MySql.Data.dll 提供了MySqlBulkLoader,但是看源码只是生成了个Load Data 并用ADO.NET执行,

核心大坑的生成*.csv数据文件的竟然没提供,所以自己生成语句并执行就好了,不需要用它。

C#代码篇:

以下代码摘自CYQ.Data,是一段今天才修正好的代码:

private static string MDataTableToFile(MDataTable dt, boolkeepID, DalType dalType)

{string path = Path.GetTempPath() + dt.TableName + ".csv";using (StreamWriter sw = new StreamWriter(path, false, new UTF8Encoding(false)))

{

MCellStruct ms;stringvalue;foreach (MDataRow row indt.Rows)

{for (int i = 0; i < dt.Columns.Count; i++)

{#region 设置值ms=dt.Columns[i];if (!keepID &&ms.IsAutoIncrement)

{continue;

}else if (dalType == DalType.MySql &&row[i].IsNull)

{

sw.Write("\\N");//Mysql用\N表示null值。

}else{

value=row[i].ToString();if (ms.SqlType ==SqlDbType.Bit)

{int v = (value.ToLower() == "true" || value == "1") ? 1 : 0;if (dalType ==DalType.MySql)

{byte[] b = new byte[1];

b[0] = (byte)v;

value= System.Text.Encoding.UTF8.GetString(b);//mysql必须用字节存档。

}else{

value=v.ToString();

}

}else{

value= value.Replace("\\", "\\\\");//处理转义符号

}

sw.Write(value);

}if (i != dt.Columns.Count - 1)//不是最后一个就输出

{

sw.Write(AppConst.SplitChar);

}#endregion}

sw.WriteLine();

}

}if (Path.DirectorySeparatorChar == '\\')

{

path= path.Replace(@"\", @"\\");

}returnpath;

}

以上代码是产生一个csv文件,用于被调用,有两个核心的坑,费了我不少时间:

1:Bit类型数据导不进去?

2:第1行数据自增ID被重置为1?

这两个问题,网上搜不到答案,放纵到今天,觉的应该解决了,然后就把它解决了。

解决的思路是这样的:

A:先用Load Data OutFile导出一个文件,再用Load Data InFile导入文件。

一开始我用记事本打开看了一下,又顺手Ctrl+S了一下,结果发现问题和我的一样,让我怀疑竟然不支持?

直到今天,重新导出,中间不看了,直接导入,发现它竟然又正常的,于是,思维一转:

B:把自己生成的文件和命令产生的文件,进行了十六进制比对,结果发现:

Bit类型自己生成的的数据:是0,1,在十六进制下显示是30、31。

命令产生的数据在十六进制是00、01,查了下资料,发现MySql的Bit存档的Bit是二进制。

于是,把0,1用字节表示,再转字符串,再存档,就好了。

于是这么一段代码产生了(网上的DataTable转CSV代码都是没处理的,都不知道他们是怎么跑的,难道都没有定义Bit类型?):

if (ms.SqlType == SqlDbType.Bit)

{

int v = (value.ToLower() == "true" || value == "1") ? 1 : 0;

if (dalType == DalType.MySql)

{

byte[] b = new byte[1];

b[0] = (byte)v;

value = System.Text.Encoding.UTF8.GetString(b);//mysql必须用字节存档。

}

else

{

value = v.ToString();

}

}

另外关于Null值,用\N表示。

解决完第一个问题,剩下就是第二个问题了,为什么第一个行代码的主键会被置为1?

还是比对十六进制,结果惊人的发现:

是BOM头,让它错识别了第一个主键值,所以被忽略主键,用了第1个自增值1替代了。

这也解释了为什么只要重新保存的数据都有Bug的原因。

于是,解决的方法就是StreaWrite的时候,不生成BOM头,怎么处理呢?

于是就有了以下的代码:

using (StreamWriter sw = new StreamWriter(path, false, new UTF8Encoding(false)))

{

...................

}

通过New一个Encoding,并指定参数为false,替代我们常规的System.Text.Encoding.UTF8Encoding。

这些细节很隐秘,不说你都猜不道。。。

3:Oracle

SQL语法篇

LOAD[DATA]

[ { INFILE | INDDN } {file | * }

[STREAM | RECORD | FIXED length [BLOCKSIZE size]|

VARIABLE [length] ]

[ { BADFILE | BADDN } file ]

{DISCARDS | DISCARDMAX} integr ]

[ {INDDN | INFILE} . . . ]

[ APPEND | REPLACE | INSERT ]

[RECLENT integer]

[ { CONCATENATE integer |

CONTINUEIF { [THIS | NEXT] (start[: end])LAST }

Operator { 'string' | X 'hex' } } ]

INTO TABLE [user.]table

[APPEND | REPLACE|INSERT]

[WHEN condition [AND condition]...]

[FIELDS [delimiter] ]

(

column {

RECNUM | CONSTANT value |

SEQUENCE ( { integer | MAX |COUNT} [, increment] ) |

[POSITION ( { start [end] | * [ + integer] }

) ]

datatype

[TERMINATED [ BY ] {WHITESPACE| [X] 'character' } ]

[ [OPTIONALLY] ENCLOSE[BY] [X]'charcter']

[NULLIF condition ]

[DEFAULTIF condotion]

}

[ ,...]

)

以上配置存档成一个CTL文件,再由以下的命令调用:

Sqlldr userid=用户名/密码@数据库 control=文件名.ctl

C#语法篇:

.NET里大概有三种操作Oracle的手法:

1:System.Data.OracleClient (需要安装客户端)没有带批量方法(还区分x86和x64)。

2:Oracle.DataAccess  (需要安装客户端)带批量方法(也区分x86和x64)。

3:Oracle.ManagedDataAccess (不需要安装客户端)没带批量方法(不区分x86和x64,但仅支持.NET 4.0或以上)

Oracle.DataAccess 带的批量方法叫:OracleBulkCopy,由于使用方式和SqlBulkCopy几乎一致,就不介绍了。

如果调用程序所在的服务器安装了Oracle客户端,可以进行以下方法的调用:

流程如下:

1:产生*.cvs数据文件,见MySql中的代码,一样用的。

2:产生*.ctl控制文件,把生成的Load Data 语句存档成一个*.ctl文件即可。

3:用sqlidr.exe执行CTL文件,这里悲催的一点是,不能用ADO.NET调用,只能用进程调用,所以,这个批量只能单独使用。

调用进程的相关代码:

bool hasSqlLoader = false;private boolHasSqlLoader() //检测是否安装了客户端。

{

hasSqlLoader= false;

Process proc= newProcess();

proc.StartInfo.FileName= "sqlldr";

proc.StartInfo.CreateNoWindow= true;

proc.StartInfo.UseShellExecute= false;

proc.StartInfo.RedirectStandardOutput= true;

proc.OutputDataReceived+= newDataReceivedEventHandler(proc_OutputDataReceived);

proc.Start();

proc.BeginOutputReadLine();

proc.WaitForExit();returnhasSqlLoader;

}void proc_OutputDataReceived(objectsender, DataReceivedEventArgs e)

{if (!hasSqlLoader)

{

hasSqlLoader= e.Data.StartsWith("SQL*Loader:");

}

}//已经实现,但没有事务,所以暂时先不引入。

private bool ExeSqlLoader(stringarg)

{try{

Process proc= newProcess();

proc.StartInfo.FileName= "sqlldr";

proc.StartInfo.Arguments=arg;

proc.Start();

proc.WaitForExit();return true;

}catch{

}return false;

}

总结:

随着大数据的普及,数据间的批量移动必然越来频繁的被涉及,所以不管是用SQL脚本,还是自己写代码,或是用DBImport工具,都将成必备技能之一了!

鉴于此,分享一下我在这一块费过的力和填过的坑,供大伙参考!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/542930.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java文件类String [] list(FilenameFilter fnf)方法,带示例

File Class String []列表(FilenameFilter fnf) (File Class String[] list(FilenameFilter fnf)) This method is available in package java.io.File.list(FilenameFilter fnf). 软件包java.io.File.list(FilenameFilter fnf)中提供了此方法。 This method is used to return…

求最大公因数

while 1:s input(请输入一个数&#xff1a;)e input(请输入一个数&#xff1a;)s int(s)e int(e)if s 0 or e 0:print(错误)continueif s > e:f eelse:f swhile f:if s % f 0 and e % f 0:print(f)breakelse:f f - 1 转载于:https://www.cnblogs.com/wumac/p/567…

窦学计算机基础期末考试,关于新生开学考计算机基础

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼单选题练习1&#xff0e;完整的计算机系统由( c )组成。A&#xff0e;运算器、控制器、存储器、输入设备和输出设备B&#xff0e;主机和外部设备C&#xff0e;硬件系统和软件系统D&#xff0e;主机箱、显示器、键盘、鼠标、打印机…

AIX配置Volumn

我们知道&#xff0c;现在操作系统都具有默认的卷管理系统来管理磁盘。详见存储技术之卷管理和文件系统。总体来说&#xff0c;从下向上分为物理磁盘(PV)、逻辑卷组(VG)、逻辑卷(LV)&#xff0c;用户可以直接mount的是逻辑卷。本文记录一些AIX下的卷管理和配置方法。 AIX下的Vo…

高并发内存占用持续下降_师兄,为什么删除数据后,Redis内存占用依然很高?...

前言上周刚来了个应届小师弟&#xff0c;组长说让我带着&#xff0c;周二问了我这样一个问题&#xff1a;师兄啊&#xff0c;我用top命令看了下服务器的内存占用情况&#xff0c;发现Redis内存占用严重&#xff0c;于是我就删除了大部分不用的keys&#xff0c;为什么内存占用还…

如何打印出给定尺寸的方格_打印给定号码的表格| 8085微处理器

如何打印出给定尺寸的方格Problem statement: 问题陈述&#xff1a; Write an assembly language program in 8085 to print the table of input integer. 在8085中编写汇编语言程序以打印输入整数表。 Assumptions: Suppose the inputted number is at memory location 2050…

maka如何看html文件,自己在MAKA上做得H5,别人如何能看到收集的信息

1。登陆1。 ? ?登陆入口&#xff1a;点击首页右上角“登录”按钮进入登录界面&#xff1b;2。 ? ?登陆界面&#xff1a;输入有效注册的个人账号信息&#xff1a;邮箱、密码&#xff1b;您也可以选择QQ等第三方登录。3。 ? ?密码找回&#xff1a;进入账户登录界面&#xf…

发现保存GIF格式后相素发生变化咋办

数学公式编辑器MathType主要的作用就是编辑公式用的&#xff0c;一些用户朋友编辑完公式希望把公式保存为“高分辨率”的GIF格式&#xff0c;但是在图片查看器中进行浏览查看时发现GIF的分辨率发生了变化&#xff0c;对于这种情况该如何处理呢&#xff1f;下面我们就针对这个问…

3个阶段 项目征名_2020年即将上线的3个爆款,或许它们能改变现有的手游格局...

在近几年国内的手游市场中&#xff0c;基本都被《王者荣耀》和吃鸡类型的给垄断了&#xff0c;偶尔有个别爆款出现&#xff0c;也只是昙花一现&#xff0c;连半年时间都坚持不到&#xff0c;就比如去年的自走棋。不过在2020年&#xff0c;以王者和吃鸡为主的这种格局或许会被打…

python判断素数程序_使用面向对象方法检查素数的Python程序

python判断素数程序This program will check whether a given number is Prime or Not, in this program we will divide the number from 2 to square root of that number, if the number is divided by any number in b/w then the number will not be a prime number. 该程…

湖北计算机技能高考专科学校排名,湖北2021年技能高考专科录取分数线

https://forms.ebdan.net/ls/wg2YPHOQ点击查看全部院校武汉船舶职业技术学院&#xff1a;技能高考(机械类)507技能高考(电气电子类)437技能高考(计算机类)532技能高考(财经类)530技能高考(建筑设计类)319技能高考(旅游类)489技能高考(汽车维修类)466湖北科技职业学院&#xff1…

定位样式

Web页面中的特殊效果&#xff0c;如菜单效果&#xff0c;对话框效果都需要通过定位属性来实现。定位样式position属性可以控制元素的定位类型position属性值可以为sataic、fixed、absolute、relativeposition属性的语法结构- position:value;定位属性static默认值。没有定位&am…

c#异常处理_C#异常处理能力问题和解答 套装2

c#异常处理1) There are the following statements that are given below, which is correct about an exception in C#.NET? The exception occurs at the time of compilationThe exception occurs during program loadingThe exception occurs during JIT compilationThe …

考虑题4所示的日志记录_[南开大学]18秋学期(1703)《数据库基础与应用》在线作业...

18秋学期(1703)《数据库基础与应用》在线作业一、单选题&#xff1a;1.[单选题]在SQL语言中&#xff0c;模式对应于() (满分:)A. 视图和部分基本表B. 基本表C. 存储文件D. 物理磁盘正确答案:——B——2.[单选题]在数据库系统中&#xff0c;读脏数据是指一个事务读了另…

数字图像处理图像反转的实现_反转8位数字| 8085微处理器

数字图像处理图像反转的实现Problem statement: 问题陈述&#xff1a; To reverse 8 bits number using 8085 microprocessors. 使用8085微处理器反转8位数字。 Algorithm: 算法&#xff1a; Load the accumulator with the first data. 向累加器加载第一个数据。 Use RLC i…

计算机控制z反变换公式,第三章 计算机控制系统的数学描述(修正Z变换).ppt

第三章 计算机控制系统的数学描述(修正Z变换)* 3.4 修改Z变换 1&#xff0e;具有多采样频率系统 在某些控制系统中&#xff0c;存在着不同采样频率的采样开关&#xff0c;如图3.10所示。 图3.10 具有不同采样频率系统结构图 图3.10表示&#xff0c;该系统反馈回路的采样频率高一…

7月19日实习日志

今天是实习第十二天&#xff0c;时间过得很快一转眼实习一般都已经过去了&#xff0c;今天早上下了大雨&#xff0c;到单位的时候差一点迟到。 今天难道单位公司的同事就带领着我给公司的防火请升级&#xff0c;防火墙可以是一套硬件或软件&#xff0c;它在网络和互联网之间形成…

g++默认参数_C ++默认参数| 查找输出程序| 套装2

g默认参数Program 1: 程序1&#xff1a; #include <iostream>using namespace std;int K 10;int fun(){return K;}int sum(int X, int Y fun()){return (X Y);}int main(){int A 0;A sum(5);cout << A << " ";K 20;A sum(5);cout <<…

python重载模块_Python 3.0中重载模块

在Python中&#xff0c;每一个以 .py结尾的Python文件都是一个模块。其他的文件可以通过导入一个模块来读取该模块的内容。导入从本质上来讲&#xff0c;就是载入另一个文件&#xff0c;并能够读取那个文件的内容。一个模块的内容通过这样的属性能够被外部世界使用。这种基于模…

计算机考研985院校不歧视,考研最不歧视的985大学有哪些

考研最不歧视的大学有很多&#xff0c;其中985院校有哈尔滨工业大学、对外经济贸易大学、中南大学、河南大学和华东师范大学等。哪些985大学不歧视考研考生1、哈尔滨工业大学面试除了自我介绍&#xff0c;其他都不透露自己的信息&#xff0c;面试老师也都不知道&#xff0c;都是…