我想编写一个SpringBatch Tasklet,它可以自动激活或取消激活给定数据库表的所有索引。代码需要独立于DBMS(需要SQL Server,Oracle和HSQLDB)。
这是我到目前为止所尝试的:
DatabaseMetaData dbMetaData = connection.getMetaData();
ResultSet rs = dbMetaData.getIndexInfo(null, null, tableName, true, false);
while (rs.next()) {
// work with ResultSet
}
但是,我没有得到索引的名称或任何有用的信息。
那么有人可以提供一些关于如何使用JDBC连接对象将表的所有索引设置为活动或非活动的提示吗?
答案 0 :(得分:4)
您必须区分主键(使用DatabaseMetaData.getPrimaryKeys()
检索)和其他索引(通过dbMetaData.getIndexInfo(null, null, tableName, true, false)
)。
在你的循环中使用:
rs.getString("INDEX_NAME")
提取索引名称rs.getBoolean("NON_UNIQUE")
提取唯一信息rs.getShort("TYPE")
提取索引类型rs.getInt("ORDINAL_POSITION")
提取序号位置使用ORDINAL_POSITION
作为键断点(当前值为< =前一个值时)以检测索引更改。
阅读official DatabaseMetaData.getIndexInfo() doc
答案 1 :(得分:0)
获取所有索引的另一种方法是使用information_schema statistics表:
public void GetIndexesOfThisTable(final String tableName) {
try {
PreparedStatement ps = conn.prepareStatement("SELECT DISTINCT INDEX_NAME FROM information_schema.statistics WHERE table_name = ?");
ps.setString(1, tableName);
ResultSet rs = ps.executeQuery();
while(rs.next()){
System.out.println(rs.getString(1));
}
rs.close();
ps.close();//important to close to prevent resource leaks
}
catch (Exception ex) {System.out.println(ex.getMessage());}
}
答案 2 :(得分:0)
下面的代码用于从数据库中检索INDEX_NAME。
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) throws Exception {
Connection conn = getOracleConnection(); //Based on the database corresponding method should be called
List<String> schemaList=new ArrayList<String>();
List<String> catalogList=new ArrayList<String>();
List<String> indexs=new ArrayList<String>();
String dbIndexName=null;
ResultSet rs=null;
System.out.println("Got Connection.");
try {
DatabaseMetaData metaData = conn.getMetaData();
ResultSet schemas = metaData.getSchemas();
ResultSet catalog = metaData.getCatalogs();
while (schemas.next()) {
String tableSchema = schemas.getString(1);
schemaList.add(tableSchema);
}
while (catalog.next()) {
String allCatalog = catalog.getString(1);
catalogList.add(allCatalog);
}
for(int i=0;i<schemaList.size();i++){
try{
if(schemaList.get(i)!=null){
ResultSet indexValues = metaData.getIndexInfo(null, schemaList.get(i),tablename, true, false);
while (indexValues.next()) {
dbIndexName = indexValues.getString("INDEX_NAME");
if(dbIndexName!=null){
indexs.add(dbIndexName);
}
}
System.out.println("CORRESPONDING TABLE SCHEMA IS : "+schemaList.get(i));
System.out.println("INDEX_NAMES IS ::: "+indexs);
}
}catch(Exception e){
}
}
} finally {
if (conn != null) {
conn.close();
}
}
}
public static Connection getOracleConnection() throws Exception {
String driver = "oracle.jdbc.OracleDriver";
String url = "jdbc:oracle:thin:@localhost:1521:oracledb";
String username = "oop";
String password = "oop";
Class.forName(driver); // load Oracle driver
Connection conn = DriverManager.getConnection(url, username, password);
return conn;
}
private static Connection getDB2Connection() throws Exception {
Class.forName("org.hsqldb.jdbcDriver");
System.out.println("Driver Loaded.");
String url = "jdbc:hsqldb:data/tutorial";
return DriverManager.getConnection(url, "sa", "");
}
public static Connection getMySqlConnection() throws Exception {
String driver = "org.gjt.mm.mysql.Driver";
String url = "jdbc:mysql://localhost/demo2s";
String username = "oost";
String password = "oost";
Class.forName(driver);
Connection conn = DriverManager.getConnection(url, username, password);
return conn;
}
}
答案 3 :(得分:0)
我有一个类似的问题,我的原因是区分大小写。我必须用小写字母写整个表名(就像它出现在SQL“ SELECT tablename,indexname,indexdef FROM pg_indexes”的结果集中一样。
我还将倒数第二个参数(“唯一”参数)更改为false,以获取所有索引(否则,我仅获得了主键)。
希望这会有所帮助。