2012-12-01 43 views
0

我想編寫一個PL/SQL函數,它將參數2個參數作爲參數。第一個參數是一個整數,第二個參數是一個Oracle序列對象。使用Oracle PL/SQL函數將對象序列作爲參數傳遞

該函數返回一個十進制值,該值爲param1.param2,其中param2必須是作爲參數的序列對象的下一個值。

例如:功能myFc(15,objSq)。假設objSq.nextVal是33那麼返回的十進制值必須是15.33

+2

嗯,我從來沒有見過這樣的要求。你能分享更多的信息嗎?因爲我擔心你會以這種方式解決問題。 –

+0

我同意戴維。您可以傳入一個字符串作爲序列的名稱,如'schemaname.mysequence',然後創建一個動態字符串,使用EXEC IMMEDIATE從序列中選擇nextval。這是一件非常奇怪的事情。 –

回答

1

這似乎有點奇怪。你應該總是知道你將要使用什麼樣的序列,並且請注意一個序列從不會生成a gap-free sequence of numbers,這是一個完美的1,2 ..n。

由於您不知道對象名稱,因此您必須使用execute immediate,這使您可以使用它。您應該也可以使用dbms_assert來防止SQL注入。

的回答你的問題會是這個樣子:

create or replace my_function ( 
       Pnumber in number 
       , Psequence in varchar2) return number is 

    l_nextval number; 

begin 

    execute immediate ' 
     select ' || dbms_assert.sql_object_name(Psequence) || '.nextval 
     from dual' 
     into l_nextval; 

    -- Who knows how many decimal places you might need? 
    return to_number(Pnumber || '.' || l_nextval, '99.9999'); 

end; 
/

然而,我不明白你爲什麼會想這樣做。您顯然知道您嘗試使用的序列的名稱。而不是使用功能的,你可以簡單地在你的調用代碼使用這些信息:

to_number(15 || '.' || sequence_name.nextval, '99.9999') 

最後,大衛在他的評論中說,這是一個很奇怪的規定。你確定這是你想做的事嗎?也許通過解釋爲什麼你正在這樣做,有人可能會提出一個更好的建議。

+0

感謝這就是我需要的 – pFace

+0

如果您使用序列來表示序列的「右側」(小數側)值,您應該考慮使用序列的「CYCLE」選項。如果序列號爲9.999,則下一個數字應將小數位重置爲:0,但小數點的左側應該增加,以便9.999之後的數字確實爲10.000。 –

+0

@Ben'你應該總是知道你將要使用的序列/然而,我不明白你爲什麼要這樣做這是基本的間接方式。想想可重用性,我的朋友。就像你不想複製觸發器7次(因爲你不應該,但AFAIK你不能將一個觸發器附加到多個表),而是將工作委託給一個通用存儲過程,並將不同的東西作爲輸入。有些場景需要使用無法預先硬編碼的序列。 – Powerslave

相關問題