String Pss=""; if (cs.getString(5).length()>0) Pss= "/"+cs.getString(5)+"%"; 自動檢測資料庫是否與伺服器同步 快速而有效率 條件 總倉或門市 SYS AUPDATE T3 是在SERVER資料範圍 附帶的條件 <=createdatetime 總倉要多檢查 Local SYS TRADENAME T8 0或1 是否拉回的數據 是整體的 不一致的數據成立時,是否 再度確認 BANKNAME 例如 異樣的資料為本機時,update to server 以本機號資料而言 本機為主 修正 伺服器 (異動TR=QKIND -> aa1_aa0_update hi) 異樣的資料為他機時,update to client (整理一份以FORMNO清單,至伺服器取得所有異樣資料Qhead Qitems) 回Local 全面更新 如何設立斷點,而不至於重複檢查,有失效率 第一波 帶著LOCAL 年月範圍 以月為單位 算出 不同步的數據 確認錯誤的節點 程序 第一時間(檢查Qhead): 先以LOCAL BANKNAME 以年-月,單別 %%應注意 年度謄檔 起算點 MYSQL_OK select 0,0,0,SUBSTRING(FORMDATE,1,7),BANKNAME,0,DEPTNO,QKIND,sum(ATOT),sum(ASUM),sum(BSUM),sum(CASH),sum(CARD),sum(ATM),sum(TRCASH),sum(DISMONEY),sum(ORDCASH),sum(ORDCARD),0,0 into outfile '/wamp/www/3G001/3G001_NOW/TEST_DATA/003/SSSA/chksum.csv' fields terminated by ';' lines terminated by '\r\n' from qhead where ISCONFIRM='Y' and ISCHECK='N' and TR<>'Y2' group by SUBSTRING(FORMDATE,1,7),BANKNAME,DEPTNO,QKIND /* 輸出的檔案內容(如果輸出時,檔案已存在時,會引發錯誤,所以需要先清除檔案後,才可以輸出) 0;0;0;2021-12;AA2;0;AA;10;829;4124857;4124857;0;0;0;0;0;0;0;0;0 0;0;0;2022-01;AA1;0;AA;30;61;24839;24839;24839;0;0;0;0;0;0;0;0 0;0;0;2022-01;AA2;0;AA;10;24;13540;13540;0;0;0;0;0;0;0;0;0 */ 這個檔案送回local 應存入一個臨時的table 且索引為 (SUBSTRING(FORMDATE,1,7),BANKNAME,DEPTNO,QKIND) 再透過 local 一樣的語法取得數據,再一一比對 利用前面三個欄位 將比對結果,存入狀態 如果數據有誤 應紀錄單號 狀況一: 在LOCAL端單據找到 但是數據有誤時 先比對BANKNAME 是自方單據時 (DOWND=1) 應產生一筆 預備傳送SERVER TR=QKIND 不是 自方單據時 (應紀錄讓SERVER 再度取回該單回LOCAL端更新) 狀況二: 在LOCAL端不存在時 先比對 BANKNAME 是自方單據時 應進行 該單號自SERVER端刪除 UPD=2 不是 自方單據時 (應紀錄讓SERVER 再度取回該單回LOCAL端更新) UPD=1 @@@以所有會員帳面檢測是否 LOCAL vs SERVER一致 DEPTNO,USER,QKIND,sum(BSUM),sum(CASH),sum(CARD),sum(ATM) @@@以日期區間為範圍從伺服器拉回一個表 暫定3個月約 90筆CSV //mUser=單一門市 DBCLOUD版 //qhead String SQLCHK="select 0,0,0,FORMDATE,0,DEPTNO,QKIND, sum(ATOT),sum(ASUM),sum(BSUM),sum(CASH),sum(CARD),sum(ATM),sum(TRCASH),sum(DISMONEY),0,0 from qhead where (FORMDATE >='"+BGCHKDATE+"' and FORMDATE<='"+ENCHKDATE+"') and ISCONFIRM='Y' and ISCHECK='N' and TR<>'Y2'"; if (apart==1){//只針對單一門市 SQLCHK+=" and (USER='"+mUser+"' or DEPTNO='"+mUser+"' )"; }else{ if (Utilis.getIni(context, "SYS", "TRADENAME", 8).equalsIgnoreCase("1")) //1表示總倉不要同步門市 (31,41) 但是 (20,21)要 SQLCHK+=" and (QKIND<>'31' and QKIND<>'41')"; } SQLCHK+=" group by FORMDATE,DEPTNO,QKIND" 在PHP 取回一個CSV檔 然後再 LOCAL 以CSV 一一檢視 每日的各項數據 如果數據有誤 應紀錄日期 再一一以日期為單位 String CHKDATE 取回以單號 String SQLCHK="select 1,0,0,FORMDATE,FORMNO,DEPTNO,QKIND, ATOT,ASUM,BSUM,CASH,CARD,ATM,TRCASH,DISMONEY,BANKNAME,CREATEDATETIME from qhead where FORMDATE='"+CHKDATE+"' and ISCONFIRM='Y' and ISCHECK='N' and TR<>'Y2'"; if (apart==1){//只針對單一門市 SQLCHK+=" and (USER='"+mUser+"' or DEPTNO='"+mUser+"' )"; }else{ if (Utilis.getIni(context, "SYS", "TRADENAME", 8).equalsIgnoreCase("1")) //1表示總倉不要同步門市 (31,41) 但是 (20,21)要 SQLCHK+=" and (QKIND<>'31' and QKIND<>'41')"; } 在PHP 取回一個CSV檔 應該在LOCAL端 有一個臨時資料庫 以CSV檔 及 加入 兩個欄位 0,0 以做為 上傳 && 下載 && 刪除紀錄 留待進一步處理程序 LOCAL端需要異動者 可以馬上異動 資料結構: 每次CHECK時 應清除資料 KIND,UPD,DOWND,FORMDATE,FORMNO,DEPTNO,QKIND, ATOT,ASUM,BSUM,CASH,CARD,ATM,TRCASH,DISMONEY,BANKNAME,CREATEDATETIME 日/單 上傳 下載 第一波帶回以日期為單位 KIND=0 FORMNO="0" 第二波帶回以單號為單位 KIND=1 UPD,DOWN 都是填入0 然後再 LOCAL 以CSV 一一檢視 每筆的各項數據 如果數據有誤 應紀錄單號 狀況一: 在LOCAL端單據找到 但是數據有誤時 先比對BANKNAME 是自方單據時 (DOWND=1) 應產生一筆 預備傳送SERVER TR=QKIND 不是 自方單據時 (應紀錄讓SERVER 再度取回該單回LOCAL端更新) 狀況二: 在LOCAL端不存在時 先比對 BANKNAME 是自方單據時 應進行 該單號自SERVER端刪除 UPD=2 不是 自方單據時 (應紀錄讓SERVER 再度取回該單回LOCAL端更新) UPD=1 @@@盲點 一切以SERVER端資料為主 唯獨LOCAL端有資料,而SERVER沒有資料時 如何察覺呢 往往這是最常發生的狀況,反而需要第三波 qitems 是否也要 Check @@@01 目前設計 Local端 可能已執行年度謄檔 應當謹慎規範 日期範圍資料 且避開年度轉結的資料 (資料範圍-全面)需考慮 @@@01 local 檢測 Qhead ATOT = = Qitems sum(UNIT(10 20 30 40)) 先記錄異樣的 FORMNO,USER,FORMDATE ATOT 再取得 server 一份一樣的數據 當Server正確 update to Client (怎樣從Server取得整筆Qhead Qitems 再度的傳回更新) 當Client正確 update to Server (異動TR=QKIND -> aa1_aa0_update_hi) 當兩端都 異樣時 警告使用者(FORMDATE FORMNO USER ATOT BSUM ) 發現在SERVER中 QHEAD ATOT 和 QITEMS UNIT() 件數不符 通常是 存入SERVER QITEMS 有REPEAT 問題 或有 QITEMS 比數 資料結構 ID FORMNO FORMDATE ATOT TATOT sum(BSUM)+sum(CASH)+sum(CARD)+sum(ATM)+sum(TRCASH),sum(DISMONEY)