消費税込み金額を計算したり、税抜き金額を計算したりするPL/SQLパッケージ。
消費税率が変わったらTAX_CALENDARという名前のテーブルに税率を追加すればいい。
これで消費税が上がっても大丈夫。10%でも20%でも平気。どんとこい。
TAX_RATE2は、テーブルを使わずに、FUNCTION内で日付とレートをハードコードして判断している。税率が変わったら書き直さないといけない。税率変わるたびにメンテナンス=ソース変更とリコンパイルが必要だけれど、まあ、運用環境によってはこっちがいい場合も多いか。シンプルだし速いはず。
/* || 消費税率のカレンダーテーブル */ DROP TABLE TAX_CALENDAR; / -- TAX CALENDAR TABLE CREATE TABLE TAX_CALENDAR ( DtS date NOT NULL, DtE date NOT NULL, TAX number(3,2) ); -- TAX TABLE ALTER TABLE TAX_CALENDAR ADD CONSTRAINT DISP_TAX_CALENDAR_PK PRIMARY KEY (DtS,DtE); / /* || TAX_CALENDAR INSERTION */ DELETE FROM TAX_CALENDAR; INSERT INTO TAX_CALENDAR(DtS,DtE,Tax) VALUES(to_date('1900-01-01'),to_date('1989-04-01'),0.000); INSERT INTO TAX_CALENDAR(DtS,DtE,Tax) VALUES(to_date('1989-04-01'),to_date('1997-04-01'),0.03); INSERT INTO TAX_CALENDAR(DtS,DtE,Tax) VALUES(to_date('1997-04-01'),to_date('2999-04-01'),0.05); CREATE OR REPLACE PACKAGE TAX_PKG AS -- 日付で消費税率を返す FUNCTION TAX_RATE(i_date IN date DEFAULT SYSDATE) RETURN NUMBER; -- 日付と金額で消費税額を返す FUNCTION TAX(i_price IN NUMBER,i_date IN date DEFAULT SYSDATE) RETURN NUMBER; -- 日付と金額で税込金額を返す FUNCTION INCLUDE_TAX(i_price IN NUMBER,i_date IN date DEFAULT SYSDATE) RETURN NUMBER; PRAGMA RESTRICT_REFERENCES(TAX_RATE,WNDS); PRAGMA RESTRICT_REFERENCES(TAX,WNDS); PRAGMA RESTRICT_REFERENCES(INCLUDE_TAX,WNDS); END TAX_PKG; / CREATE OR REPLACE PACKAGE BODY TAX_PKG AS /* || 日付で消費税率を返す || TAX_CALENDARテーブルを参照する */ FUNCTION TAX_RATE(i_date IN date DEFAULT SYSDATE) RETURN NUMBER IS ATax number; BEGIN SELECT TAX INTO ATAX FROM TAX_CALENDAR WHERE i_date >= DtS AND i_date < DtE; RETURN ATAX; END; /* || 日付で消費税率を返す */ FUNCTION TAX_RATE2(i_date IN date DEFAULT SYSDATE) RETURN NUMBER IS BEGIN IF i_date < to_date('89-04-01') THEN RETURN 0.00; ELSIF i_date < to_date('97-04-01') THEN RETURN 0.03; ELSE RETURN 0.05; --現状 END IF; END; ------------------------------------------------------- -- 日付と金額で消費税額を返す ------------------------------------------------------- FUNCTION TAX(i_price IN NUMBER, i_date IN date DEFAULT SYSDATE) RETURN NUMBER IS BEGIN RETURN ROUND(i_price * TAX_RATE(i_date)); END; ------------------------------------------------------- -- 日付と金額で税込金額を返す ------------------------------------------------------- FUNCTION INCLUDE_TAX(i_price IN NUMBER, i_date IN date DEFAULT SYSDATE) RETURN NUMBER IS BEGIN RETURN ROUND(i_price + (i_price * TAX_RATE(i_date))); END; END TAX_PKG; / ------------------------------------------------------- -- 消費税計算のテスト用 ------------------------------------------------------- select tax_pkg.tax_rate('89-03-31'), tax_pkg.tax_rate('89-04-01'), tax_pkg.tax_rate('97-03-31'), tax_pkg.tax_rate('97-04-01'), tax_pkg.tax_rate(SYSDATE) from dual; select tax_pkg.tax(101,'89-03-31'), tax_pkg.tax(101,'89-04-01'), tax_pkg.tax(101,'97-03-31'), tax_pkg.tax(101,'97-04-01'), tax_pkg.tax(101,SYSDATE) from dual; select tax_pkg.include_tax(101,'89-03-31'), tax_pkg.include_tax(101,'89-04-01'), tax_pkg.include_tax(101,'97-03-31'), tax_pkg.include_tax(101,'97-04-01'), tax_pkg.include_tax(101,SYSDATE) from dual;