<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    亡羊補牢,為時未晚!!!

    Posted on 2010-09-06 11:21 java小爬蟲 閱讀(1535) 評論(0)  編輯  收藏
        有這么一種場景,設(shè)計好的數(shù)據(jù)模型在有數(shù)據(jù)以后要修改數(shù)據(jù)模型。本文就是針對這個問題展開的。
        要增加,刪除一列,這根本不是問題,關(guān)鍵是要修改一列。這需要考慮到那些問題呢?
        在java里面有類型轉(zhuǎn)換,轉(zhuǎn)換分為兩種:自然轉(zhuǎn)換和強制轉(zhuǎn)換。自然轉(zhuǎn)換就是把子類型轉(zhuǎn)成父類型,強制轉(zhuǎn)換就是把父類型轉(zhuǎn)成子類型。在數(shù)據(jù)庫里面也一樣,當(dāng)然還要包括長度的截短和加長。強制轉(zhuǎn)換和截短會造成數(shù)據(jù)的不準(zhǔn)確和異常,本文不考慮這個情況。
        那么,如何改變數(shù)據(jù)表的列類型呢?通過SQL語句直接操作數(shù)據(jù)庫,當(dāng)然能解決這個問題,可是,如何有很多張表都要修改呢?那不把人累死了!!!
     
        我就碰到了這么一個問題,加班加點的,寫成了一個JAVA小程序,來自動實現(xiàn)我的要求。

        需求:把數(shù)據(jù)庫中字段類型為blob和varchar2(4000)的數(shù)據(jù)表都修改為clob;

        問題解決思路:復(fù)制數(shù)據(jù)表結(jié)構(gòu)和數(shù)據(jù)到一個臨時表,先刪除要修改的列,再創(chuàng)建同名不同類型的列,從原始表中查出這一列的數(shù)據(jù),復(fù)制的臨時表中,刪除原始表,修改臨時表名為原始表名。

        處理過程日志截圖:


        代碼思路及重要代碼:
        1:獲取系統(tǒng)所有的用戶表:
                 String sql = " select table_name from user_tables " ;
        2:獲取表的主鍵(只考慮單主鍵) 
                 String sql = "  select column_name from user_cons_columns " +
                            "  where constraint_name = (" +
                                  "  select constraint_name from user_constraints " +
                                      " where table_name = upper('"+tableName+"') " +
                                          "and constraint_type = 'P'" +
                                              ")" ; 
        3:獲取表中列信息:列名,類型 和長度。
                 String sql = " select column_name,data_type,data_length from user_tab_columns  where table_name =  '"+ tableName+"'" ;   
        4:根據(jù)2和3,判斷要修改的列,組織(主鍵和要修改的列信息)數(shù)據(jù)。
            代碼片段:

            List<String[]> :裝有要修改表的表名,主鍵,列信息(列名,類型,長度);List中,第一條數(shù)據(jù)為表名,第二條數(shù)據(jù)為主鍵,其余為要修改的列信息,String[]為變長數(shù)組;
       
    String columnName="";
            String dataType
    ="";
            String dataLength
    ="";
            List
    <String[]> result = new ArrayList<String[]>(3);
            result.add(
    new String[]{tableName});
            String primaryKeyName 
    = getPrimaryKey(tableName);
            
    if(primaryKeyName.equals("")||primaryKeyName==nullreturn null ;
            result.add(
    new String[]{primaryKeyName});
                
    try {
                    String sql 
    = " select column_name,data_type,data_length from user_tab_columns  where table_name =  '"+ tableName+"'" ;    
                    ResultSet resultSet 
    = OracleDBUtil.executeQuery(sql);
                    
    while(resultSet.next()){
                        columnName
    =resultSet.getString(1);
                        dataType
    =resultSet.getString(2);
                        dataLength
    =resultSet.getString(3);
                        
    if(dataType.equals("BLOB")){
                            result.add(
    new String[]{columnName,dataType});
                        }
    else if((dataType.equals("VARCHAR2")&&Integer.parseInt(dataLength) >= Constant.varchar2_size)||(dataType.equals("VARCHAR")&&Integer.parseInt(dataLength) >= Constant.varchar2_size)){
                            result.add(
    new String[]{columnName,dataType,dataLength});
                        }
                    }
                    resultSet.close();
                } 
    catch (SQLException e1) {
                    e1.printStackTrace();
                }
            
    return result;
        5:取出4返回的信息,組織數(shù)據(jù),啟動修改流程;
    for (List<String[]> table : tables) {
                
    //tableInfo = tableInfo+  "\t表名:\t" ;
                tableInfo = "\t表名:\t" ;
                tableInfo 
    = tableInfo+table.get(0)[0]+ "\t主鍵 :\t "+table.get(1)[0]+" \t字段 :\t ";
                String[] columns 
    = new String[table.size()-2];
                
    for (int i =2;i<table.size();i++) {
                    
    if(table.get(i)==nullbreak ;
                    tableInfo 
    = tableInfo+table.get(i)[0]+"  "+table.get(i)[1];
                    
    if(table.get(i).length == 3) tableInfo = tableInfo+ "("+table.get(i)[2]+")";
                    tableInfo 
    = tableInfo + "\t";
                    String[] columnInfo 
    = table.get(i) ;
                    columns[i
    -2]=columnInfo[0];
                }
                tableInfo 
    = tableInfo+"\n";
                System.out.println(tableInfo);
                
                
                BufferedReader in 
    = new BufferedReader(new InputStreamReader(System.in));
                String str 
    = "";
                    System.out.println(
    "   是否修改,請輸入'Y'或者'N' ! ");
                    
    try {
                        str 
    = in.readLine();
                    } 
    catch (IOException e) {
                        e.printStackTrace();
                    }
                    
    if(str.equalsIgnoreCase("y")){
                        blobOrVarchar2Clob(table.get(
    0)[0],table.get(1)[0],columns);
                    }
            }
            
            System.out.println(
    "數(shù)據(jù)表修改處理邏輯結(jié)束!!!");

        6:修改流程:使用了門面模式,實現(xiàn)了“復(fù)制數(shù)據(jù)表結(jié)構(gòu)和數(shù)據(jù)到一個臨時表,先刪除要修改的列,再創(chuàng)建同名不同類型的列,從原始表中查出這一列的數(shù)據(jù),復(fù)制的臨時表中,刪除原始表,修改臨時表名為原始表名。”構(gòu)想。
        
    public static boolean blobOrVarchar2Clob(String srcTableName, String srcTableIdName, String columnNames) {
            
    if (srcTableName == null || srcTableName.equals("")
                    
    || columnNames == null || columnNames.length == 0
                    
    || srcTableIdName == null || srcTableIdName.equals(""))
                
    return false;
            String printColumnNames 
    = "" ;
            
    for (String columnName : columnNames) {
                printColumnNames 
    += "  " +  columnName ;
            }
            System.out.println(
    "馬上就被修改  表名: "+srcTableName +  "   ,ID: " + srcTableIdName+"  字段:   "+printColumnNames);
            Utils.createTempTable(srcTableName);
            
    for (String columnName : columnNames) {
                
    if(columnName==null||columnName.equals(""))continue ;
                Utils.dropTempTableColumn(srcTableName, columnName);
                Utils.addTempTableClobColumn(srcTableName, columnName);
                Utils.copyDataOneColumn(srcTableName, columnName, srcTableIdName);
            }
            Utils.dropSrcTable(srcTableName
    +"_");
    //        Utils.dropSrcTable(srcTableName);
    //        Utils.modifyTempTableToSrcTable(srcTableName);
            return true;
        }

        7:從原始表復(fù)制一列數(shù)據(jù)到臨時表:將數(shù)據(jù)寫入Map結(jié)構(gòu),再寫入臨時表。
          代碼片斷:
       
    HashMap<Integer, String> map = new HashMap<Integer, String>();
        
                
    try {
                    
    while(resultSet.next()){
                        String content 
    = "";            
                            
    int id = resultSet.getInt(srcTableIdName);
                            
                            
    int columnIndex = resultSet.findColumn(columnName);
                             ResultSetMetaData resulSetMetaData 
    = resultSet.getMetaData();
                             String columnTypeName 
    =resulSetMetaData.getColumnTypeName(columnIndex);
                            
                             
    if("VARCHAR2".equals(columnTypeName)||"VARCHAR".equals(columnTypeName)){
                                 content 
    = resultSet.getString(columnName);
                             }
    else if("BLOB".equals(columnTypeName)){
                                    Blob blob 
    = resultSet.getBlob(columnName);
                                    
    if(blob==null)continue;
                                    content 
    = Utils.readBlobToString(blob);
                             }
                            map.put(id, content);
                    }
                    resultSet.close();
                } 
    catch (SQLException e1) {
                    e1.printStackTrace();
                }
            
            Set
    <Entry <Integer,String> > set = map.entrySet();
            Iterator
    <Entry<Integer, String>> iterator =set.iterator();
            
    while(iterator.hasNext()){
                Entry
    <Integer, String> entry = iterator.next();
            sql 
    = " update " + srcTableName + "" + " set "
                
    + columnName + " = ? where " + srcTableName + "_."
                
    + srcTableIdName + " = ? "  ;
            PreparedStatement pstatement 
    =OracleDBUtil.getPreparedStatement(sql);
            
    try {
                pstatement.setString(
    1, entry.getValue());
                pstatement.setInt(
    2, entry.getKey());
                OracleDBUtil.executeUpdate(pstatement);
                pstatement.close();




    只有注冊用戶登錄后才能發(fā)表評論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 亚洲精品无码不卡在线播HE| 亚洲韩国精品无码一区二区三区| 亚洲AV日韩AV天堂久久| 香蕉视频在线观看免费| 高清国语自产拍免费视频国产| 色老板亚洲视频免在线观| 国产电影午夜成年免费视频| 亚洲日韩中文字幕| 亚洲AV无码之国产精品| 日韩电影免费在线观看中文字幕| 亚洲av无码国产精品色午夜字幕| 久久www免费人成看国产片| 99视频在线精品免费观看6| 亚洲av专区无码观看精品天堂| 国产无限免费观看黄网站| AV在线播放日韩亚洲欧| 亚洲中文无码永久免| 成人最新午夜免费视频| 亚洲AV无码成人精品区狼人影院| 国产成人无码区免费A∨视频网站| 黄网站色视频免费看无下截| 亚洲综合国产精品第一页| 成人A片产无码免费视频在线观看| 亚洲AV日韩精品久久久久久久| 永久免费在线观看视频| 亚洲sss综合天堂久久久| 国产免费久久精品| 视频免费在线观看| 亚洲伊人久久大香线焦| 在线免费观看国产视频| 亚洲伊人久久大香线蕉在观| 日韩免费视频播播| 免费无码又爽又刺激网站直播| 亚洲成aⅴ人片在线观| 国产美女a做受大片免费| 黄色网址免费在线观看| 亚洲制服丝袜在线播放| 亚洲成A人片在线观看无码3D| 一区二区三区免费在线视频| 国产精品亚洲精品日韩已满| 999久久久免费精品国产|