使用java實現(xiàn)備份和恢復SQLServer表數(shù)據(jù)
需求
近來工作中遇到一個問題,內(nèi)網(wǎng)辦公系統(tǒng)中的數(shù)據(jù)需要導出到外網(wǎng)中進行查詢,外網(wǎng)的數(shù)據(jù)庫中還有一些表存儲外網(wǎng)的數(shù)據(jù),因此無法使用全庫備份恢復功能來滿足需求。即只從內(nèi)網(wǎng)數(shù)據(jù)庫中導出若干表的內(nèi)容至外網(wǎng)數(shù)據(jù)庫的對應表。
其他解決方案:使用SQL Server自身的導出SQL語句的方法其實也可以,但是涉及到幾十個表,一一手工導出工作量較大。
因此自己寫了個函數(shù),將內(nèi)網(wǎng)中的表數(shù)據(jù)導出,根據(jù)數(shù)據(jù)生成insert into 語句,然后使用批處理的方式導入到外網(wǎng)數(shù)據(jù)庫中。
1.表結構的分析
生成insert語句時,不得不面對的是引號的使用,對于int等類型無需引號,但是對于char、text等必須加上引號,一個表動輒幾十個字段,人工用數(shù)組等方式記錄字段的類型、名稱再進行處理,也比較耗費精力,尤其是數(shù)據(jù)表的結構時常還在變化,而且是另一個開發(fā)公司在維護,何時變化也不得而知。這里通過分析建表語句完成了自動的字段類型的對應,從而大大減輕了人工維護字段及其類型的工作量。
譬如建表語句如下(在SQL Server企業(yè)管理器中選中表,Ctrl+C即可得到),這里存放一個文件中:
CREATE TABLE [Import_BizDescrs] ( [DescrId] [char] (10) COLLATE Chinese_PRC_CI_AS NULL , [DescrType] [char] (20) COLLATE Chinese_PRC_CI_AS NULL , [DescrAt] [datetime] NULL , [Descr] [text] COLLATE Chinese_PRC_CI_AS NULL , [DescrBy] [char] (20) COLLATE Chinese_PRC_CI_AS NULL , [BizId] [char] (10) COLLATE Chinese_PRC_CI_AS NULL , [SampId] [char] (20) COLLATE Chinese_PRC_CI_AS NULL , [AssistTaskId] [char] (20) COLLATE Chinese_PRC_CI_AS NULL , [CreatePerson] [char] (20) COLLATE Chinese_PRC_CI_AS NULL , [CreateDate] [datetime] NULL , [UpdatePerson] [char] (20) COLLATE Chinese_PRC_CI_AS NULL , [UpdateDate] [datetime] NULL ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] GO
從以上文字中,做出如下處理,即可獲得表名、字段名、字段類型以及附帶的是否需要引號。
public static void exportTableDataByCreateSQL(String createSQLFileName){
ArrayList <String> fieldNames = new ArrayList<String>();
ArrayList <String> fieldtypes = new ArrayList<String>();
ArrayList <Boolean> needQuotationMark = new ArrayList<Boolean>();
String tableName = "";
String filePath = "C:\\importSQLs\\";
String tmpString;
try {
BufferedReader reader = new BufferedReader(new FileReader(createSQLFileName));
String line = reader.readLine();
//從第一行獲取表名
tableName = line.substring(line.indexOf("[")+1,line.indexOf("]"));;
System.out.println(tableName) ;
//后面獲取其他信息
while ((line = reader.readLine()) != null) {
if(line.startsWith(")")){
break;
}
tmpString = line.substring(line.indexOf("[")+1,line.indexOf("]"));
fieldNames.add(tmpString);
line = line.substring(line.indexOf("]")+1);
tmpString = line.substring(line.indexOf("[")+1,line.indexOf("]"));
fieldtypes.add(tmpString);
if(tmpString.contains("char")
||tmpString.contains("text")
||tmpString.contains("datetime")){
needQuotationMark.add(true);
}else{
needQuotationMark.add(false);
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}2.備份表
獲取到完整的字段、字段屬性后,就可以開始生成SQL文件了,對于值為null的數(shù)據(jù),略去相應的插入語句,同時由于是全表全量導入,開始時增加了delete from tableName;的語句
全部代碼如下:
public static void exportTableDataByCreateSQL(String createSQLFileName){
ArrayList <String> fieldNames = new ArrayList<String>();
ArrayList <String> fieldtypes = new ArrayList<String>();
ArrayList <Boolean> needQuotationMark = new ArrayList<Boolean>();
String tableName = "";
String filePath = "C:\\importSQLs\\";
String tmpString;
try {
BufferedReader reader = new BufferedReader(new FileReader(createSQLFileName));
String line = reader.readLine();
//從第一行獲取表名
tableName = line.substring(line.indexOf("[")+1,line.indexOf("]"));;
//后面獲取其他信息
while ((line = reader.readLine()) != null) {
if(line.startsWith(")")){
break;
}
tmpString = line.substring(line.indexOf("[")+1,line.indexOf("]"));
fieldNames.add(tmpString);
line = line.substring(line.indexOf("]")+1);
tmpString = line.substring(line.indexOf("[")+1,line.indexOf("]"));
fieldtypes.add(tmpString);
if(tmpString.contains("char")
||tmpString.contains("text")
||tmpString.contains("datetime")){
needQuotationMark.add(true);
}else{
needQuotationMark.add(false);
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//開始生成insert語句
Connection conn;
try {
Class.forName("net.sourceforge.jtds.jdbc.Driver");
conn = DriverManager.getConnection(GlobalVar.ConnURL,GlobalVar.ConnUser,GlobalVar.ConnPWD);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM " + tableName);
FileWriter writer = new FileWriter(filePath + tableName+".lims2", false);
BufferedWriter bufferedWriter = new BufferedWriter(writer);
bufferedWriter.write("delete from "+tableName + ";");
bufferedWriter.newLine();
while (rs.next()) {
String FieldsString="";
String ValuesString="";
for(int i=0; i< needQuotationMark.size();i++){
tmpString = rs.getString(fieldNames.get(i));
if(tmpString != null){
if(FieldsString.equals("")){
FieldsString += fieldNames.get(i);
ValuesString += (needQuotationMark.get(i)?"'":"")+ tmpString.trim() +(needQuotationMark.get(i)?"'":"");
}else{
FieldsString += "," + fieldNames.get(i);
ValuesString += "," + (needQuotationMark.get(i)?"'":"")+ tmpString.trim() + (needQuotationMark.get(i)?"'":"");
}
}
}
bufferedWriter.write("insert into "+ tableName + "("+FieldsString+") values("+ValuesString+");");
bufferedWriter.newLine();
}
bufferedWriter.close();
writer.close();
rs.close();
stmt.close();
conn.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}調(diào)用以上函數(shù)時,只需將保存建表語句的sql文件位置作為參數(shù)即可,在本項目中,生成的sql文件以.lims2結尾。
3.還原表
由于生成的表數(shù)據(jù)文件較多,這里寫了個批處理文件,將導出的表數(shù)據(jù)文件和該批處理文件一起拷貝到外網(wǎng)服務器中,運行批處理即完成了導入操作。以后準備寫個上傳的頁面,省去了遠程桌面的麻煩。批處理文件如下:
osql -S 127.0.0.1 -U 用戶名 -P 密碼 -d lims2 -i Import_table1.lims2 -o Rst_Import_table1.log
osql -S 127.0.0.1 -U 用戶名 -P 密碼 -d lims2 -i import_table2.lims2 -o Rst_import_table2.log
osql -S 127.0.0.1 -U 用戶名 -P 密碼 -d lims2 -i Import_table3.lims2 -o Rst_Import_table3.log
osql -S 127.0.0.1 -U 用戶名 -P 密碼 -d lims2 -i import_table4.lims2 -o Rst_import_table4.log
osql -S 127.0.0.1 -U 用戶名 -P 密碼 -d lims2 -i import_table5.lims2 -o Rst_import_table5.log
........
結語
此方法適用于同步部分表而不是整庫的情況,尤其是兩個數(shù)據(jù)庫無法直接通信,需要手工同步的場景。
到此這篇關于使用java實現(xiàn)備份和恢復SQLServer表數(shù)據(jù)的文章就介紹到這了,更多相關java備份和恢復SQLServer表數(shù)據(jù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
解決Springboot啟動報錯:類文件具有錯誤的版本61.0,應為?52.0
這篇文章主要給大家介紹了關于解決Springboot啟動報錯:類文件具有錯誤的版本?61.0,應為?52.0的相關資料,這是查閱了網(wǎng)上的很多資料才解決的,分享給大家,需要的朋友可以參考下2023-01-01
SpringSecurity權限控制實現(xiàn)原理解析
這篇文章主要介紹了SpringSecurity權限控制實現(xiàn)原理解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-03-03
SpringBoot整合resilience4j實現(xiàn)接口限流
最近在開發(fā)項目的時候,需要用到限流的功能,本文主要介紹了SpringBoot整合resilience4j實現(xiàn)接口限流,具有一定的參考價值,感興趣的可以了解一下2024-01-01
Jenkins Pipeline為Kubernetes應用部署增加狀態(tài)檢測腳本優(yōu)化
這篇文章主要為大家介紹了Jenkins Pipeline為Kubernetes應用部署增加狀態(tài)檢測腳本優(yōu)化示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-12-12
Spring中的@Value和@PropertySource注解詳解
這篇文章主要介紹了Spring中的@Value和@PropertySource注解詳解,@PropertySource:讀取外部配置文件中的key-value保存到運行的環(huán)境變量中,本文提供了部分實現(xiàn)代碼,需要的朋友可以參考下2023-11-11
Debian 7 和 Debian 8 用戶安裝 Java 8的方法
Oracle Java 8 穩(wěn)定版本近期已發(fā)布,有很多新的特征變化。其中,有功能的程序支持通過“Lambda項目 ”,收到了一些安全更新和界面改進上的bug修復,使得開發(fā)人員的工作更容易。2014-03-03
使用Java編寫導出不確定行數(shù)列數(shù)數(shù)據(jù)的工具類
這篇文章主要為大家詳細介紹了如何使用Java編寫導出不確定行數(shù)列數(shù)數(shù)據(jù)的工具類,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下2024-03-03

