標籤:base 忽略 nta sch 更新記錄 特定 update array cti
1、背景:
客戶要求更改員工編號,使其具有某一 特定規則,此編號類似於人員的ID,可能被幾十張表引用
2、思路:
先找到關聯此欄位的具體表以及具體欄位,逐一排查確定最終sql語句,寫出邏輯規則,採用程式輸出的方式輸出修複語句
3、具體實現:
import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.Map.Entry;import java.util.Set;import org.apache.log4j.Logger;import eman.spring.BaseJdbcDao;import eman.spring.jdbc.BaseJdbcTemplate;public class UpdateEManHumanIDSql extends BaseJdbcDao{private BaseJdbcTemplate jdbc = this.getJdbcTemplate();private static Logger log4j = Logger.getRootLogger();/*** 程式入口* @author* @date 2018年8月31日* @param type*/public static void main(String[] args) { new UpdateEManHumanIDSql().comprehensiveCallMethod("11");//測試}/*** 方法調用邏輯* @author* @date 2018年8月31日* @param type*/public void comprehensiveCallMethod(String type){ //1、擷取Human表中的所有humanID List<String> humanList = this.getHumanList(); //2、將humanID按8位的規則進行拼接,得到鍵為原humanID,值為新humanID的map Map<String, String> humanMap = this.getHumanMap(humanList, type); //3、擷取需要更新的表名以及表中欄位,鍵為表名,值為涉及欄位的list集合 Map<String, List<String>> tableMap = this.getTableMap(); //4、執行update語句 this.mainLogicMethod(tableMap, humanList, humanMap);}/*** 擷取humanID集合* @author* @date 2018年8月31日* @return List<String>*/private List<String> getHumanList(){ String sql = "SELECT humanID FROM Human WHERE humanID<>‘admin‘"; return jdbc.eManForList(sql, String.class);}/*** * 擷取原來的humanID並根據公司編號拼接新的的humanID,以map的形式返回* @author* @date 2018年8月31日* @param humanIDList - humanID集合* @param type * @return Map<String,String>* 鍵 - 原humanID, 值 - 新的humanID*/private Map<String, String> getHumanMap(List<String> humanIDList,String type){ HashMap<String, String> humanMap = new HashMap<String, String>(); if (humanIDList == null || humanIDList.isEmpty()) { return null; } String newHumanID = ""; for (String humanID : humanIDList) { newHumanID = humanID; if (newHumanID.toUpperCase().contains("KT")) { newHumanID = newHumanID.substring(2, newHumanID.length()); } if (newHumanID.length() == 4) { humanMap.put(humanID, type + "00" + newHumanID); } else if (newHumanID.length() == 5){ humanMap.put(humanID, type + "0" + newHumanID); } else if (newHumanID.length() == 6){ humanMap.put(humanID, type + newHumanID); } else if (newHumanID.length() == 8){ humanMap.put(humanID, newHumanID); } } return humanMap;}/*** 擷取跟humanID有關的表以及對應的列* @author * @date 2018年8月31日* @return Map<String,String>* 鍵 - 表名, 值 - 欄位名的list集合*/private Map<String, List<String>> getTableMap(){ String sql = "SELECT columns.TABLE_NAME,columns.COLUMN_NAME " + " FROM information_schema.columns " + " WHERE DATA_TYPE LIKE ‘%char‘ " + " AND (COLUMN_NAME LIKE ‘%human%‘ " + " OR COLUMN_NAME LIKE ‘%oper%‘ " + " OR COLUMN_NAME LIKE ‘%person%‘ " + " OR COLUMN_NAME LIKE ‘%executor%‘ " + " OR COLUMN_NAME LIKE ‘%loginID%‘" + " OR COLUMN_NAME LIKE ‘%projectAdderID%‘ " + " OR COLUMN_NAME LIKE ‘%man%‘) " + " OR COLUMN_NAME LIKE ‘%designer%‘) " + " OR COLUMN_NAME LIKE ‘%employeeID%‘) " + " OR COLUMN_NAME LIKE ‘%checkID%‘) " + " AND COLUMN_NAME NOT LIKE ‘%operation%‘ " + " AND COLUMN_NAME NOT IN (‘Wit_TreatManner‘,‘humanMonitorID‘,‘humanMonitorLengthID‘,‘humanSort‘" + ",‘manageState‘,‘HumanName‘,‘manufactureClassID‘,‘directoryProperties‘,‘demandFrom‘) " + " AND TABLE_NAME NOT LIKE ‘v_%‘" + " AND TABLE_NAME NOT LIKE ‘%View%‘"; return jdbc.eManForMapList(sql, null, String.class, String.class);}/*** 主邏輯* @author* @date 2018年8月31日* @param tableMap - 涉及的表以及欄位的集合* @param humanList - humanID集合* @param humanMap - 鍵-原來的humanID,值-新的humanID*/private void mainLogicMethod(Map<String, List<String>> tableMap, List<String> humanList, Map<String, String> humanMap){ if (tableMap == null || tableMap.isEmpty()) {//涉及表為空白直接返回 return; } Set<Entry<String, List<String>>> entrySet = tableMap.entrySet(); String key = "";//tableMap的鍵 List<String> value = new ArrayList<String>();//tableMap的值 List<String> list = new ArrayList<String>();//指定表及指定列需要更新的值集合 int i = 1;//用於調試輸出更新的第幾張表 try { this.beginTransaction(); for (Entry<String, List<String>> entry : entrySet) { key = entry.getKey(); value = entry.getValue(); if (value == null) { continue; } System.out.println("--更新第"+ i +"張表:" + key);//調試資訊,實際可忽略! for (String column : value) { if ("BOM".equals(key)) { System.out.println(); } list = this.getRelationHumanID(key, column);//擷取涉及欄位的值不為空白的list集合 if (list == null || list.size() == 0) {//為空白直接跳過 System.out.println(" --第"+ i +"張表" + key + "的列" + column + "無需要更新記錄!");//調試資訊,實際可忽略! continue; } System.out.println("--更新列:" + column);//調試資訊,實際可忽略! for (String str : list) {//執行更新 if (humanMap.containsKey(str)) { this.updateRelationHumanID(key, column,str,humanMap.get(str)); } } } i++; } this.commit(); } catch (Exception e) { log4j.warn("更新失敗!", e); e.printStackTrace(); }}/*** 擷取當前表中對應欄位需要更新的值* @author* @date 2018年8月31日* @param tableName* @param columnName* @return List<String> - 需要更新的值集合*/private List<String> getRelationHumanID(String tableName, String columnName){ String sql = "SELECT DISTINCT " + columnName + " FROM " + tableName + " WHERE " + columnName + " IS NOT NULL AND " + columnName + "<>‘‘"; return jdbc.eManForList(sql, String.class);}/*** 擷取更新語句* @author* @date 2018年8月31日* @param tableName - 表名* @param columnName - 欄位名* @param humanID - 原humanID* @param newHumanID - 新的humanID*/private void updateRelationHumanID(String tableName, String columnName, String humanID, String newHumanID){ String sql = "UPDATE " + tableName + " SET " + columnName + " = ‘" + newHumanID + "‘ WHERE " + columnName + " = ‘" + humanID + "‘"; this.jdbc.update(sql); System.out.println(sql);}}
3.2、禁用外鍵和觸發器
-- 禁用所有的外鍵約束
DECLARE @sql1 NVARCHAR (1000)
DECLARE @tabname VARCHAR (50)
DECLARE @tabfkn VARCHAR (100)
DECLARE tabs CURSOR FOR SELECT b.name tabname , a.name tabfk FROM sysobjects a , sysobjects b WHERE a.xtype = ‘f‘ AND a.parent_obj = b.id
OPEN tabs
FETCH next FROM tabs INTO @tabname, @tabfkn
WHILE @@FETCH_STATUS = 0
BEGIN
SET @sql1 = ‘ALTER TABLE [‘ + @tabname + ‘] NOCHECK CONSTRAINT ‘+ @tabfkn +‘;‘;
-- PRINT @sql1;
EXEC sp_executesql @sql1;
FETCH next FROM tabs INTO @tabname, @tabfkn
END
CLOSE tabs
DEALLOCATE tabs
GO
-- 禁用所有的觸發器約束
DECLARE @sql1 NVARCHAR (1000)
DECLARE @tabname VARCHAR (50)
DECLARE @tabfkn VARCHAR (100)
DECLARE tabs CURSOR FOR SELECT b.name tabname , a.name tabfk FROM sysobjects a , sysobjects b WHERE a.xtype = ‘TR‘ AND a.parent_obj = b.id
OPEN tabs
FETCH next FROM tabs INTO @tabname, @tabfkn
WHILE @@FETCH_STATUS = 0
BEGIN
SET @sql1 = ‘ALTER TABLE [‘ + @tabname + ‘] DISABLE TRIGGER ‘+ @tabfkn +‘;‘;
-- PRINT @sql1;
EXEC sp_executesql @sql1;
FETCH next FROM tabs INTO @tabname, @tabfkn
END
CLOSE tabs
DEALLOCATE tabs
GO
3.3、啟用外鍵和觸發器
-- 啟用所有的觸發器約束
DECLARE @sql1 NVARCHAR (1000)
DECLARE @tabname VARCHAR (50)
DECLARE @tabfkn VARCHAR (100)
DECLARE tabs CURSOR FOR SELECT b.name tabname , a.name tabfk FROM sysobjects a , sysobjects b WHERE a.xtype = ‘TR‘ AND a.parent_obj = b.id
OPEN tabs
FETCH next FROM tabs INTO @tabname, @tabfkn
WHILE @@FETCH_STATUS = 0
BEGIN
SET @sql1 = ‘ALTER TABLE [‘ + @tabname + ‘] ENABLE TRIGGER ‘+ @tabfkn +‘;‘;
-- PRINT @sql1;
EXEC sp_executesql @sql1;
FETCH next FROM tabs INTO @tabname, @tabfkn
END
CLOSE tabs
DEALLOCATE tabs
GO
-- 啟用所有的外鍵約束
DECLARE @sql1 NVARCHAR (1000)
DECLARE @tabname VARCHAR (50)
DECLARE @tabfkn VARCHAR (100)
DECLARE tabs CURSOR FOR SELECT b.name tabname , a.name tabfk FROM sysobjects a , sysobjects b WHERE a.xtype = ‘f‘ AND a.parent_obj = b.id
OPEN tabs
FETCH next FROM tabs INTO @tabname, @tabfkn
WHILE @@FETCH_STATUS = 0
BEGIN
SET @sql1 = ‘ALTER TABLE [‘ + @tabname + ‘] CHECK CONSTRAINT ‘+ @tabfkn +‘;‘;
-- PRINT @sql1;
EXEC sp_executesql @sql1;
FETCH next FROM tabs INTO @tabname, @tabfkn
END
CLOSE tabs
DEALLOCATE tabs
GO
關於修複資料的問題(案例1)