自动删除所有表,有外键约束的表优先删除

      在数据迁移的过程中,可能涉及到要清除数据库中表数据,大家在做删除操作的过程中经常遇到,想要删除的表往往有很多外键相关联的表,必须将这些有关联的表的数据清空掉以后,才能将需要删除的表数据清空。

      如:delete from testXX;报错外键约束 ‘FK_XX_XX’ 这样需要查询是那张表,select * from user_constraints t where lower(t.constraint_name) like 'fk_xx_xx%' 往往这个过程有些复杂,执行删除语句,发现是哪个外键引用,然后找到表,然后清除这个引用表的数据,然后继续以上步骤。。。

      基于此类繁琐的操作,要删除的表少了还可以手动测试,最后整理需要顺序删除的语句,但是如果表很多,这个过程就相当繁琐了,所以决定写一个测试类,来解决这个问题,让程序自动运行,自动删除表,遇到有外键约束的表优先删除后,再进行删除需要删除的表。

 

代码如下:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.UnavailableException;

/**
 * @author Bicashy
 */
public class TableOperate {
	static Statement stmt = null;
	static Connection conn = null;
	static Map map = new HashMap();          //用来保存已经删除了的表的集合
	static Map filterMap = new HashMap();    //用来保存需要过滤的表的集合
	
	static String schema ;
	/**
	 * 获得数据库链接
	 * @return
	 */
	private static Connection getConnection(){
		try {
			Class.forName( "oracle.jdbc.driver.OracleDriver").newInstance(); 
			//String   url= "jdbc:oracle:thin:@10.45.10.177:1521:highway"; 
			String   url= "jdbc:oracle:thin:@127.0.0.1:1521:highway";
			String   user= "sa"; 
			String   password= "123456"; 
			schema = user;
			conn =   DriverManager.getConnection(url,user,password);
			return conn;
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
		return null;
	}
	
	/**
	 * 获得该用户的所有表,并删除表(除了要过滤的表)
	 */
	private static void findDeleteTableSQL(){
		if(conn!=null){
			try {
				stmt=conn.createStatement(); 
				String sql = "select * from user_tables";
				//找到该链接用户的所有表
 				ResultSet rs=stmt.executeQuery(sql); 
				while(rs.next()){
					String tabName = rs.getString("table_name");
					//如果map中包含了表名,说明已经删除过了
					//如果filterMap中包含了表名,则不删除
					if(!map.containsKey(tabName)&&!filterMap.containsKey(tabName)){
						printDeleteTableSQL(tabName);
					}
				}
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	
	
	/**
	 * 
	 * 删除表,并将删除表的语句输出到控制台(记录后方便在数据库客户端执行)
	 * @param l
	 * @param tableName
	 * @return
	 */
	private static void printDeleteTableSQL(String tableName){
		String sql = "DELETE FROM "+tableName.toUpperCase();
		try {
			    stmt=conn.createStatement(); 
				stmt.execute(sql);
				stmt.close();
				System.out.println(sql+";");       //将删除语句输出到控制台
				map.put(tableName,null);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			String error = e.toString(); 
			String errorStart = "java.sql.SQLException: ORA-02292: 违反完整约束条件 ("+schema.toUpperCase()+".";
			int start = errorStart.length();
			int end = error.length()-") - 已找到子记录 ".length();
			//截取错误信息得到外键约束名称
			String fk_constraints = error.substring(start,end);
			deleteTableNameFromFK(fk_constraints);
			//删除外键约束表后,就可以将本表删掉
			printDeleteTableSQL(tableName);
			
		}
	}
	
	/**
	 * 删除通过外键约束找到的有子记录的表
	 * @param fk_constraints
	 */
	private static void deleteTableNameFromFK(String fk_constraints){
		String sql = "select table_name from user_constraints  where constraint_name='"+fk_constraints+"'";
		try {
			ResultSet  rs=stmt.executeQuery(sql); 
			while(rs.next()){
				String tabN = rs.getString("table_name");
				printDeleteTableSQL(tabN);//递归
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	/**
	 * 初始化需要过滤表的集合(该表如果是别的表的外键关联表也有可能被删除)
	 */
	private static void initFilterMap(){
		String[] tables = {"ETC_USER","etc_dic_data","MENU"};
		for (int j = 0; j < tables.length; j++) {
			filterMap.put(tables[j].toUpperCase(),null);
		}
	}
	
	public static void main(String[] args) {
		getConnection();
		//initFilterMap();//初始化不需要删除的表
		
		//删除该用户下所有表(除了需要过滤的),并获得删除语句
		//findDeleteTableSQL();
		
		//删除某一个表(有外键约束的表将先删除),并获得删除语句
		printDeleteTableSQL("obu_mast");
	} 
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值