2016-03-15 35 views
0

我知道SQL Server。在使用Oracle的項目上,並且有時間做事。我目前的問題是,我們有一個類似於以下的表格:基於不同字段的Oracle序列字段遞增

ACCOUNT_ID NUMBER 
SEQUENCE_ID NUMBER 
DISPLAY_NAME VARCHAR2 
TOKEN  VARCHAR2 
PAYMENT_TYPE NUMBER 

Account_ID可以在此表中多次出現。我需要的是Sequence_ID需要爲每個Account_ID唯一地增加。所以看起來像這樣。

ACCOUNT_ID SEQUENCE_ID DISPLAY_NAME TOKEN PAYMENT_TYPE 
------------------------------------------------------------------ 
111111  1    Primary   abcd  1 
222222  1    Primary   bcde  1 
222222  2    Secondary  dffs  1 
333333  1    Default   fdsf  2 
111111  2    Alternate  sfff  2 
222222  3    Another   slsl  1 

正如您所見,11111的Account_ID有2條記錄,並且Sequence_ID不會爲該Account_ID重複。基本上,Sequence_ID是自動遞增的,但對於每個Account_ID都是唯一的。

這可能嗎?

+0

可能的但不是與序列。存儲過程或函數必須被合併爲此。 –

回答

2

可以封裝所有的邏輯過程:

CREATE OR REPLACE PROCEDURE create_Account(
    in_account_id IN ACCOUNTS.ACCOUNT_ID%TYPE, 
    in_display_name IN ACCOUNTS.DISPLAY_NAME%TYPE, 
    in_token   IN ACCOUNTS.TOKEN%TYPE, 
    in_payment_type IN ACCOUNTS.PAYMENT_TYPE%TYPE 
) 
AS 
    p_seq_id ACCOUNTS.SEQUENCE_ID%TYPE; 
BEGIN 
    SELECT COUNT(*) + 1 
    INTO p_seq_no 
    FROM ACCOUNTS 
    WHERE ACCOUNT_ID = in_account_id; 

    INSERT INTO ACCOUNTS (
    account_id, 
    sequence_id, 
    display_name, 
    token, 
    payment_type 
) VALUES (
    in_account_id, 
    p_seq_id, 
    in_display_name, 
    in_token, 
    in_payment_type 
); 
END; 
/

或者你可以只使用一個INSERT

INSERT INTO ACCOUNTS 
SELECT :account_id, 
     COUNT(*) + 1, 
     :display_name, 
     :token, 
     :payment_type 
FROM ACCOUNTS 
WHERE account_id = :account_id; 
0

我認爲最簡單的解決方案,您的問題將是上創建一個觸發您的表如下:

create or replace trigger yourtable_biu 
    before insert or update of ACCOUNT_ID on yourtable 
    referencing new as new old as old 
    for each row 
begin 
    select count(*) into :new.SEQUENCE_ID from yourtable where ACCOUNT_ID = new.ACCOUNT_ID; 
end; 
/
+2

不鼓勵對[這些](http://www.toadworld.com/platforms/oracle/w/wiki/5806.trigger-disadvantages)原因使用觸發器。除非,直到沒有其他出路。 –

+0

@SameerMirji我真的不認爲觸發器是如此邪惡,並且這個鏈接仍然是相關的,但當然應該考慮到所有... – mrkovec

0

正如上面的答案完美說明,您可以使用Procedure to 來做到這一點。如果您不想使用過程中的所有內容,則可以使用 函數,因爲您可以以任何方式使用函數的返回值。希望這個 幫助。

CREATE OR REPLACE FUNCTION create_Account(
    in_account_id IN ACCOUNTS.ACCOUNT_ID%TYPE, 
    in_display_name IN ACCOUNTS.DISPLAY_NAME%TYPE, 
    in_token   IN ACCOUNTS.TOKEN%TYPE, 
    in_payment_type IN ACCOUNTS.PAYMENT_TYPE%TYPE 
) 
RETURN PLS_INTEGER 
AS 
    p_seq_id ACCOUNTS.SEQUENCE_ID%TYPE; 
BEGIN 
    SELECT COUNT(*) + 1 
    INTO p_seq_no 
    FROM ACCOUNTS 
    WHERE ACCOUNT_ID = in_account_id; 

RETURN p_seq_no; 
END; 
+0

因此,我們也可以從過程返回值。我不明白爲什麼功能比這裏的過程更好。 –

+3

您似乎已經逐字複製了我的過程標題和正文的一部分,但您僅使用其中一個輸入值,因此剩下的部分是多餘的。如果你顯示如何在INSERT語句中使用它,它也會很有用。 – MT0

+0

是的,正如我在我的回答中提到的,在這種情況下,您的答案是完美的。但是,重點是將DML交易與下一代分開。同樣的事情可以爲DML調用一個可以使用這個函數來獲取seq的過程。 –