Oracle中rowid插入后会立即失效吗?
我正在运行如下所示的查询:
INSERT INTO foo (...) VALUES (...) RETURNING ROWID INTO :bind_var
SELECT ... FROM foo WHERE ROWID = :bind_var
本质上,我插入一行并获取其 ROWID,然后针对该 ROWID 进行选择以从该记录取回数据。但偶尔会找不到 ROWID。
忽略可能有更好的方法来完成我想做的事情这一事实,假设没有其他人使用数据库,ROWID 是否可以快速更改?
更新涉及一个触发器。下面是它的 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/AUTO INCREMENT 字段。这个触发器有问题吗?
I'm running queries that look something like this:
INSERT INTO foo (...) VALUES (...) RETURNING ROWID INTO :bind_var
SELECT ... FROM foo WHERE ROWID = :bind_var
Essentially, I'm inserting a row and getting its ROWID, then doing a select against that ROWID to get data back from that record. Very occasionally though, the ROWID won't be found.
Ignoring the fact that there's probably a better way to do what I'm trying to do, is it possible for a ROWID to change that quickly assuming that there's no one else using the database?
UPDATE There is a trigger involved. Here's the DDL statement for it:
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;
Essentially, it's just a trigger that is set up to help us emulate an IDENTITY/AUTO INCREMENT field. Is there something wrong with this trigger?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
ROWID 不会更改,除非:
当一行在标准(HEAP)表中从一个块移动到另一个块时,由于它变得太大而无法容纳到其原始块中,因此它将被迁移。 Oracle 将留下一个指向新块的指针并移动该行。该行将保留其原始 ROWID。
ROWID 是可以信赖的,它们在复制中用于刷新物化视图等。
A ROWID won't change unless:
When a row moves from one block to another in a standard (HEAP) table, because it grows so large it can't fit into its original block for example, it will be migrated. Oracle will leave a pointer to the new block and move the row. The row will keep its original ROWID.
ROWIDs can be relied upon, they are used in replication to refresh materialized views for example.
您的 INSERT 应该是:
不需要触发器。
Your INSERT should be:
There's no need for the trigger.
我同意沃尔特的观点。
而不是
...为什么不执行以下操作?
I agree with Walter.
Instead of
...why not do the following?
可能还会发生其他一些事情。
首先,INSERT 可能会失败。您是否检查错误/异常?如果不是,则变量中的值可能是垃圾值。
其次,您可以插入一些可以选择的内容。虚拟专用数据库/行级安全性可能负责。
第三,如果您在插入和选择之间提交,则延迟约束可能会强制回滚插入。
第四,也许你正在做回滚。
A couple of other things may be happening.
Firstly, the INSERT may be failing. Are you checking for errors/exceptions ? If not, maybe the value in the variable is junk.
Secondly, you could be inserting something that you can select. Virtual Private Database / Row Level Security could be responsible.
Thirdly, if you commit in between the insert and select, a deferred constraint may force a rollback of the insert.
Fourthly, maybe you are doing a rollback.
表上是否存在可能反转插入的触发器?
Is there a trigger on the table that might be reversing the insert?
根据我的经验,发生此类错误的最可能原因是发生了回滚。或者,如果有提交,则其他用户可能已删除该记录。
In my experience, the most likely reason for such an error to happen is that somewhere in between, a rollback has happened. Or, if there has been a commit, another user might have deleted the record.
绑定变量是如何声明的?在 SQLPlus 中,不能使用 ROWID 类型,因此需要进行类型转换。我想知道这是否可能有时会影响 ROWID 值。
How is the bind variable declared? In SQLPlus, you can't use a ROWID type, so there is type conversion going on. I wonder if it's possible that this is munging the ROWID value some of the time.