在正常生产操作期间更改数据库同义词的策略

时间:2013-05-09 12:11:17

标签: sql oracle oracle10g scheduler

目前我的方案涉及在完成预定作业后切换同义词定义。该作业将创建一个标识为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是否有任何依赖对象?

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

  

这听起来真的很奇怪。你能解释一下吗?   那个开关用于/如何使用?

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

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

2 个答案:

答案 0 :(得分: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中的列是相同的。

分享并享受。

答案 1 :(得分: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;

De Morgan的法律因简洁而被省略。

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

a)Tokenize枚举的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);
 }