博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
DatabaseMetadata.getTables()方法 问题记录
阅读量:5321 次
发布时间:2019-06-14

本文共 2407 字,大约阅读时间需要 8 分钟。

之前写了一个程序,负责从一个集群中同步Hive数据到另一个集群中,代码中有这么一步,指定好表格后,会首先判断表格是否存在,不存在则创建,已经存在则提示是否覆盖。

在我最初编写程序的时候,两个集群中的表格基本上都是一致的,所以当初没有出什么问题。但是最近组长说这个程序干脆整合到平台里好了,所以找了一个前辈来帮我测试。

前辈不愧是前辈,噼里啪啦没多久就找出一堆小问题(主要因为最初是给自己写的,没有考虑那么多),其中一个问题就是就是在他删除了某张表之后,再次同步这张表的数据时,程序提示表已经存在,但是最终修复表格信息时确保了错,提示表格不存在。

我很容易就想到应该是表格判断那里出了问题。判断表格是否存在我使用的是DatabaseMetadata类下的getTables(),这个方法有四个参数,可以根据指定的参数从元数据中获取表格信息,理论上是不会出错的,毕竟是元数据,而且删除表格使用的Hue,删除没出任何问题,理论上元数据中的数据也应该删掉的:

   

 

我针对那张表进行测试,发现返回的真的是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"(可能为空)

 

  

我在想,方法中匹配到的真的是那张表的信息吗?于是我编写了以下方法,输出所查询到的表的信息:

   

 

输出如下(A为我所查询的表名):

 

 

查询到的的确是这张表,但是这张表所在的库却是"test",我赶紧去test库中看了一下,发现里面真的存在一张A表,我这才想起来,这不是我当初写程序的时候创建的测试表吗?!!

闹了半天是被以前的自己坑了,但是这个问题也是很有价值的。

在输出中可以看到,第一列代表参数catalog,第二列代表参数schemaPattern,第三列代表参数tableNamePattern,第四列代表参数types

所以参数schemaPattern应该指定为数据库,这样就能利用到我最初传入的参数database了。

将方法修改为:

   

接着进行测试,发现果然返回了false!最终,在困扰了我两个多小时后,这个问题终于得以解决。

 

以上就是我在使用DatabaseMetadata.getTables()方法时遇到的一个小问题,希望能够给予大家帮助。

 

转载于:https://www.cnblogs.com/BlackString/p/11139186.html

你可能感兴趣的文章
企业级PHP开发框架Symfony 2
查看>>
微信小程序wx.request请求用POST后台得不到传递数据
查看>>
2016。2017...
查看>>
jquery 第四章
查看>>
基于时间系统的状态机
查看>>
windows下boost编译(vs2010)
查看>>
计划排程和管控体系的先决条件
查看>>
poj 3250 栈应用
查看>>
小数组的读写和带Buffer的读写哪个快
查看>>
自定义view实现画个闪烁的心
查看>>
linux的子进程调用exec( )系列函数
查看>>
TFS Instructions
查看>>
MSChart的研究
查看>>
[LeetCode] Intersection of Two Arrays II 两个数组相交之二
查看>>
C# 服务的安装、卸载、启动、停止操作
查看>>
C# 索引器
查看>>
MySQLdb & pymsql
查看>>
zju 2744 回文字符 hdu 1544
查看>>
XmlDocument
查看>>
delphi 内嵌汇编例子
查看>>