2014-07-03 43 views
2

我正在編寫一個將供應商表中的數據轉換爲本地表的過程,並且有許多從源表上的光標映射到目標表的ROWTYPE的分配。所有供應商的字符串列的大小定義爲255,但我們的字符串列的定義更嚴格,通常只有30或50個字符。如果源表的字符串太長而目標行類型的列無法接受,則某些映射會拋出異常VALUE_ERROR自動截斷超過目標字符串大小的源字符串

預期的結果是目標ROWTYPE的列包含儘可能多的可容納的部分,其餘部分將被截斷。我的第一本能就是簡單地使用SUBSTR並對最大尺寸進行硬編碼,但必須有一個更加優雅和強大的解決方案。

我想出了一個解決方案(雖然它不給我溫暖的模糊感覺)是以下過程,它只處理異常並重試映射。

PROCEDURE p_safe_mapper(p_dest IN OUT VARCHAR2, p_out IN VARCHAR2) IS 
counter INTEGER := 0; 
    BEGIN 
    --only loop for as many characters are in the source string 
    WHILE counter < length(p_src) LOOP 
    BEGIN 
     --attempt to map, trimming COUNTER characters from the end of the source string. If it works, we're done. 
     p_dest := substr(p_src, 
         0, 
         length(p_src) - counter); 
     EXIT; 
    EXCEPTION 
     --else if we get an error, increment the counter to try again with the source string one character shorter. 
     WHEN value_error THEN 
     counter := counter + 1; 
    END; 
    END LOOP; 
END; 

我也考慮表列的大小查詢ALL_TAB_COLUMNS,但我不知道任何方式從具有ROWTYPE那裏。基本上,因爲甲骨文顯然知道我的變量的最大大小 - 無論他們ROWTYPEs,遊標,或普通老VARCHAR2s - 我希望獲得一個通用的程序/函數,可以安全地分配他們之間,截斷多餘字符。

+0

非常有趣的問題!我嘗試了'sys.anydata' +'sys.anytype'組合,但目前還沒有運氣。我試着把'p_src'放到一個從'dual'中選擇的引用遊標中,並且通過'dbms_sql'描述遊標列...也沒有運氣。到目前爲止,我認爲唯一的「優化」是你對最大字符串長度進行二分搜索而不是線性搜索。 :-) – nop77svk

+0

我也一直在研究'anydata'和'anytype',但是我還不太熟悉他們想要什麼。其他一些與我一起工作的人也提出了二分法搜索 - 如果沒有更好的選擇,我肯定會實現這一點。 –

回答

1

我可以看到兩種方法可以做到這一點 - 無論是

A)更改p_safe_mapper接受第三個參數定義的最大允許輸出字符串大小

B)更改p_safe_mapper接受目標表和列名稱,並使用它們在* _TAB_COLUMNS視圖之一中查找最大大小。

分享和享受。

+0

感謝您的建議。關於選項A,我絕對可以做到這一點沒有什麼問題,但我試圖避免硬編碼的大小。關於選項B,有沒有辦法查詢ROWTYPE或遊標的大小數據的* _TAB_COLUMNS視圖?不幸的是,我不是直接寫入表格,而是寫入這些其他中間容器。 –

+1

@TheDIMMReaper rowtype和cursor是PL/SQL結構,所以我不認爲你會爲它們找到任何元數據。相反,你必須知道表和列。 – user272735

+0

@ user272735謝謝,這是有道理的。有沒有另外一種方法可以從PL/SQL端獲得類似的數據,而不需要知道表? –