靈魂-放水

          為學(xué)日益,為道日損。

          BlogJava 首頁(yè) 新隨筆 聯(lián)系 聚合 管理
            296 Posts :: 10 Stories :: 274 Comments :: 0 Trackbacks
           

          在虛擬主機(jī)的環(huán)境下,因?yàn)闆](méi)有管理員權(quán)限,只有數(shù)據(jù)庫(kù)使用權(quán)限,定時(shí)備份SQL數(shù)據(jù)是

          個(gè)比較麻煩的問(wèn)題。解決思路如下:(僅對(duì)SQL2000有效)
          1. 利用T-SQL備份數(shù)據(jù)庫(kù)到指定目錄,文件名根據(jù)日期指定。
          2. 利用Resin的定時(shí)功能,定時(shí)執(zhí)行備份。
          3. 用戶定時(shí)下載備份并且刪除過(guò)期備份。

          導(dǎo)出全部數(shù)據(jù)到Excel也比較實(shí)用。下面提供的方法可以導(dǎo)出庫(kù)中的全部表,也可以指定

          幾個(gè)表導(dǎo)出。注意:
          1. 因?yàn)槭菍?dǎo)出全部數(shù)據(jù),在數(shù)據(jù)比較多的情況下慎用。
          2. 理論上應(yīng)該適用各種JDBC數(shù)據(jù)庫(kù),僅對(duì)SQL2000測(cè)試過(guò)
          3. 對(duì)于B/S下載,建議不要在服務(wù)器上生成文件,以免造成垃圾文件。直接從HTTP的Response中取得OutputStream進(jìn)行輸出。
          4. Excel操作的API請(qǐng)到這里下載:http://www.andykhan.com/jexcelapi/

          package steeven;
          import jxl.write.*;
          import java.util.*;
          import java.sql.Statement;
          import java.sql.ResultSet;
          import java.sql.Types;
          import java.sql.Connection;
          import java.sql.PreparedStatement;
          import java.sql.SQLException;
          import java.text.DateFormat;
          import java.io.*;

          /**
           * <p>Title: 數(shù)據(jù)庫(kù)備份</p>
           * <p>Description: 在Java中備份數(shù)據(jù)庫(kù)</p>
           * @author steeven
           * @version 1.0
           */
          public class DBackup{
              Context ctx ;
              public DBackup(Context ctx) {
                  this.ctx = ctx;
              }
              /**
               * 備份SQL2000數(shù)據(jù)庫(kù)到文件,整個(gè)數(shù)據(jù)庫(kù)備份
               * 文件名后面將追加備份年月日。例如:c:\dbBackup\mydb031109
               * @param file 導(dǎo)出的文件名全路徑。例如:"c:\\dbBackup\\mydb"
               */
              public void backup(String dbName, String file)throws SQLException{
                  String sql = "BACKUP DATABASE ["+dbName+"] TO DISK = N'";
                  sql += file + new SimpleDateFormat("yyMMdd").format(new Date());
                  sql += "' WITH  NOINIT ,  NOUNLOAD ,  NAME = N'lvdong',  NOSKIP , 

          STATS = 10,  NOFORMAT";
                  Statement stmt = ctx.getConnection().createStatement();
                  stmt.executeUpdate(sql);
              }
              /**
               * 導(dǎo)出整個(gè)數(shù)據(jù)庫(kù)到Excel
               * @param conn 數(shù)據(jù)庫(kù)連接
               * @param out 輸出Stream
               */
              public static void db2Excel(Connection conn,OutputStream out)throws

          Exception{
                  db2Excel(conn,out,getTables(conn));
              }
              /**
               * 導(dǎo)出數(shù)據(jù)庫(kù)中指定的表名到Excel
               * @param conn 數(shù)據(jù)庫(kù)連接
               * @param out 輸出Stream
               * @param tables 表名
               * @throws Exception
               */
              public static void db2Excel(Connection conn,OutputStream out,List

          tables)throws Exception{
                  WritableWorkbook wb = jxl.Workbook.createWorkbook(out);
                  for (int i = 0; i < tables.size(); i++) {
                      WritableSheet sheet = wb.createSheet(tables.get(i).toString(),i);
                      writeSheet(sheet,tables.get(i).toString(),conn);
                  }
                  wb.write();
                  wb.close();
              }
              /**
               * 導(dǎo)出表數(shù)據(jù)到Excel的sheet
               */
              public static void writeSheet(
                  WritableSheet sheet,String table,Connection conn)
                  throws Exception
              {
                  //取得所有表數(shù)據(jù)
                  String sql = "select * from "+DB.ESC1+table+DB.ESC2;
                  ResultSet rs = conn.createStatement().executeQuery(sql);
                  //根據(jù)ResultSet的MetaData取得表頭,列數(shù),列寬
                  java.sql.ResultSetMetaData meta = rs.getMetaData();
                  int n = meta.getColumnCount();
                  int row = 0;
                  WritableCellFormat fmt = new WritableCellFormat();
                  fmt.setBackground(jxl.format.Colour.YELLOW);
                  for (int i = 0; i < n; i++){
                      //導(dǎo)出表頭
                      sheet.addCell(new Label(i, row, meta.getColumnLabel(i + 1),fmt));
                      //設(shè)定列寬
          //            sheet.setColumnView(i,meta.getColumnDisplaySize(i+1));
                  }
                  row++;
                  while(rs.next()){
                      for (int i = 0; i < n; i++){
                          //根據(jù)列的類型決定Excel中對(duì)應(yīng)的Cell類型,缺省為文本。
                          WritableCell cell ;
                          switch(meta.getColumnType(i+1)){
                              case Types.BIT:
                              case Types.BIGINT:
                              case Types.BOOLEAN:
                              case Types.DECIMAL:
                              case Types.FLOAT:
                              case Types.INTEGER:
                              case Types.NUMERIC:
                              case Types.REAL:
                              case Types.SMALLINT:
                              case Types.TINYINT:
                                  double val = rs.getDouble(i+1);
                                  if (rs.wasNull()) cell = new jxl.write.Blank(i,row);
                                  cell = new jxl.write.Number(i, row, val);
                                  break;
                              case Types.DATE:
                              case Types.TIME:
                              case Types.TIMESTAMP:
                                  Date date = rs.getDate(i + 1);
                                  if (rs.wasNull()) cell = new jxl.write.Blank(i,row);
                                  else cell = new jxl.write.DateTime(i, row, date);
                                  break;
                              default:
                                  cell = new Label(i, row, rs.getString(i + 1));
                          } //end of switch
                          sheet.addCell(cell);
                      }//end of for each column
                      row++;
                  }//end of while(rs.next())
              }
              /**
               * 從Connection的MetaData取得所有數(shù)據(jù)表的名稱
               */
              public static List getTables(Connection conn)throws Exception{
                  ResultSet rs = conn.getMetaData().getTables(
                      null,null,null,new String[]{"Table"});
                  List list = new ArrayList();
                  while(rs.next())
                      list.add(rs.getString(3));
                  rs.close();
                  return list;
              }

              public static void main(String[] args) throws Exception{
                  Connection conn = DB.getConn();
                  FileOutputStream out = new FileOutputStream("c:\\test.xls");
                  db2Excel(conn,out);
                  out.close();
                  conn.close();
              }
          }

          ------------------------------------
          關(guān)于虛擬主機(jī)的數(shù)據(jù)庫(kù)如何備份
          1.最早的時(shí)候用sqlserver的備份功能,在本地可以實(shí)現(xiàn),用程序調(diào)用就可以了。后來(lái)發(fā)不到虛擬機(jī)的時(shí)候才發(fā)現(xiàn),虛擬機(jī)把大部分的存儲(chǔ)過(guò)程都給關(guān)閉了。只好考慮用別的方法。
          2.后來(lái),我就用自己寫的存儲(chǔ)過(guò)程來(lái)備份數(shù)據(jù)庫(kù),當(dāng)時(shí)是虛擬主機(jī)和數(shù)據(jù)庫(kù)在同一臺(tái)機(jī)器上,ok沒(méi)有問(wèn)題了。
          3.現(xiàn)在由于速度問(wèn)題,虛擬主機(jī)必須移到香港,所以第二種方法就沒(méi)法子實(shí)現(xiàn)了。
          想來(lái)想去,嘿嘿,利用本地的sqlserver。
          新建一個(gè)包,然后點(diǎn)“復(fù)制sqlserver 對(duì)象任務(wù)”,然后輸入源/目的/復(fù)制的信息。一般如果是數(shù)據(jù)量比較少的話,我們可以用替換現(xiàn)有數(shù)據(jù),也是最正常的情況,我覺(jué)得這個(gè)比較可行,如果是追加的話,就會(huì)丟失修改的信息。然后,虛擬主機(jī)的sqlserver一般需要用戶名密碼,那么我們就在自己本地的sqlserver的安全里面也增加相同用戶名及密碼。這樣我們執(zhí)行的時(shí)候就不會(huì)出問(wèn)題了。
          然后我們保存這個(gè)包,確信sqlagent服務(wù)已經(jīng)啟動(dòng)。如果啟動(dòng)了,那么我們?cè)跀?shù)據(jù)轉(zhuǎn)換服務(wù)-本地包,然后右擊我們剛才創(chuàng)建的包,選擇調(diào)度。設(shè)定一個(gè)時(shí)間段,我一般選擇12點(diǎn),那時(shí)候大家都去吃飯了~~
          posted on 2008-07-02 16:12 放水老倌 閱讀(704) 評(píng)論(0)  編輯  收藏 所屬分類: 數(shù)據(jù)庫(kù)
          主站蜘蛛池模板: 长兴县| 祥云县| 黄梅县| 攀枝花市| 马边| 汤阴县| 湖南省| 蒲城县| 满洲里市| 湾仔区| 房产| 腾冲县| 茶陵县| 榆社县| 会宁县| 武城县| 溧水县| 三穗县| 平湖市| 黄石市| 繁峙县| 滨州市| 呈贡县| 视频| 淮安市| 洱源县| 绥滨县| 邻水| 太仆寺旗| 辽宁省| 泰兴市| 宁海县| 金门县| 南宁市| 徐闻县| 仁寿县| 文昌市| 宜春市| 威海市| 宁陵县| 常州市|