2012-05-18 95 views
1

我有一個員工,產品和產品里程錶表看起來像下面Oracle存儲過程生成序列號?

enter image description here

每個員工都有要看他訪問該產品的獨特emp_code。

每個產品都有一個唯一的標識符前綴。

我需要爲每個產品生成一個唯一的字母數字標識符並將其分配給員工。

此產品標識符將包含前綴9個字符。

里程錶將存儲分配給該特定產品中的員工的最後一個emp_code。

如何編寫一個存儲過程來爲系統中添加的每個新員工生成基於產品的這些字母數字emp_codes?

請幫忙。

編輯1:

只是在里程錶表小幅盤整,我們可能不需要里程錶存儲爲A00000001。相反,我們只能存儲00000001,然後附加前綴。

編輯2:

這是我做的這麼遠。

create or replace PROCEDURE SP_GEN_NEXT_DUMMY_DB_PRISM_ID 
(
    in_product_id number, 
    db_prism_id out varchar2 
) 
AS 
BEGIN 

    UPDATE BI_DB_PRISM_ID_ODOMETER 
    SET DB_PRISM_ID = DB_PRISM_ID + 1 
    WHERE 
    PRODUCT_ID = in_product_id; 

    SELECT to_char(db_prism_id, 'FM00000000') into db_prism_id FROM  BI_DB_PRISM_ID_ODOMETER WHERE PRODUCT_ID = in_product_id; 

END; 

但我怎麼能確保它在一個事務中運行,並且還我怎麼追加產品前綴產生的數量。

+0

他們需要在一個產品中連續嗎? – zerkms

+0

@ zerkms.Yes。他們需要連續。它不應該是一些隨機數字。 – ashishjmeshram

+0

@zerkms。可能發生的情況是,我們生成了一個連續的號碼,但它從來沒有分配給員工,在這種情況下,它丟失了,這與我們一致。 – ashishjmeshram

回答

3

你,我能想到的兩個選項:

  1. 爲每個產品Oracle序列,也許某種維護程序,將檢測新產品和新動態創建序列。

  2. 滾動你自己的序列碼。將最後一個值存儲在Product表中。編寫一個爲給定產品生成新值的過程。該過程將首先獲取產品表上的行鎖(以便您不會同時獲得兩個會話相同的值),提前值並將新值寫入Product表。您需要將此過程設置爲自治事務(否則,其他會話只會在會話未提交或立即回滾的情況下等待)。

#1的優點是它是最快的。

#1的一個缺點是您不得不運行動態DDL,並且您必須確保在嘗試插入里程計記錄之前運行產品的DDL。如果產品被刪除,您可能還需要考慮是否刪除序列。

#1的另一個缺點是您只能使用動態SQL獲取序列值(您必須在運行時確定序列的名稱)。

#2的一個缺點是容易讓一個允許併發DML的系統出錯。你需要確保你的邏輯正確,並在高併發負載下進行測試。此外,#2將執行比#1差,因爲它序列化每個產品的訪問。

編輯

「但我怎麼能確保它在一個事務中運行,並且還怎麼 我追加的產品前綴產生的數量。」

事務在Oracle中是自動的。但是,在這種情況下,您想要的是autonomous transaction

附加產品前綴是使用字符串連接功能完成的 - 例如, ||

+0

請參閱我已將我的答案更新至目前爲止所嘗試的內容。 – ashishjmeshram

+0

已更新的答案。順便說一句,從代碼中不清楚你指的是哪張表 - 你似乎在增加里程表上的ID,這對我來說沒有意義? –

1

似乎是你在這裏使數據模型非規範化。

里程錶與產品表是1:1,里程錶的價值也取決於當前分配給該產品的員工數量。

emp_code序列號可以從員工ID和產品表派生。可以說,標識符前綴也可以從產品ID中推斷出來,所以實際上您的模式中有冗餘列和冗餘表。

你確定你確實需要它們嗎?

0

也許我錯過了這裏的東西,如果是的話,接受我的道歉。

在我看來,里程錶僅僅是有多少員工訪問每個產品的計數器。

如果是這樣的話,爲什麼不放棄表(和EMP_CODE列),並在一個或多個視圖中「建立」信息?

亞歷山德羅

PS:貌似我貼大衛阿爾德里奇的同樣的建議。對困惑感到抱歉。