二.受到老同事資料庫同步軟體的啟發,我製作了乙個基於觸發器的同步。
基本風格和老同事的一樣,我們還是先來看介面
繼續沿用了前人的智慧型。。。
第一次介面跳轉時,需要的時間比較長。。。(後台工作比較多)
剛剛幾個圖形不好擷取,就是工具裡面的,包括:表比較,完整備份,差異備份和增量備份。
這個資料庫同步實現的原理是:
在主資料庫伺服器的指定資料庫上面建乙個基於庫的觸發器來記錄資料庫的庫結構改變,然後直接基於資料庫連線在從資料庫上執行一遍;在資料庫內所有的資料表上面建立乙個基於表內容得觸發器來記錄各個表的資料變化情況。在退出軟體時刪掉所有的觸發器。
相關**:
#region
設定同步
//同步是思路:為主伺服器上的每個表都建立三個觸發器,用來做插入、更新、刪除操作。
private void setsynchronous()
#endregion
#region
獲取主伺服器資料庫的表列表
private void gethostserverdatatable()
catch
xmlnode rootnode = xmlhelper.getsubindexnode("systemconfig", 0);//
獲取根節點
xmlnodelist hostserver = rootnode.childnodes[0].childnodes[0].childnodes;//
獲取主伺服器配置節點
xmlnodelist hosttablenode = rootnode.childnodes[1].childnodes[0].childnodes;//
獲取伺服器中所有的表
listmessage.items.add("
準備配置表同步!
");
#region
建立日誌表
//判斷日誌表是否存在
string sql0 = @"if not exists (select 1 from sysobjects where id = object_id('ddl_log2') and type = 'u')
create table ddl_log2 (posttime datetimenotnulldefault(getdate()), tsql text);";
string connectionstring1 = "data source=192.168.0.104//sql2005;database=bobuitest2;user id=sa;password=123456"; //
刪除存在的觸發器
string sql1 = @"if exists (select * from sys.triggers where parent_class = 0 and name = 'log') drop trigger log on database;";
sqlhelper.executenonquery(connectionstring1, commandtype.text, sql0);
sqlhelper.executenonquery(connectionstring1, commandtype.text, sql1);
#endregion
#region
資料同步
foreach (xmlnode xn in hosttablenode)
#endregion
#region
建立資料庫庫結構同步
//建立可能不存在的表
string sql2 = @"if not exists (select 1 from sysobjects where id = object_id('ddl_log2') and type = 'u')"+
"create table ddl_log2 (posttime datetime, tsql nvarchar(2000));"; //
建立結構同步觸發器
string sql3 = @"create trigger log on database for ddl_database_level_events as declare @data xml set @data = eventdata() insert ddl_log2 (posttime, tsql)values(getdate(),@data.value('(/event_instance/tsqlcommand)[1]','nvarchar(2000)') ) ;";
sqlhelper.executenonquery(connectionstring1, commandtype.text, sql2);
sqlhelper.executenonquery(connectionstring1, commandtype.text, sql3);
#endregion }
catch
} #region
刪除表的三種觸發器
private void deletetablestrigger(string tablename, string connectionstring1)
} #endregion
#endregion
#region
建立表的三種觸發器
private void createtablestrigger(string tablename, string connectionstring1)
} #endregion
#region
迴圈讀取更改記錄
private void timer1_tick(object sender, eventargs e)
//製作檔名
if (!directory.exists(path3))
//儲存檔案
//例項化乙個檔案流
--->
與寫入檔案相關聯
filestream fs = new filestream(path2, filemode.create); //
例項化乙個
streamwriter-->與fs
相關聯streamwriter sw = new streamwriter(fs); //
開始寫入
for (int i = 0; i < count; i++)
//清空緩衝區
sw.flush(); //
關閉流sw.close();
fs.close(); }
catch
} #endregion
private void
完全備份
toolstripmenuitem_click(object sender, eventargs e)
//#region
產生乙個隨機的密碼字元
//int password;
//random random = new random();
//password = random.next(1000, 9999);
//string bakup = @"backup database bobuitest2 to disk='" + path + "' withpassword=" + password + "";
//#endregion
string bakup = @"backup database bobuitest2 to disk='" + path + "'";
conn.open();
try
catch
finally
} private void
差異備份
toolstripmenuitem_click(object sender, eventargs e)
string bakup = @"backup database bobuitest2 to disk='" + path + "' with differential ";
conn.open();
try
catch
finally
} 這樣就完成了基於觸發器的資料庫同步,不過這樣存在很多問題。問題1
:在網際網路模式下完全依靠
sql的鏈結是行不通的,特別是資料量大的情況問題2
:在資料庫上加觸發器破壞了資料庫的完整性問題3
:使用觸發器,程式的可控性太差,發生錯誤很難檢查。特別是當從資料庫上執行錯誤時將導致主資料庫也不能執行成功。
上面三個問題告訴我們這種方法行不通。我們必須尋找另外的方法。
資料庫同步方式(二)
exp imp總結 用命令列的方式進行匯出 exp 和匯入 imp 可以進行全域性匯出 入 按使用者匯出 入 按表匯出 入 按資料匯出 入 等方式。匯出 1.全域性匯出 exp system manager orcl file e test bak full.dmp full y 將資料庫orcl完...
SQL 2000 異資料庫資料同步
最近在為客戶做異地分公司 資料庫同步的處理 採用sql 加ftp伺服器來實現 在 中定義處理步驟用vbs實現 客戶端 約定一天只允許同步一次資料 1.測試是否已經備份資料庫,若已備份直接返回 2.按要求整理同步資料,採用儲存過程來整理資料,並存入臨時資料庫中 8.設定備份標誌 3.將臨時資料庫備份至...
資料庫同步相關的SQL語句
一 目標 二 例子 1 找出a表中不存在於b表的記錄。select a.序號 a.日期 a.ip a.部門 a.操作員 a.事件 from a where notexists select 1from b where a.序號 b.序號 2 將a表中不存在於b表的記錄,插入到b表中。insert i...