2009-09-29 61 views
2

我运行像这样的查询:在Oracle中插入rowid后可以立即失效吗?

INSERT INTO foo (...) VALUES (...) RETURNING ROWID INTO :bind_var 

SELECT ... FROM foo WHERE ROWID = :bind_var 

本质上讲,我插入一行,并获取其ROWID,然后做一个选择针对ROWID获取数据从记录回来。虽然偶尔,ROWID将不会被发现。

忽略这样一个事实,即可能有更好的方法来做我想做的事情,假设没有其他人使用数据库,ROWID可以快速更改吗?

UPDATE有涉及的触发器。这里的DDL语句吧:

CREATE OR REPLACE TRIGGER "LOG_ELIG_DEMOGRAPHICS_TRG" 
before insert on log_elig_demographics 
for each row 
begin 
select log_elig_demographics_seq.nextval into :new.log_idn from dual; 
end; 

从本质上讲,它只是设置为帮助我们模拟一个IDENTITY /自动增量字段的触发器。这个触发器有什么问题吗?

回答

1

桌子上是否有触发器可能会颠倒插入?

+0

有一个触发器从序列创建主键。但它*不应该*反转插入。我会用触发器的DDL语句更新我的问题。 – 2009-09-29 18:38:22

1

根据我的经验,发生此类错误的最可能原因是发生了回滚事件。或者,如果有提交,另一个用户可能已经删除了该记录。

2

你的INSERT应该是:

INSERT INTO foo 
    (primary_key, 
    ...) 
VALUES 
    (log_elig_demographics_seq.nextval, 
    ...) 
RETURNING primary_key INTO :bind_var 

没有必要的触发。

3

甲ROWID不会改变,除非:

  • 从一个分区移动表(ALTER TABLE吨MOVE),从一个表到另一例如
  • 行切换到另一个(分区表使用ENABLE ROW MOVEMENT)
  • 您更新INDEX ORGANIZED表的主键。

当从一个块的行移动到另一在标准(堆)的表,因为它长得大就不能装配到其原始例如块,它将被迁移。 Oracle会留下一个指向新块的指针并移动该行。该行将保持其原始ROWID。

可以依赖ROWID,它们用于复制以刷新实例化视图。

+0

除此之外,ALTER TABLE MOVE不是移动表格的唯一方法,它仍然需要表格锁定。在线表格重新定义将更有可能表现出这种行为,因为新插入可能会从“旧”和“新”段之间移动。 – 2009-09-30 09:42:16

2

我同意沃尔特。

而不是

 
INSERT INTO foo (...) VALUES (...) RETURNING ROWID INTO :bind_var 
SELECT ... FROM foo WHERE ROWID = :bind_var 


...为什么不执行以下操作?

 
SELECT primaryKey_seq.nextVal 
INTO bind_var 
FROM dual; 

INSERT INTO foo (primaryKeyColumn,...) 
VALUES (bind_var,...); 

SELECT ... FROM foo WHERE primaryKeyColumn = bind_var; 
2

几个其他的事情可能会发生。 首先,INSERT可能失败。你在检查错误/异常吗?如果不是,那么变量中的值可能是垃圾。其次,你可以插入一些你可以选择的东西。虚拟专用数据库/行级安全可以负责。第三,如果您在插入和选择之间提交,则延迟约束可能会强制插入的回滚。

第四,也许你正在做一个回滚。

1

如何声明绑定变量?在SQLPlus中,您不能使用ROWID类型,因此需要进行类型转换。我想知道这是否有可能在某些时候消耗ROWID值。

相关问题