Se till att du använder sifferdatatypen med skala och precision som är lämpliga för data istället för att använda NUMBER
utan skala och precision. Om du ska lagra dollar/euro/pund/etc. sedan Gross World Product
var i storleksordningen 100 000 000 000 000 $ 2014. Låt oss anta att du inte kommer att ha att göra med mer än så här, då kan din valutakolumn vara:
NUMBER(17,2)
Om du får ett värde som är större än så måste du göra en förnuftskontroll på din data och fundera på om ett belopp som är större än världens bruttoprodukt är vettigt. Om du ska lagra värdena som till exempel yen eller zimbabwiska dollar, justera skalan på lämpligt sätt.
Du kan till och med definiera en undertyp i ett paket som:
CREATE PACKAGE currencies_pkg IS
SUBTYPE currency_type IS NUMBER(17,2);
FUNCTION formatCurrency(
amount IN CURRENCY_TYPE
) RETURN VARCHAR2;
END;
/
Och din kod för att formatera den kan vara:
CREATE PACKAGE BODY currencies_pkg IS
FUNCTION formatCurrency(
amount IN CURRENCY_TYPE
) RETURN VARCHAR2
IS
BEGIN
RETURN TO_CHAR( currency_value, 'FM999999999999990D00' );
END;
END;
/
Om du sedan refererar till den undertypen i dina lagrade procedurer/paket kommer du inte att kunna överskrida den maximala storleken på valutadatatypen utan att ett undantag höjs. Formatmodellen för att visa värdet behöver bara definieras på ett enda ställe och eftersom inmatningen är begränsad till valutasubtypen kommer formateringsfunktionen aldrig att överskrida den pålagda skalan/precisionen och kan inte mata ut # s.
CREATE PROCEDURE your_procedure(
in_value1 IN ACCOUNTS_TABLE.ACCOUNT_BALANCE%TYPE,
in_value2 IN ACCOUNTS_TABLE.ACCOUNT_BALANCE%TYPE
)
IS
v_value CURRENCIES_PKG.CURRENCY_TYPE;
BEGIN
-- Do something
v_value := in_value1 + in_value2;
-- Output formatted value
DBMS_OUTPUT.PUT_LINE( CURRENCIES_PKG.formatCurrency( v_value ) );
END;
/