Oracle中rowid插入后会立即失效吗?

发布于 2024-08-06 07:57:37 字数 637 浏览 7 评论 0原文

我正在运行如下所示的查询:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

千里故人稀 2024-08-13 07:57:37

ROWID 不会更改,除非:

  • 您将表 (ALTER TABLE t MOVE) 从一个表空间移动到另一个表空间,例如,
  • 行从一个分区切换到另一个分区(使用 ENABLE ROW MOVMENT 的分区表)
  • 您更新 INDEX 的主键有组织的表。

当一行在标准(HEAP)表中从一个块移动到另一个块时,由于它变得太大而无法容纳到其原始块中,因此它将被迁移。 Oracle 将留下一个指向新块的指针并移动该行。该行将保留其原始 ROWID。

ROWID 是可以信赖的,它们在复制中用于刷新物化视图等。

A ROWID won't change unless:

  • you move the table (ALTER TABLE t MOVE), from one tablespace to another for example
  • the row switches from one partition to another (partitioned table with ENABLE ROW MOVEMENT)
  • you update the primary key of an INDEX ORGANIZED table.

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.

依 靠 2024-08-13 07:57:37

您的 INSERT 应该是:

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

不需要触发器。

Your INSERT should be:

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

There's no need for the trigger.

一场春暖 2024-08-13 07:57:37

我同意沃尔特的观点。

而不是

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;

I agree with Walter.

Instead of

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

...why not do the following?

SELECT primaryKey_seq.nextVal
INTO bind_var
FROM dual;

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

SELECT ... FROM foo WHERE primaryKeyColumn = bind_var;
岁月染过的梦 2024-08-13 07:57:37

可能还会发生其他一些事情。
首先,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.

呆萌少年 2024-08-13 07:57:37

表上是否存在可能反转插入的触发器?

Is there a trigger on the table that might be reversing the insert?

愁杀 2024-08-13 07:57:37

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

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.

儭儭莪哋寶赑 2024-08-13 07:57:37

绑定变量是如何声明的?在 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文