2012-01-17 119 views
1

我在oracle中有一个表,其中的数据从某个第三方插入。我想从该表填充主表。那么,什么是使用集合的最佳性能表现方式。Oracle中的条件插入或更新

E.g.假设数据将从第三方填充到的表是'EMP_TMP'。

现在我想通过将从EMP_TMP表填充的过程填充'EMPLOYEE'主表。

这里又有一个条件,如IF SAME EMPID(这不是主键)EXISTS那么我们必须更新FULL TABLE,它包含相同的EMPID ELSE我们有INSERT NEW RECORD。

[注:这里EMPID是VARCHAR2和EMPNO将是主键,我们将使用SEQUENCE]

我觉得这里合并将不会执行好得多performancewise,因为我们不能在MERGE语句中使用集合。

+2

你需要解释为什么合并是行不通的好一点。它专为这种upsert风格的场景设计。另一种方法是回到旧学校预先合并,这是2条语句,更新的内部连接和插入的左侧反连接。 – Andrew 2012-01-17 16:13:32

+0

我知道合并会起作用。如果它的性能比BULK COLLECT更好,对我来说可以。这里的数据也将以十万卢比为单位。 – user1017936 2012-01-17 16:16:02

+0

@ user1017936 - 与编写模拟相同操作的循环代码相比,单个SQL语句(无论是“INSERT”,“UPDATE”,“DELETE”还是“MERGE”)效率更高。使用'BULK COLLECT'可以使循环代码更高效,但不会比SQL更高效。 – 2012-01-17 16:24:31

回答

0

好吧,如果性能是你的首要考虑,而你不喜欢MERGE,那么这个怎么样(如运行脚本,单笔交易):

delete from EMPLOYEE where emp_id IN (
select emp_id from EMP_TMP); 

insert into EMPLOYEE 
select * from EMP_TMP; 

commit; 

显然不是“最安全”的方法(和正如书面假设完全相同的表定义,你有回滚),但应该很快(你也可以混淆IN与EXISTS等)。如果emp_id或emp_no是这两个表中的常见关键字,但我无法完全理解您的帖子,但在您的情况下使用哪个更合理。

+0

我不能使用删除,因为在这里emp_id是序列生成的主键,它以后也会有子记录。对于参考empid将像1,2和emp_no将VARCHAR2像'ABC','DEF' – user1017936 2012-01-17 16:45:26

+1

@ user1017936 - 你在这个评论中说的是*与你在你的问题中说的完全相反。请记住你的想法。无论如何,无论这个活动密钥是什么,只要你有一个。在目标表中删除某个键与源表中的键匹配的记录,然后将临时记录插入到目标表中与执行“UPDATE FULL TABLE”相同 – APC 2012-01-17 18:23:23

0

创建一个程序,你需要使用PL/SQL。 先执行更新,然后测试sql%rowcount。 如果它是0,那么没有更新完成,你必须做一个插入。

我认为这是相当有效的。

伪代码

Update table; 
if sql%rowcount = 0 then 
    //get new sequence number 
    insert into table; 
END IF; 
COMMIT; 

HTH
HARV

+0

感谢所有人提供的解决方案。你们能否澄清最后一件事?现在,哪个更新将运行得更快。无论是通过MERGE还是使用PSEUDOCODE? – user1017936 2012-01-17 19:49:12

+0

我很确定MERGE会跑得更快,但我无法确切地说出这一点。 – Harv 2012-01-17 20:39:35

+0

这需要多长时间运行一次?每次运行多少条记录? – Harv 2012-01-17 20:41:12