我正在編寫一個將供應商表中的數據轉換爲本地表的過程,並且有許多從源表上的光標映射到目標表的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
- 我希望獲得一個通用的程序/函數,可以安全地分配他們之間,截斷多餘字符。
非常有趣的問題!我嘗試了'sys.anydata' +'sys.anytype'組合,但目前還沒有運氣。我試着把'p_src'放到一個從'dual'中選擇的引用遊標中,並且通過'dbms_sql'描述遊標列...也沒有運氣。到目前爲止,我認爲唯一的「優化」是你對最大字符串長度進行二分搜索而不是線性搜索。 :-) – nop77svk
我也一直在研究'anydata'和'anytype',但是我還不太熟悉他們想要什麼。其他一些與我一起工作的人也提出了二分法搜索 - 如果沒有更好的選擇,我肯定會實現這一點。 –