1

目前,我有一个场景涉及在计划作业完成后切换同义词定义。该作业将创建一个标识符为evenodd对应于偶数或奇数小时的表。我们目前正在做的是这样的:

odd_job:  

create foo_odd ...  
replace foo_syn as foo_odd

even_job:  

create foo_even ...  
replace foo_syn as foo_even

发生的事情是在正常生产期间foo_syn处于锁定状态。因此,我们正在寻找一种能够交换同义词定义的生产方式。

问题是我们如何在 Oracle 10g 中以最少的用户中断来交换生产级系统中的同义词定义?

从评论中

foo_syn 是否有任何依赖对象?

Nofoo_syn只不过是指向我生成的表的指针。也就是说,不需要为此开关重新编译任何程序。

这听起来像是一件很奇怪的事情。你能解释一下那个开关的用途/它是如何使用的吗?

当然。我们有一个与数据库接口的应用程序,从 Java(业务逻辑查询)执行的 SQL 具有对foo_syn. 由于数据的动态特性,可以保证每小时交换将提供新的结果,这对于我们试图接近实时是很重要的。在此之前,它是每天一次,并且对它类型的场景感到满意。

交换的原因是我不希望动态 SQL(就表名而言)成为我的应用程序查询的一部分。因此,数据库在不更改作为我的应用程序的一部分引用的同义词的名称的情况下对较新的数据集进行切换。

4

2 回答 2

3

如果您不喜欢使用动态 SQL(并且我会很快指出,根据我的经验,动态 SQL 从未被证明是性能问题,但是 YMMV)那么 UNION 查询可能就是您正在寻找的 - 类似于

SELECT *
  FROM EVEN_DATA_TABLE
  WHERE TO_NUMBER(TO_CHAR(SYSDATE, 'HH')) IN (0, 2, 4, 6, 8, 10, 12)
UNION ALL
SELECT *
  FROM ODD_DATA_TABLE
  WHERE TO_NUMBER(TO_CHAR(SYSDATE, 'HH')) IN (1, 3, 5, 7, 9, 11)

这也消除了定期作业来更改同义词的需要,因为它已脱离 SYSDATE。

这假设 EVEN_DATA_TABLE 和 ODD_DATA_TABLE 中的列是相同的。

分享和享受。

于 2013-05-09T13:13:07.140 回答
0

我们提出的解决方案如下:

1) 定义一个函数,该函数将返回您应该查看的表集:

  create or replace function which_synonym return varchar2 as  
  to_return varchar2(4) := NULL;  
  is_valid number :=- 1;  
  current_time number := to_number(to_char(sysdate,'HH'));    
  is_odd boolean := FALSE;  

BEGIN   
   if = mod(current_time,2)    -- it is an even time slot
   then    
      select success into is_valid  
      from success_table  
      where run='EVEN';    
   else    
      select success into is_valid  
      from success_table  
      where run='ODD';  
   end if;  
   if is_valid=0 and is_odd=TRUE  
   then to_Return ='ODD';  
   else  
     to_return='EVEN';    
   end if;  
   Return to_return;   
END which_synonym;

为简洁起见,省略了德摩根定律。

2) 配置应用程序以利用此翻转:

a) 使用要匹配的序列标记枚举的 sql 字符串:

select * from foo_&&&

b) 编写将替换此序列的函数:

 public String whichSynonym(String sql)  
 {  
   if(null==sql || "".equals(sql.trim()))  
   {  
        throw new IllegalArgumentException("Cannot process null or empty sql");
   }    
   String oddEven = "";
     //removed boilerplate  
     PreparedStatement statement = conn.prepareStatement("Select which_synonym from dual");  
     statement.execute();  
     ResultSet results = statement.getResults();  
     while(results.next())  
     {
          oddEven=results.getString(1);  
     }    
     return sql.replace("&&&",oddEven);
 }  
于 2013-05-10T16:25:38.037 回答