简体   繁体   English

Oracle数据库:访问多个数据库模式

[英]Oracle Database: access multiple database schemas

I have several Oracle database schemas: eg MainSchema, and other data schemas like dataSchema1, dataSchema2, dataSchema3 我有几种Oracle数据库模式:例如MainSchema,以及其他数据模式,例如dataSchema1,dataSchema2,dataSchema3

My requirement is to execute sql statements (stored in MainSchema tables) in one of the data schemas and write results to MainSchema result tables. 我的要求是在其中一种数据模式中执行sql语句(存储在MainSchema表中),并将结果写入MainSchema结果表中。

What I can think of is: Use Java Stored Procedure, which published in MainSchema, connect to data schema (I know which schema to connect for the sql statement) and execute sql, then write results to MainSchema result tables. 我能想到的是:使用在MainSchema中发布的Java存储过程,连接到数据模式(我知道要为sql语句连接哪个模式)并执行sql,然后将结果写入MainSchema结果表。

I want to know: 我想知道:

  • This is a good approach to go? 这是个好方法吗? or any alternate is best practice? 还是其他最佳做法?

  • This is multi-threaded environment, meaning the number of connections may grow quickly. 这是多线程环境,这意味着连接数可能会快速增长。 How I handle the connection pooling? 如何处理连接池?

EDIT: Assumptions below: 编辑:下面的假设:

  1. sql statements are stored in a clob column in MainSchemas; sql语句存储在MainSchemas的clob列中;
  2. sql statements are only SELECT queries (read only) and already validated; sql语句仅是SELECT查询(只读),并且已经过验证;
  3. sql statements do not require any connection information (meaning written locally) sql语句不需要任何连接信息(意味着在本地编写)
  4. "schema" can be different database so prefixing schema name is not an option; “模式”可以是不同的数据库,因此不能为模式名称加上前缀;

So I think it's hard to do with procedures/functions. 因此,我认为很难使用过程/功能。 Using Java implementation to access different databases may be a good choice? 使用Java实现访问不同的数据库可能是一个不错的选择?

Experts here please give some advice on how to design this? 这里的专家请就如何设计提出一些建议?

I am not quite sure what you mean by sql statements (stored in MainSchema tables) . 我不太确定sql语句(存储在MainSchema表中)的含义 If you really mean tables with a string column holding SQL text, then this is really an odd thing to do. 如果您的意思是带有包含SQL文本的字符串列的表,那么这确实是一件奇怪的事情。

A somewhat better approach is to create a bunch of stored procedures, which return a cursor. 更好的方法是创建一堆存储过程,这些存储过程返回游标。 You would then call one of these procedures and fetch from the cursor and write back to to MainSchema's result tables. 然后,您将调用以下过程之一,并从游标中获取并写回到MainSchema的结果表。 The benefit of this approach is that the SQL is checked during compilation, while SQL in Strings (no matter where you store them) is an error prone thing. 这种方法的好处是在编译过程中会检查SQL,而字符串中的SQL(无论将它们存储在哪里)都是容易出错的事情。

Operating on two schemas is actually easy: you need to prefix your tables (and other object) with the schama name. 实际上,在两种模式下进行操作很容易:您需要在表(和其他对象)上添加schama名称作为前缀。 You can do things like 你可以做类似的事情

insert into mainSchema.resultTable (
select ... from dataSchema1.dataTable1
where ...
)

If you can write things like this, then .. well .. you just run it. 如果您可以编写这样的内容,那么..好吧..您只需运行它。 You can also do this from Java if you must. 您也可以根据需要从Java中执行此操作。

If however, the schema name is a variable , ie your SQL is not specific to a schema, but you decide which dataSchema to use at runtime, then this doesn't work. 但是,如果模式名称是一个变量 ,即您的SQL不是特定于模式的,但是您决定在运行时使用哪个dataSchema,则此方法将不起作用。 Then again having multiple schemas holding similar data is almost always a bad idea. 然后,拥有多个拥有相似数据的模式几乎总是一个坏主意。 You need to partition by meaning, not by physical things like origin or time-period. 您需要按含义进行分区,而不是按诸如起源或时间周期之类的物理事物进行分区。 A good solution here is to use partitioned tables. 一个很好的解决方案是使用分区表。

Edit: 编辑:

If you're just worried about the number of connections, you may want to setup Oracle to use shared connections . 如果您只是担心连接数,可以将Oracle设置为使用共享连接 This however requires control over the database which you may not have. 但是,这需要控制您可能没有的数据库。

Connection pooling is a typical job of an application server. 连接池是应用程序服务器的典型工作。 But that would be quite some overhead just for running some selects and it sometimes has unexpected consequences if you're not completely stateless. 但这仅仅是运行某些选择的开销,如果您不是完全无状态的话,有时会产生意想不到的后果。

If you need to connect to different database, then database links are the standard way to go. 如果需要连接到其他数据库,则数据库链接是标准的处理方式。 Instead of prefixing objects with the schema name, you'll need to add the name of the database link as in 无需在对象之前添加架构名称,您需要添加数据库链接的名称,如下所示:

insert into mainSchema.resultTable (
select ... from dataTable1@linkName
where ...
)

If your SQL is written without any particular DB in mind, then you can of course just connect to the DB and leave the SQL as it is. 如果编写SQL时没有考虑任何特定的DB,那么您当然可以只连接到DB并保留SQL原样。 However, you will not be able to use insert-select . 但是,您将无法使用insert-select You need two DB connections, one where you execute the select and another where you execute the insert. 您需要两个数据库连接,一个用于执行选择,另一个用于执行插入。

I believe your approach will work, though I don't see the point why you store SQL in a database and not in the application code. 我相信您的方法会奏效,尽管我不明白为什么您将SQL存储在数据库中而不是应用程序代码中。 If it was in the application code you can just assemble the SQL adding @linkName where needed, you could use insert-select and you could run such an insert-select from the commandline for testing without having to do any compilations. 如果在应用程序代码中,则只需在需要的地方添加@linkName即可组装SQL,可以使用insert-select,并且可以从命令行运行这样的insert-select进行测试,而无需进行任何编译。

For me, Java Stored Procedures is a way to go. 对我来说,Java存储过程是一种方法。

http://docs.oracle.com/cd/B19306_01/java.102/b14187/chfive.htm http://docs.oracle.com/cd/B19306_01/java.102/b14187/chfive.htm

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM