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.pswp.cn/news/542930.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/542930.shtml
英文地址,請注明出處:http://en.pswp.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;都是…