如果你是12cR2,那麼你可以使用VALIDATE_CONVERSION
在進行轉換之前檢查潛在類型轉換的有效性並完全避免該例外。
在早期版本中,您可以爲TIMESTAMP
創建自己的等效函數,該函數試圖進行轉換並處理異常。您可以單獨聲明每個異常類型,並根據需要單獨記錄/處理每個感興趣的故障模式,對於您不關心或想要記錄/處理的內容,整體爲WHEN OTHERS
:
CREATE OR REPLACE FUNCTION IS_TIMESTAMP_FORMAT_OK(P_TIMESTAMP_TEXT IN VARCHAR2, P_FORMAT IN VARCHAR2 DEFAULT 'yyyy-MM-dd')
RETURN BOOLEAN
IS
--exception names
V_TIMESTAMP TIMESTAMP;
DAY_OF_MONTH EXCEPTION;
NON_NUMERIC EXCEPTION;
--etc.
PRAGMA EXCEPTION_INIT (DAY_OF_MONTH, -1847);
PRAGMA EXCEPTION_INIT (NON_NUMERIC, -1858);
BEGIN
V_TIMESTAMP := to_timestamp(P_TIMESTAMP_TEXT, P_FORMAT);
RETURN TRUE;
EXCEPTION WHEN DAY_OF_MONTH
THEN
DBMS_OUTPUT.PUT_LINE('The day of month must be between...');
RETURN FALSE;
WHEN NON_NUMERIC
THEN
DBMS_OUTPUT.PUT_LINE('Non-Numeric data was found...');
RETURN FALSE;
--etc.
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(UTL_LMS.FORMAT_MESSAGE('Unexpected timestamp problem: %s', SQLERRM));
RETURN FALSE;
END;
/
然後你就可以登錄/處理類型的興趣:
DECLARE
V_CHECK BOOLEAN;
BEGIN
V_CHECK := IS_TIMESTAMP_FORMAT_OK('2016010a');
V_CHECK := IS_TIMESTAMP_FORMAT_OK('2016-01-aa');
V_CHECK := IS_TIMESTAMP_FORMAT_OK('2016-01-0a');
IF IS_TIMESTAMP_FORMAT_OK('2014-01-01')
THEN
DBMS_OUTPUT.PUT_LINE('It is ok. Yay');
END IF;
END;
/
Unexpected timestamp problem: ORA-01862: the numeric value does not match the
length of the format item
Non-Numeric data was found...
The day of month must be between...
It is ok. Yay
或者,如果你不關心日誌記錄/處理不同故障模式,只是想阻止廣泛的異常奪目,你可以繼續使用WHEN OTHERS
,但在隔離範圍內:
CREATE OR REPLACE FUNCTION
IS_TIMESTAMP_FORMAT_OK(P_TIMESTAMP_TEXT IN VARCHAR2, P_FORMAT IN VARCHAR2 DEFAULT 'yyyy-MM-dd')
RETURN BOOLEAN
IS
V_TIMESTAMP TIMESTAMP;
BEGIN
V_TIMESTAMP := to_timestamp(P_TIMESTAMP_TEXT, P_FORMAT);
RETURN TRUE;
EXCEPTION WHEN OTHERS THEN
RETURN FALSE;
END;
/
或內聯:
DECLARE
V_MY_TIMESTAMP TIMESTAMP;
BEGIN
-- some other code ...
BEGIN
V_MY_TIMESTAMP := to_timestamp('2016-01-aa', 'yyyy-MM-dd');
EXCEPTION WHEN OTHERS THEN NULL;
END;
DBMS_OUTPUT.PUT_LINE('My Timestamp:'||V_MY_TIMESTAMP);
END;
/
My Timestamp:
感謝馬修。我想知道你使用的是什麼版本的oracle?如果在12cR2上,如果你有'validate_conversion'函數可能會感興趣。 – alexgibbs
另一個問題,我不知道你的帖子。你是否也想避免多個異常塊(對於不同的異常,多個'EXCEPTION_INIT')或者只是爲了避免'當其他異常'?謝謝 – alexgibbs
@alexgibbs不幸的是我在12cR1,但我們應該遲早會升級,所以我會留意的。理想情況下,除了避免「WHEN OTHERS」之外,對於由不正確的日期字符串導致的'to_timestamp'產生的所有可能的錯誤捕獲單個異常將是很好的,但我不確定這是否可能。 –