在我最初编写程序的时候,两个集群中的表格基本上都是一致的,所以当初没有出什么问题。但是最近组长说这个程序干脆整合到平台里好了,所以找了一个前辈来帮我测试。
前辈不愧是前辈,噼里啪啦没多久就找出一堆小问题(主要因为最初是给自己写的,没有考虑那么多),其中一个问题就是就是在他删除了某张表之后,再次同步这张表的数据时,程序提示表已经存在,但是最终修复表格信息时确保了错,提示表格不存在。
我很容易就想到应该是表格判断那里出了问题。判断表格是否存在我使用的是DatabaseMetadata类下的getTables(),这个方法有四个参数,可以根据指定的参数从元数据中获取表格信息,理论上是不会出错的,毕竟是元数据,而且删除表格使用的Hue,删除没出任何问题,理论上元数据中的数据也应该删掉的:
public static boolean tableExist(String database, String table) throws SQLException { rs = connection.getMetaData().getTables(null, null, table ,null); return rs.next();}
我针对那张表进行测试,发现返回的真的是true。
事实上,我对这个方法并不怎么熟悉,连这个判断的方法也是从网上查到的。
所以,为了解决这个问题,我开始研究这个方法。首先看这个方法的描述:
Retrieves a description of the tables available in the given catalog.Only table descriptions matching the catalog, schema, tablename and type criteria are returned.They are ordered by TABLE_TYPE, TABLE_CAT, TABLE_SCHEM and TABLE_NAME. 检索给定目录中可用表的说明。只返回与目录、架构、表名和类型条件匹配的表说明。它们按表类型、表类别、表计划和表名称排序。
它有四个参数:String catalog,String schemaPattern,String tableNamePattern,String[] types,分别表示:
catalog 包含目录名称的 String。对此参数提供 Null 值表示无需使用目录名称。schema 包含架构名称模式的 String 值。对此参数提供 Null 值表示无需使用架构名称。tableNamePattern 包含表名称模式的 String。types 含有要包含的表类型的字符串数组。Null 表示应包含所有表类型。
最初我提供的参数是null, null, table ,null,即仅提供表名,因为当初查到的就是这样的,而且catalog和schema代表什么我也不清楚。
这种做法下在最初是没有什么问题的,但是到底为什么会导致查询出一张已经被删除的表?
我注意到了参数中的"tableNamePattern",而不是"tableName"或"table",所以是不是因为这个原因,它匹配到了其他表?
因为在Hive中我当初为了测试建立过几张副表(假设原表名为A,另外几张表是A2,A3等)。
所以我开始尝试替换掉"_",并且指定头尾(^ $ )进行精准匹配,然而反而任何表都匹配不到了。经过了数十分钟的测试,我最终认为原因应该不在这里。
getTables()方法的结果集中可能有以下列:TABLE_CAT String=>表目录(可能为空)TABLE_SCHEM String=>表架构(可能为空)TABLE_NAME String=>表名TABLE_TYPE String =>表类, 典型的类型有"TABLE","VIEW", "SYSTEM TABLE", "GLOBAL TEMPORARY","LOCAL TEMPORARY", "ALIAS", "SYNONYM"REMARKS String => 表格注释TYPE_CAT String => 目录类型(可能为空)TYPE_SCHEM String => 架构类型(可能为空)TYPE_NAME String => 类型名(可能为空)SELF_REFERENCING_COL_NAME String => 类型表的指定“标识符”列的名称(可能为空)REF_GENERATION String => 指定如何创建引用_col_name的inself_值。值为"SYSTEM", "USER", "DERIVED"(可能为空)
我在想,方法中匹配到的真的是那张表的信息吗?于是我编写了以下方法,输出所查询到的表的信息:
public static void tableData(String database, String table) throws SQLException { rs = connection.getMetaData().getTables(null, database, table ,null); while(rs.next()){ System.out.println("==>"+rs.getString(1)); System.out.println("==>"+rs.getString(2)); System.out.println("==>"+rs.getString(3)); System.out.println("==>"+rs.getString(4)); System.out.println("==>"+rs.getString(5)); }}
输出如下(A为我所查询的表名):
==> ==>test ==>A ==>TABLE ==>null
查询到的的确是这张表,但是这张表所在的库却是"test",我赶紧去test库中看了一下,发现里面真的存在一张A表,我这才想起来,这不是我当初写程序的时候创检测测试表吗?!!
闹了半天是被以前的自己坑了,但是这个问题也是很有价值的。
在输出中可以看到,第一列代表参数catalog,第二列代表参数schemaPattern,第三列代表参数tableNamePattern,第四列代表参数types。
所以参数schemaPattern应该指定为数据库,这样就能利用到我最初传入的参数database了。
将方法修改为:
public static boolean tableExist(String database, String table) throws SQLException { rs = connection.getMetaData().getTables(null, database, table ,null); return rs.next();}
接着进行测试,发现果然返回了false!最终,在困扰了我两个多小时后,这个问题终于得以解决。
小编还为您整理了以下内容,可能对您也有帮助:
请教DatabaseMetaData.getTables方法中各参数的含义,严重谢,0
getTables
ResultSet getTables(String catalog,
String schemaPattern,
String tableNamePattern,
String[] types)
throws SQLException检索可在给定类别中使用的表的描述。仅返回与类别、模式、表名称和类型标准匹配的表描述。它们根据 TABLE_TYPE、TABLE_SCHEM 和 TABLE_NAME 进行排序。
每个表描述都有以下列:
TABLE_CAT String => 表类别(可为 null)
TABLE_SCHEM String => 表模式(可为 null)
TABLE_NAME String => 表名称
TABLE_TYPE String => 表类型。典型的类型是 "TABLE"、"VIEW"、"SYSTEM TABLE"、"GLOBAL TEMPORARY"、"LOCAL TEMPORARY"、"ALIAS" 和 "SYNONYM"。
REMARKS String => 表的解释性注释
TYPE_CAT String => 类型的类别(可为 null)
TYPE_SCHEM String => 类型模式(可为 null)
TYPE_NAME String => 类型名称(可为 null)
SELF_REFERENCING_COL_NAME String => 有类型表的指定 "identifier" 列的名称(可为 null)
REF_GENERATION String => 指定在 SELF_REFERENCING_COL_NAME 中创建值的方式。这些值为 "SYSTEM"、"USER" 和 "DERIVED"。(可能为 null)
注: 有些数据库可能不返回用于所有表的信息。
参数:
catalog - 类别名称,因为存储在数据库中,所以它必须匹配类别名称。该参数为 "" 则检索没有类别的描述,为 null 则表示该类别名称不应用于缩小搜索范围
schemaPattern - 模式名称的模式,因为存储在数据库中,所以它必须匹配模式名称。该参数为 "" 则检索那些没有模式的描述,为 null 则表示该模式名称不应用于缩小搜索范围
tableNamePattern - 表名称模式,因为存储在数据库中,所以它必须匹配表名称
types - 要包括的表类型组成的列表,null 表示返回所有类型
返回:
ResultSet - 每一行都是一个表描述
抛出:
SQLException - 如果发生数据库访问错误
~~~~~~~~~~
需要匹配上面的表描述啊
菜鸟求教,jdbc程序中判断某个表是否存在的程序该怎么写?
这样:
select * from table_name where exists(select 1 from sysobjects where name ='tb' and type ='u')
exists一般是在where语句后面,表示是否存在记录,如果存在记录条数就返回true,因此用select 1 from ... 是完全可以的,用exists的最主要好处是,其可以返回多条记录。
JDBC如何获得数据库的约束信息
以MySQL5为例,看看实现过程:
首先为了描述表和列的关系,必须做个简单建模:
表对象、列对象,之间是一对多关系。
public class TableInfoBean {
private String tableName;
private String tableComment;
private List<ColumnBean> columnList=new ArrayList<ColumnBean>();
public class ColumnBean {
private String columnName;
private String columnComment;
private String SqlType;
这个关系很简单,就这么搞定了,用来保存一个表信息。
下面就是如何从数据库读取表信息了。
在这里依赖一个类DatabaseMetaData,这个对象可以从数据库连接来获取。有了它万事大吉了,想知道什么问它即可:
DatabaseMetaData databaseMetaData = conn.getMetaData();
//获取所有表
ResultSet tableSet = databaseMetaData.getTables(null, "%", "%", new String[]{"TABLE"});
//获取tableName表列信息
ResultSet columnSet = databaseMetaData.getColumns(null, "%", tableName, "%");
上面代码会得到两个结果集,对照DatabaseMetaData 的文档,我们可以通过结果集的列名来获取想要的信息,例如
String tableName = tableSet.getString("TABLE_NAME");
String tableComment = tableSet.getString("REMARKS");
String columnName = columnSet.getString("COLUMN_NAME");
String columnComment = columnSet.getString("REMARKS");
String sqlType = columnSet.getString("DATA_TYPE");
含义很清楚我就不做解释了。
逐个遍历表,然后得到一个TableInfoBean的集合,这个集合就是数据库中所有表的信息了
JDBC如何获得数据库的约束信息
以MySQL5为例,看看实现过程:
首先为了描述表和列的关系,必须做个简单建模:
表对象、列对象,之间是一对多关系。
public class TableInfoBean {
private String tableName;
private String tableComment;
private List<ColumnBean> columnList=new ArrayList<ColumnBean>();
public class ColumnBean {
private String columnName;
private String columnComment;
private String SqlType;
这个关系很简单,就这么搞定了,用来保存一个表信息。
下面就是如何从数据库读取表信息了。
在这里依赖一个类DatabaseMetaData,这个对象可以从数据库连接来获取。有了它万事大吉了,想知道什么问它即可:
DatabaseMetaData databaseMetaData = conn.getMetaData();
//获取所有表
ResultSet tableSet = databaseMetaData.getTables(null, "%", "%", new String[]{"TABLE"});
//获取tableName表列信息
ResultSet columnSet = databaseMetaData.getColumns(null, "%", tableName, "%");
上面代码会得到两个结果集,对照DatabaseMetaData 的文档,我们可以通过结果集的列名来获取想要的信息,例如
String tableName = tableSet.getString("TABLE_NAME");
String tableComment = tableSet.getString("REMARKS");
String columnName = columnSet.getString("COLUMN_NAME");
String columnComment = columnSet.getString("REMARKS");
String sqlType = columnSet.getString("DATA_TYPE");
含义很清楚我就不做解释了。
逐个遍历表,然后得到一个TableInfoBean的集合,这个集合就是数据库中所有表的信息了
请教:java从数据库获取数据导出docx,有多个表格,请问怎么导出?
第一步:如何用POI操作Excel
@Test
public void createXls() throws Exception{
//声明一个工作薄
HSSFWorkbook wb = new HSSFWorkbook();
//声明表
HSSFSheet sheet = wb.createSheet("第一个表");
//声明行
HSSFRow row = sheet.createRow(7);
//声明列
HSSFCell cel = row.createCell(3);
//写入数据
cel.setCellValue("你也好");
FileOutputStream fileOut = new FileOutputStream("d:/a/b.xls");
wb.write(fileOut);
fileOut.close();
}
第二步:导出指定数据库的所有表
分析:
1:某个数数据库有多少表,表名是什么?―――DataBaseMetadate.getMetadate().getTables(null,null,null,new String[]{Table}); - excel的文件名称。
2:对每一个表进行select * 操作。 - 每一个sheet的名称。
3:分析表结构,rs.getMetadate(); ResultSetMedated
4:多个列,列名是什么. - 字段名就是sheet的第一行信息。
5:获取每一行的数据 – 放到sheet第一行以后。
@Test
public void export() throws Exception{
//声明需要导出的数据库
String dbName = "focus";
//声明book
HSSFWorkbook book = new HSSFWorkbook();
//获取Connection,获取db的元数据
Connection con = DataSourceUtils.getConn();
//声明statemen
Statement st = con.createStatement();
//st.execute("use "+dbName);
DatabaseMetaData dmd = con.getMetaData();
//获取数据库有多少表
ResultSet rs = dmd.getTables(dbName,dbName,null,new String[]{"TABLE"});
//获取所有表名 - 就是一个sheet
List<String> tables = new ArrayList<String>();
while(rs.next()){
String tableName = rs.getString("TABLE_NAME");
tables.add(tableName);
}
for(String tableName:tables){
HSSFSheet sheet = book.createSheet(tableName);
//声明sql
String sql = "select * from "+dbName+"."+tableName;
//查询数据
rs = st.executeQuery(sql);
//根据查询的结果,分析结果集的元数据
ResultSetMetaData rsmd = rs.getMetaData();
//获取这个查询有多少行
int cols = rsmd.getColumnCount();
//获取所有列名
//创建第一行
HSSFRow row = sheet.createRow(0);
for(int i=0;i<cols;i++){
String colName = rsmd.getColumnName(i+1);
//创建一个新的列
HSSFCell cell = row.createCell(i);
//写入列名
cell.setCellValue(colName);
}
//遍历数据
int index = 1;
while(rs.next()){
row = sheet.createRow(index++);
//声明列
for(int i=0;i<cols;i++){
String val = rs.getString(i+1);
//声明列
HSSFCell cel = row.createCell(i);
//放数据
cel.setCellValue(val);
}
}
}
con.close();
book.write(new FileOutputStream("d:/a/"+dbName+".xls"));
}追问我要导出的是docx
DB2中如何查询一个数据库中有多少张表
数据库中还有大量系统表的,所以我觉得你查某些模式下的表比较好:
select count(*) from syscat.tables where tabschema='GP'
GP为某用户模式。
当然也可以用
select count(*) from syscat.tables where tabschema='GP'
查出所有表的数量。
再查出有多少张系统表,就是在SYSIBM、SYSTOOLS下的表数目。相减就可以了。
我用的是DB2 V9.7。
DB2中如何查询一个数据库中有多少张表
数据库中还有大量系统表的,所以我觉得你查某些模式下的表比较好:
select count(*) from syscat.tables where tabschema='GP'
GP为某用户模式。
当然也可以用
select count(*) from syscat.tables where tabschema='GP'
查出所有表的数量。
再查出有多少张系统表,就是在SYSIBM、SYSTOOLS下的表数目。相减就可以了。
我用的是DB2 V9.7。
java中怎么查询表单是否存在
最近在写一个程序,需要取数据库表的数据之前,需要先查看数据库是否存在该表否则就跳过该表。
二、解决方案(目前想到两种,以后遇到还会继续添加):
1、建立JDBC数据源,通过Java.sql.DatabaseMetaData接口来判断
备注:参数分析
getTables(String catalog,String schemaPattern,String tableNamePattern,String[] types)
参数: catalog:目录名称,一般都为空.
参数:schema:数据库名,对于oracle来说就用户名
参数:tablename:表名称
参数:type :表的类型(TABLE | VIEW)
注意:在使用过程中,参数名称必须使用大写的。
2、使用数据库数据字典,直接用sql语句从数据库查询
sql:select * from user_all_tables where table_name=‘tableName‘
如果结果为空则表示不存在,如何结果不为空则表示存在;
三、分析
考虑到程序运行过程的性能问题,方法一会占用连接池,从而影响程序的运行速度;因此个人建议,一般采用数据字典来判断数据库表是否存在。
Java判断数据库表是否存在的方法
标签:load 解决方案 占用 16px 不为 att sel tab pes
java中怎么查询表单是否存在
最近在写一个程序,需要取数据库表的数据之前,需要先查看数据库是否存在该表否则就跳过该表。
二、解决方案(目前想到两种,以后遇到还会继续添加):
1、建立JDBC数据源,通过Java.sql.DatabaseMetaData接口来判断
备注:参数分析
getTables(String catalog,String schemaPattern,String tableNamePattern,String[] types)
参数: catalog:目录名称,一般都为空.
参数:schema:数据库名,对于oracle来说就用户名
参数:tablename:表名称
参数:type :表的类型(TABLE | VIEW)
注意:在使用过程中,参数名称必须使用大写的。
2、使用数据库数据字典,直接用sql语句从数据库查询
sql:select * from user_all_tables where table_name=‘tableName‘
如果结果为空则表示不存在,如何结果不为空则表示存在;
三、分析
考虑到程序运行过程的性能问题,方法一会占用连接池,从而影响程序的运行速度;因此个人建议,一般采用数据字典来判断数据库表是否存在。
Java判断数据库表是否存在的方法
标签:load 解决方案 占用 16px 不为 att sel tab pes
DB2中如何查询一个数据库中有多少张表
数据库中还有大量系统表的,所以我觉得你查某些模式下的表比较好:
select count(*) from syscat.tables where tabschema='GP'
GP为某用户模式。
当然也可以用
select count(*) from syscat.tables where tabschema='GP'
查出所有表的数量。
再查出有多少张系统表,就是在SYSIBM、SYSTOOLS下的表数目。相减就可以了。
我用的是DB2 V9.7。
java 获取数据库所有表
看来LZ并没有认真看API文档啊,在接口Connection中有一个getMetaData()函数,其返回值是接口DatabaseMetaData,里面有各种数据库的配置信息,如是否支持空、最大连接数、用户可以调用的所有存储过程等,其中包括getSchemas()-获取所有模式,getTables(),获取所有的表,根据输入的不同参数可以获取所有表或者其中某个模式的表,还包括表的注射等信息,getColumns()则是获取表的具体字段,这些函数大多是以ResultSet的形式返回,和一般的JDBC使用差不多,LZ慢慢研究研究吧
java 获取数据库所有表
看来LZ并没有认真看API文档啊,在接口Connection中有一个getMetaData()函数,其返回值是接口DatabaseMetaData,里面有各种数据库的配置信息,如是否支持空、最大连接数、用户可以调用的所有存储过程等,其中包括getSchemas()-获取所有模式,getTables(),获取所有的表,根据输入的不同参数可以获取所有表或者其中某个模式的表,还包括表的注射等信息,getColumns()则是获取表的具体字段,这些函数大多是以ResultSet的形式返回,和一般的JDBC使用差不多,LZ慢慢研究研究吧
java处理数据库时遇到个小问题:
一看就知道你是个不看API的人。
虽然jdbc提供了数据库通用方法,但是不同的数据库需要设置不同的参数。
Access没人用这种数据库,我不讨论。oracle数据库与其他数据不同,它不存在catalog,所以你调用jdbc的方法的时候要注意参数。
如果是oracle数据库,要获取它的所有表,是通过模式去加载,也就是当前登录的用户名。
conn=DBUtils.getConnection();
DatabaseMetaData dbmd=conn.getMetaData();
DatabaseMetaData提供了如下方法用来获取数据库表的定义
//检索数据库中表的类型
ResultSet getTables(
String catalog,
String schemaPattern,
String tableNamePattern,
String[] types
)
throws SQLException
如果是oracle数据库,应该写成getgetTables(null,"用户名","这里不为null","TABLE");
这就是Oracle的,其他数据库应该getTables(catalog,null,null,"TABLE");
catalog是你连接的数据库名conn.getCatalog获得。
types = new String[]{"TABLE","VIEW"}这样表示视图和索引都加载。tableNamePattern可以不写,主要是控制加载什么表,可以写成一个匹配表达式,比如什么不包含tmp的,也就是不加载临时表。不看API永远学不会东西。
获取所有字段:
stmt = conn.createStatement();
rs = stmt.executeQuery("select * from " + tableName);
ResultSetMetaData meta = rs.getMetaData();
int fdcount = meta.getColumnCount();
int i = 1;
while (i <= fdcount) {
String name = meta.getColumnName(i);
String type = meta.getColumnTypeName(i).toUpperCase();
int size = meta.getColumnDisplaySize(i);
int isNull = meta.isNullable(i);
}追问我现在帮别人编一个处理Access数据库的程序啊(人家就用Access,我也很无奈),那么你懂Access,怎么实现以上效果吗?你说的看Api,是指如果我要弄Access就要看Access的API是吗?
追答自己随便写个Test测试一下不就OK了。Access哪有什么API。Java API,数据库大致相同。Access你进去看一下又没有catalog不就行了,或者看看Access怎么管理数据库的,不就知道怎么设置参数,再不行两种参数都设置不就完了。不动手,问别人你什么也学不到。这些操作都是jdbc最基本的操作了。
如何在JAVA中获取表的列名
不知道你用的是什么数据库,如果是oracle的话,可以用oracle的JDBC driver,它里面的ResultSetMetaData可以取到表名。
另外一个方法,在oracle里面有很多object,你可以写SQL进行查询,然后得到含有列名(colname)的TableName.
俺倒是想到一个土办法,根据列名来获取表名。
其实很简单,首先获取所有的表名,记录下来。有了表名,就可以知道其Meta信息了,可以获取相应的列名。然后把已知的列名在所有列名中遍历,对应的所有表名就可以得到了。
提供一段获取所有表名的代码片断,主要靠DatabaseMetaData:
DatabaseMetaData databaseMetaData = conn.getMetaData();
String[] tableType = {"TABLE"};
ResultSet resultSet = databaseMetaData.getTables(null, null, "%", tableType);
try {
while(resultSet.next()) {
String schemaName = resultSet.getString(2);
String tableName = resultSet.getString(3);
}
} finally {
resultSet.close();
}
如何在JAVA中获取表的列名
不知道你用的是什么数据库,如果是oracle的话,可以用oracle的JDBC driver,它里面的ResultSetMetaData可以取到表名。
另外一个方法,在oracle里面有很多object,你可以写SQL进行查询,然后得到含有列名(colname)的TableName.
俺倒是想到一个土办法,根据列名来获取表名。
其实很简单,首先获取所有的表名,记录下来。有了表名,就可以知道其Meta信息了,可以获取相应的列名。然后把已知的列名在所有列名中遍历,对应的所有表名就可以得到了。
提供一段获取所有表名的代码片断,主要靠DatabaseMetaData:
DatabaseMetaData databaseMetaData = conn.getMetaData();
String[] tableType = {"TABLE"};
ResultSet resultSet = databaseMetaData.getTables(null, null, "%", tableType);
try {
while(resultSet.next()) {
String schemaName = resultSet.getString(2);
String tableName = resultSet.getString(3);
}
} finally {
resultSet.close();
}