2009-09-29 60 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值。

相關問題