2013-04-15 73 views
1

我正在编写一个Oracle存储过程,它将刷新一个包含非规格化数据的表。该过程的要点是:Oracle原子存储过程

CREATE OR REPLACE PROCEDURE loadDenormalizedTable IS 
BEGIN 

DELETE FROM denormalizedTable; 

INSERT INTO 
    denormalizedTable 
    (
     data 
    ) 
SELECT DISTINCT 
    data 
FROM 
    normalizedTables; 

END; 
/

我想所有这一切都在交易发生,这样总会有表中的数据。现在删除运行并且表格在几分钟内是空的,直到插入完成。什么是处理这种类型的表刷新没有任何停机时间的最佳方式?

+1

的删除不会对其他会话可见。所以你会看到空桌子,但没有人会。这是你真实程序的一个明显缩减版吗?此外...你重塑[物化视图(http://docs.oracle.com/cd/E11882_01/server.112/e25789/schemaob.htm#CFAIGHFC)? –

+0

谢谢!会议问题让我感到沮丧。我现在看到,在刷新表格时,应用程序仍然可以看到数据。这是削减的,我删除了所有的实际表和列,只是放在占位符。虽然结构相同。是的,这是重塑物化视图,数据架构师并不是MV的粉丝。 – wshato

+0

什么是席位视图错误?它可以以原子方式或非原子方式刷新。而且一旦创建,所有这些工作都可以简化为单个刷新语句。我不会说我对你的数据有什么看法“建筑师” – tbone

回答

1

默认情况下,过程将作为会话拥有的较大事务的一部分执行。由于documentation提到:

注:事务可以跨越多个块,块可以包含多个事务。

利用如上描述你的代码,没有其他的会议将看到您删除插入,直到你调用该过程后提交。如果你只是从SQL *执行它加提示,例如:

SQL> exec loadDenormalizedTable; 

PL/SQL procedure successfully completed. 

SQL> 

...然后别人看着表仍然会看到旧的数据,即使同时删除和插入后已经完成。 (其他任何人试图执行该过程,或插入或删除denormalizedTable中的数据,都会阻止,但可能你只希望其他人查询它)。一旦你发出commit,那么每个人都会看到同样的事情。

让你形容是在过程中手动结束交易行为的唯一方法:

CREATE OR REPLACE PROCEDURE loadDenormalizedTable IS 
BEGIN 

DELETE FROM denormalizedTable; 

COMMIT WORK; -- makes the delete visible elsewhere 

INSERT INTO 
    denormalizedTable 
    (
     data 
    ) 
SELECT DISTINCT 
    data 
FROM 
    normalizedTables;  
END; 
/

你不不需要commit在程序的中间,这是非常罕见的,你将会或应该永远想要这样做,因为它打破了原子性。

这是可能的,你正在做的事情,做一个隐含的承诺,而你意识到这一点;也许调用另一个执行它自己的提交的过程或函数(这样做的原因之一 - 它可能会有意想不到的副作用!),或者DDL语句 - 它总是会在后台执行隐式提交,但是你无论如何,动态SQL必须这样做。其他

一种可能性是,你实际上并没有做delete,但是,你正在做一个truncate。如果没有明确的提交,那么其他人立即就会看到这一点,暗示为in the documentation。这也将与您提供的大纲背道而驰。直到你提交时,你不应该在过程中做

+0

我仍然习惯于在Oracle中工作的方式。它的工作方式完全如您所述。谢谢。 – wshato

1

如果Oracle分区选项可用,则最好,也是最有效的方法是使用分区交换操作。这是在许多海量数据仓库中完成的一项非常常见的操作。

看一些例子在:

http://www.akadia.com/services/ora_exchange_partition.html http://gerardnico.com/wiki/database/oracle/partition_exchange_loading

例如,你可以想像具有完全相同的结构denormalizedTable第二个表。为了实现你的负荷运转:

  • 截断denormalizedTable2
  • 将您的数据转换成denormalizeTable2
  • 交换表denormalizedTable和denormalizedTable2
  • 的分区

它通常保证上运行的应用程序影响最小。

+0

谢谢。如果DBA更喜欢截断与删除,我会记住这一点。 – wshato