使用 oracle jdbc 连接时如何获取数据库模式名称?
Posted
技术标签:
【中文标题】使用 oracle jdbc 连接时如何获取数据库模式名称?【英文标题】:How to get database schema name when using oracle jdbc connection? 【发布时间】:2012-11-12 09:37:39 【问题描述】:我正在尝试使用 DatabaseMetaData.getTables() 方法获取所有数据库表。但是这种方法需要数据库模式名称模式。是否可以获取当前数据库连接的架构名称?
【问题讨论】:
【参考方案1】:当前连接的标准架构是您用于登录的用户名。因此,如果您的用户是SCOTT
,则必须使用SCOTT
来表示DatabaseMetaData.getTables()
。
您可以通过DatabaseMetaData.getUserName()
获取用户名。
但请记住,在 JDBC 驱动程序中比较模式/用户名是区分大小写的,并且通常用户名是大写的。
我不能 100% 确定 DatabaseMetaData.getUserName()
是否会在所有情况下以正确的大小写返回名称。可以肯定的是,您可能希望在使用该值之前执行一个 upperCase()。
【讨论】:
你是对的。我正在寻找的带有模式 id 名称的字符串是大写的用户名字符串。 既然schema/username是区分大小写的,为什么Oracle把用户名存储为大写?? @CKLee:因为 SQL 标准要求标识符被折叠成大写,这就是为什么非引号标识符在 Oracle 中以大写形式存储。在这种情况下,区分大小写的原因是后台的 JDBC 驱动程序执行类似where owner = ?
的操作,并且 that 比较区分大小写(与所有其他字符串比较一样)。作为 标识符 一部分的用户名不区分大小写。 select * from SCOTT.foobar
与 select * from scott.FOObar
相同
我现在正在为不同的数据库开发 DDL 层。 Oracle 的行为使我无法概括我的实现。无论如何要强制 Oracle 将用户名与原始案例一起存储?
@CKLee:没有单一的解决方案:一些 DBMS 以大写形式存储它,一些以小写形式存储,一些以混合大小写形式存储。比较字符串时,有些区分大小写,有些不区分,有些有时区分。有些总是独立于操作系统和安装选项工作,因为有些这种行为取决于配置或操作系统。【参考方案2】:
尝试使用 getCatalogs()。这是一个速写
public List<String> getDatabases(DBEnv dbEnv)
Connection conn = getConnection(dbEnv);
List<String> resultSet = new ArrayList<String>();
try
DatabaseMetaData metaData = conn.getMetaData();
ResultSet res = metaData.getCatalogs();
while (res.next())
resultSet.add(res.getString("TABLE_CAT"));
catch (SQLException e)
logger.error(e.toString());
return resultSet;
【讨论】:
不知道为什么但是结果集是空的。 @ThaiTran 你知道为什么该方法被称为 getCatalogs 而不是 getSchemas 吗? @johnny-b-goode - 如果您同时发现原因:) - 是数据库以不同的方式解释该方法吗?我的意思是,它适用于 mysql,但在 Oracle 或其他类型的数据库上它可能会返回其他类型的对象(我在阅读 ***.com/questions/7942520/… 时遇到了这个提示)【参考方案3】:从 Java 7 开始,Connection
有一个 getSchema
方法:https://docs.oracle.com/javase/8/docs/api/java/sql/Connection.html#getSchema--
【讨论】:
很好的调用但是...至少在 MySQL (v5.7.x) [Connection].getSchema() 上返回 null - 即使模式是在连接字符串上定义的。 MySQL 将其解释为数据库实例 ID 的方式略有不同,并且显然没有将其转换为 JDBC 的适当数据模型(目录/模式/object)。 OP 问题与 Oracle 特别相关,但考虑到 JDBC 应该是抽象的……人们会认为“getSchema()”会返回模式,而“getUserName()”等会返回与用户、数据库实例 ID 和模式的通用模型相关联的预期数据,但是……唉,这显然与 Oracle 和 MySQL 不一致。【参考方案4】:不幸的是,答案是没有一致的解决方案。如果 John 有权访问 Sally.Table ... 查询将起作用,但 getUserName() 将返回 John 而不是 Sally 模式。对于 Oracle,用户拥有他们的架构,而其他人可能有权访问,该用户 ID 是该连接上的 默认 架构。
此外,getSchemaName() 和 getCatalog() 都不会返回架构名称。
@horse_with_no_name 对 Oracle 有最接近的答案,因为给定的用户名是(默认)模式名称,除非在对象引用中被覆盖,如图所示。
对于其他数据库,相同的规则并不一致。
【讨论】:
【参考方案5】:您可以使用
获取架构名称Connection conn =
DriverManager.getConnection("jdbc:oracle:thin:@server:port:SID",prop);
DatabaseMetaData databaseMetaData = conn.getMetaData();
System.out.println("schema name >>>> "+databaseMetaData.getUserName());
【讨论】:
以上是关于使用 oracle jdbc 连接时如何获取数据库模式名称?的主要内容,如果未能解决你的问题,请参考以下文章