Oracle 程序:从表 A 中读取,如果没有找到,则转到表 B

Posted

技术标签:

【中文标题】Oracle 程序:从表 A 中读取,如果没有找到,则转到表 B【英文标题】:Oracle Procedure: Read from Table A and if not found go to Table B 【发布时间】:2015-03-24 08:59:48 【问题描述】:

我想从 Table-A 或 Table-B 中读取数据。我的数据库是 oracle,过程必须使用最少数量的查询。要求是从一个表中读取,如果数据不可用,则转到另一个表。我写了以下程序,

CREATE OR REPLACE PROCEDURE READ(myId IN VARCHAR2, aout OUT   SYS_REFCURSOR,  bout OUT SYS_REFCURSOR )
  IS
  temp_acout_type A_TABLE%ROWTYPE;
  BEGIN
     OPEN aout FOR SELECT * FROM A_TABLE WHERE ID = myId;
     FETCH aout into temp_acout_type ;
     if aout%NOTFOUND then
        OPEN bout FOR SELECT * FROM B_TABLE WHERE ID = myId;
     end if;
 END;

我从 java 端调用这个函数。我的问题是一旦我在程序中获取游标,游标就会丢失数据。我从 Java 客户端观察到这一点,因为 ResultSetin java 端是空的(过程中的查询将只有 1 条记录,因为它是从主键搜索的),尽管它必须包含数据。

我需要一种方法来实现上述逻辑,但不使用更多查询(例如:Table-A 中提供了第一个检查数据)。有没有办法做到这一点?

【问题讨论】:

【参考方案1】:

您总是可以在 PL/SQL 存储过程中打开两个游标,然后在 Java 中,从第一个中获取数据,如果您没有从第一个中获取数据,则仅从第二个中获取数据。这将防止发生不必要的读取(打开游标不会进行任何读取;它会为您准备好获取数据的执行路径)。

或者,您可以在两个表之间进行联合并只选择第一行(其中 first 表示第一个查询中有数据)。

【讨论】:

【参考方案2】:

检查表中的行数。您可以在 12c 中使用 row-limiting 子句,例如 ROWNUMFETCH

既然您说 ID 是主键,因此它只会获取 1 行,那么只需这样做:

SELECT COUNT(*) INTO var_cnt FROM A_TABLE WHERE ID = myId;

IF var_cnt > 0
THEN 
   OPEN aout FOR SELECT * FROM A_TABLE WHERE ID = myId;
ELSE
   OPEN bout FOR SELECT * FROM B_TABLE WHERE ID = myId;
END IF;

但是,您不能确定要获取的行是否一定会出现在游标结果集中,因为同时其他一些会话可能 DELETE OPEN FOR 之前的行strong> 正在执行语句。

为了理智,我建议在 explicit cursor 查询中使用 Analytic COUNT() OVER()

【讨论】:

是否有可能只使用两个主要的选择查询以某种方式省略select count(*) 是的,使用count() over()。然后您将计算同一查询中的行数。

以上是关于Oracle 程序:从表 A 中读取,如果没有找到,则转到表 B的主要内容,如果未能解决你的问题,请参考以下文章

通过只知道没有时间的日期从表中选择 (ORACLE)

如果存在则从表中选择,否则从oracle中的另一个表中选择

windows下怎么查看oracle的安装路径

您能帮我在 Oracle 中编写一个程序来将数据从表中转存到 CSV 文件吗?

从表元数据中读取“0.-127”时,Empire db code-gen 双重解析失败

Oracle - 我想找出数据库表中的增量变化