灵魂-放水

为学日益,为道日损。

BlogJava 首页 新随笔 联系 聚合 管理
  296 Posts :: 10 Stories :: 274 Comments :: 0 Trackbacks
 

在虚拟主机的环境下,因为没有管理员权限,只有数据库使用权限,定时备份SQL数据是

个比较麻烦的问题。解决思路如下:(仅对SQL2000有效)
1. 利用T-SQL备份数据库到指定目录,文件名根据日期指定。
2. 利用Resin的定时功能,定时执行备份。
3. 用户定时下载备份并且删除过期备份。

导出全部数据到Excel也比较实用。下面提供的方法可以导出库中的全部表,也可以指定

几个表导出。注意:
1. 因为是导出全部数据,在数据比较多的情况下慎用。
2. 理论上应该适用各种JDBC数据库,仅对SQL2000测试过
3. 对于B/S下载,建议不要在服务器上生成文件,以免造成垃圾文件。直接从HTTP的Response中取得OutputStream进行输出。
4. Excel操作的API请到这里下载: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: 数据库备份</p>
 * <p>Description: 在Java中备份数据库</p>
 * @author steeven
 * @version 1.0
 */
public class DBackup{
    Context ctx ;
    public DBackup(Context ctx) {
        this.ctx = ctx;
    }
    /**
     * 备份SQL2000数据库到文件,整个数据库备份
     * 文件名后面将追加备份年月日。例如:c:\dbBackup\mydb031109
     * @param file 导出的文件名全路径。例如:"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);
    }
    /**
     * 导出整个数据库到Excel
     * @param conn 数据库连接
     * @param out 输出Stream
     */
    public static void db2Excel(Connection conn,OutputStream out)throws

Exception{
        db2Excel(conn,out,getTables(conn));
    }
    /**
     * 导出数据库中指定的表名到Excel
     * @param conn 数据库连接
     * @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();
    }
    /**
     * 导出表数据到Excel的sheet
     */
    public static void writeSheet(
        WritableSheet sheet,String table,Connection conn)
        throws Exception
    {
        //取得所有表数据
        String sql = "select * from "+DB.ESC1+table+DB.ESC2;
        ResultSet rs = conn.createStatement().executeQuery(sql);
        //根据ResultSet的MetaData取得表头,列数,列宽
        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++){
            //导出表头
            sheet.addCell(new Label(i, row, meta.getColumnLabel(i + 1),fmt));
            //设定列宽
//            sheet.setColumnView(i,meta.getColumnDisplaySize(i+1));
        }
        row++;
        while(rs.next()){
            for (int i = 0; i < n; i++){
                //根据列的类型决定Excel中对应的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取得所有数据表的名称
     */
    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();
    }
}

------------------------------------
关于虚拟主机的数据库如何备份
1.最早的时候用sqlserver的备份功能,在本地可以实现,用程序调用就可以了。后来发不到虚拟机的时候才发现,虚拟机把大部分的存储过程都给关闭了。只好考虑用别的方法。
2.后来,我就用自己写的存储过程来备份数据库,当时是虚拟主机和数据库在同一台机器上,ok没有问题了。
3.现在由于速度问题,虚拟主机必须移到香港,所以第二种方法就没法子实现了。
想来想去,嘿嘿,利用本地的sqlserver。
新建一个包,然后点“复制sqlserver 对象任务”,然后输入源/目的/复制的信息。一般如果是数据量比较少的话,我们可以用替换现有数据,也是最正常的情况,我觉得这个比较可行,如果是追加的话,就会丢失修改的信息。然后,虚拟主机的sqlserver一般需要用户名密码,那么我们就在自己本地的sqlserver的安全里面也增加相同用户名及密码。这样我们执行的时候就不会出问题了。
然后我们保存这个包,确信sqlagent服务已经启动。如果启动了,那么我们在数据转换服务-本地包,然后右击我们刚才创建的包,选择调度。设定一个时间段,我一般选择12点,那时候大家都去吃饭了~~
posted on 2008-07-02 16:12 放水老倌 阅读(690) 评论(0)  编辑  收藏 所属分类: 数据库

只有注册用户登录后才能发表评论。


网站导航:
博客园   IT新闻   Chat2DB   C++博客   博问