2011-11-17 44 views
0

在用戶界面中,我顯示account_idaccount_name
用戶能夠更新account_id以及account_name,並且account_id對用戶是唯一的。由於我允許用戶更新account_id(組合鍵),我怎樣才能在更新時創建一個where子句?SQL:如何更新複合鍵?

以下是我的餐桌設計。

CREATE TABLE accounts (
    user_id  VARCHAR2(20) NOT NULL, 
    account_id VARCHAR2(20) NOT NULL, 
    account_name VARCHAR2(20) NOT NULL 
) 

ALTER TABLE accounts ADD CONSTRAINT 
uk_myTable_1 UNIQUE (User_id, account_id) 
+0

雖然這有效,但我都是爲了永遠不會分享或展示的幕後不可變的鑰匙;它消除了外鍵關係和組合鍵部分更新的問題。(IE添加一個字段(AccountID,這是PK,並用於FK關係。 – xQbert

+0

@OMGPonies它的Oracle ... – james007

+0

一些想法的飼料:http://programmers.stackexchange.com/questions/8187/should-a- primary-key-be-immutable – xQbert

回答

3

account_iduser_id值保持,直到你改變它們。

因此。如果它開始爲user_id 10與account_id 20,並且您將account_id更改爲30

UPDATE accounts 
    SET account_id = '30' 
    WHERE account_id = '20' 
     AND user_id = '10'; 

雖然,你保留你的複合鍵的所有值情況下,上述工程,我所有的,它永遠不會共享或顯示的幕後不可改變的關鍵。它消除了外鍵關係和組合鍵部分更新的問題。要實現這一點,添加一個字段(AccountID),這是PK,並在FK關係中使用。

或者,Oracle可以通過使用ROWSCN和所有表的無狀態環境行相關性來做類似於此的事情。如果僅使用AccountID,則可能遇到的問題是,在多用戶環境中,可以讓人員對記錄1和用戶2進行更新以編輯記錄1,然後保存;覆蓋用戶1的更新。這是我提到ROWSCN和ROWDEPENDENCIES的原因。但是,如果您處於狀態感知的環境中,這將會過度。

最後,您可以在更新課程之前更改操作的順序以執行數據庫更新。這樣你有兩個值。

+0

我喜歡你的解決方案,在幕後擁有不變的鑰匙......在你的答案部分明確你的觀點...... – james007

0
UPDATE accounts 
SET whatevercolumnsyouwantasnormal 
WHERE USER_ID = 'whatever' and ACCOUNT_ID = 'whatever2' 

顯然,這將需要你(在新的單獨)跟蹤原始USER_ID和ACCOUNT_ID,直至發出UPDATE。

如果這是一個Web應用程序(特別是),請務必考慮用戶快速連續兩次觸發此過程的情況。

或者,查看Oracle的RowID。您可以在WHERE子句中使用它,而不是PK列。

+0

更新賬戶設置account_id ='dummy2'其中user_id ='user1'和account_id ='accountid'因爲我更改了UI中的account_id,所以在業務層沒有舊的account_id來形成where子句... – james007

+0

GUI中的隱藏字段,用於跟蹤組合鍵。或者您的類需要擴展以保留組合鍵的值,以便您可以構建where子句...... – xQbert

+0

@ james007您需要跟蹤某種方式來識別該行。沒有其他辦法了。 – mjwills

0

試試這個:

UPDATE accounts SET account_id = New_account,account_name = new_name 
WHERE user_id = Old_id and account_id = old_account_id 
+0

因爲我正在改變account_id,我不保留old_account_id ..我足夠的靈活性,以改變表設計,如果需要....我需要跟蹤old_values?我相信,不是好practive .. – james007

+0

您必須將原始帳戶ID存儲在某個地方,否則如何查找該記錄。我只建議使用舊的帳戶ID作爲搜索關鍵字...... – Sparky

+0

我認爲他意味着包含信息的類在覆蓋數據庫之前被覆蓋。另一種選擇是在您更新課程之前更新數據庫。 – xQbert

0

SQL中的工作單元是行,而不是列。

現在不實際運行這一點,但認爲

UPDATE accounts 
    SET user_id = account_id, 
     account_id = user_id ; 

會成功交換user_idaccount_id爲所有用戶。這是因爲受到更新影響的所有行(由WHERE子句確定)都會一次全部更新。