特殊タイプの操作例として以下のものを挙げます。
たとえば、1999 年 7 月 (7/99) に米国で 100 000.00 米ドルを超える売上があった商品を知りたいとします。
SELECT PRODUCT_ITEM FROM US_SALES WHERE TOTAL > US_DOLLAR (100000) AND month = 7 AND year = 1999
米ドルとそのソース・タイプのインスタンス (すなわち DECIMAL) を直接比較できないので、 DB2 により提供されるキャスト機能を使用して DECIMAL から米ドルにキャストしました。また、DB2 により提供されるもう 1 つのキャスト機能 (すなわち、米ドルから DECIMAL にキャストする機能) を使用して、列の合計を DECIMAL にキャストすることもできます。特殊タイプからのキャストの場合はキャストを実行するキャスト指定表記法を、特殊タイプへのキャストの場合は機能表記法をそれぞれ使用することができます。すなわち、上記の照会は以下のように作成してもかまいません。
SELECT PRODUCT_ITEM FROM US_SALES WHERE TOTAL > CAST (100000 AS us_dollar) AND MONTH = 7 AND YEAR = 1999
たとえば、カナダドルを米ドルに変換する UDF を定義したいとします。このとき、DB2 の外部で管理されているファイルから現行の為替相場を求めることができるとします。そこで、カナダドルの値を取得し、為替相場のファイルにアクセスし、米ドルの額に対応した値を戻すような UDF を定義します。
一見、このような UDF を定義するのは容易に見えるかもしれません。しかし、C は DECIMAL の値をサポートしません。異なる通貨を表す特殊タイプは、DECIMAL と定義しました。 10 進精度を失わずに DECIMAL の値を表すことができる、 C によって提供される唯一のデータ・タイプは DOUBLE なので、 UDF は、DOUBLE の値を受け取り、戻す必要があります。このため、UDF は以下のように定義しなければなりません。
CREATE FUNCTION CDN_TO_US_DOUBLE(DOUBLE) RETURNS DOUBLE EXTERNAL NAME '/u/finance/funcdir/currencies!cdn2us' LANGUAGE C PARAMETER STYLE DB2SQL NO SQL NOT DETERMINISTIC NO EXTERNAL ACTION FENCED
UDF が 2 回呼び出される間にカナダドルおよび米ドルの為替相場が変化する場合があるので、 UDF は NOT DETERMINISTIC として宣言します。
ここで問題なのは、どのようにしてカナダドルを UDF に渡して、それから米ドルを受け取るかということです。カナダドルは、DECIMAL の値にキャストしなければなりません。 DECIMAL の値は DOUBLE にキャストしなければなりません。また、戻された DOUBLE の値を DECIMAL に、DECIMAL の値を米ドルにキャストしなければなりません。
このようなキャストは、ソース派生 UDF を定義する際に DB2 により自動的に実行され、その UDF のパラメーターおよび戻りタイプはソース関数のものと正確には一致しません。そのため、ソース派生 UDF を 2 つ定義する必要があります。最初のものは、DECIMAL 表記に DOUBLE の値を渡します。 2 番目のものは、特殊タイプに DECIMAL の値を渡します。すなわち、以下のものを定義します。
CREATE FUNCTION CDN_TO_US_DEC (DECIMAL(9,2)) RETURNS DECIMAL(9,2) SOURCE CDN_TO_US_DOUBLE (DOUBLE) CREATE FUNCTION US_DOLLAR (CANADIAN_DOLLAR) RETURNS US_DOLLAR SOURCE CDN_TO_US_DEC (DECIMAL())
US_DOLLAR(C1) (C1 はタイプがカナダドルの列) のような US_DOLLAR 関数の呼び出しは、この以下の呼び出しと同じように作用します。
US_DOLLAR (DECIMAL(CDN_TO_US_DOUBLE (DOUBLE (DECIMAL (C1)))))
つまりこれは (カナダドルの) C1 が 10 進数にキャストされ、次に倍精度値にキャストされてから CDN_TO_US_DOUBLE 関数に渡されるということです。この関数は、為替相場のファイルにアクセスし、倍精度値 (米ドルで額を表す) を戻します。この値は、まず 10 進数に、その後米ドルにキャストされます。
ユーロを米ドルに変換する関数は、上記の例と同様になります。
CREATE FUNCTION EURO_TO_US_DOUBL(DOUBLE) RETURNS DOUBLE EXTERNAL NAME '/u/finance/funcdir/currencies!euro2us' LANGUAGE C PARAMETER STYLE DB2SQL NO SQL NOT DETERMINISTIC NO EXTERNAL ACTION FENCED CREATE FUNCTION EURO_TO_US_DEC (DECIMAL(9,2)) RETURNS DECIMAL(9,2) SOURCE EURO_TO_US_DOUBL (DOUBLE) CREATE FUNCTION US_DOLLAR(EURO) RETURNS US_DOLLAR SOURCE EURO_TO_US_DEC (DECIMAL())
たとえば、1999 年 7 月 (7/99) に米国において、カナダおよびドイツよりも売上の多かった製品を知りたいとします。
SELECT US.PRODUCT_ITEM, US.TOTAL FROM US_SALES AS US, CANADIAN_SALES AS CDN, GERMAN_SALES AS GERMAN WHERE US.PRODUCT_ITEM = CDN.PRODUCT_ITEM AND US.PRODUCT_ITEM = GERMAN.PRODUCT_ITEM AND US.TOTAL > US_DOLLAR (CDN.TOTAL) AND US.TOTAL > US_DOLLAR (GERMAN.TOTAL) AND US.MONTH = 7 AND US.YEAR = 1999 AND CDN.MONTH = 7 AND CDN.YEAR = 1999 AND GERMAN.MONTH = 7 AND GERMAN.YEAR = 1999
米ドルは、カナダドルやユーロと直接比較できないので、カナダドルの額を米ドルにキャストする UDF や、ユーロの額を米ドルにキャストする UDF を使用します。各総額を貨幣上比較できないので、これらすべてを DECIMAL にキャストし、変換された DECIMAL の値を比較することはできません。すなわち、各総額が同じ通貨でないということです。
たとえば、ユーロの SUM をサポートする SUM 組み込み関数にソース派生 UDF を定義したとします。
CREATE FUNCTION SUM (EUROS) RETURNS EUROS SOURCE SYSIBM.SUM (DECIMAL())
1994 年のドイツにおける各製品の売上総額を知りたいとします。米ドルで総売上を求めます。
SELECT PRODUCT_ITEM, US_DOLLAR (SUM (TOTAL)) FROM GERMAN_SALES WHERE YEAR = 1994 GROUP BY PRODUCT_ITEM
上記と同じ方法で米ドルに SUM 関数を定義していないと、 SUM (us_dollar (total)) を定義できません。
新規の応募者が記入した書式をデータベースに保管する場合を考えてみましょう。ここで、記入された書式を表すのに使用する文字ストリングの値を含む、ホスト変数を次のように定義してあるものとします。
EXEC SQL BEGIN DECLARE SECTION; SQL TYPE IS CLOB(32K) hv_form; EXEC SQL END DECLARE SECTION; /* Code to fill hv_form */ INSERT INTO APPLICATIONS VALUES (134523, 'Peter Holland', CURRENT DATE, :hv_form)
DB2 が、特殊タイプのソース・タイプのインスタンスをその特殊タイプを持つターゲットに割り当てるようにさせるので、キャスト機能を明示的に呼び出してその文字ストリングを特殊タイプの personal.application_form に変換することはしません。
例: 特殊タイプを使用した割り当てで示されたのと同じステートメントを動的 SQL で使用したい場合は、次のようにパラメーター・マーカーを使用します。
EXEC SQL BEGIN DECLARE SECTION; long id; char name[30]; SQL TYPE IS CLOB(32K) form; char command[80]; EXEC SQL END DECLARE SECTION; /* Code to fill host variables */ strcpy(command,"INSERT INTO APPLICATIONS VALUES"); strcat(command,"(?, ?, CURRENT DATE, CAST (? AS CLOB(32K)))"); EXEC SQL PREPARE APP_INSERT FROM :command; EXEC SQL EXECUTE APP_INSERT USING :id, :name, :form;
DB2 のキャスト指定を使用して、パラメーター・マーカーのタイプが CLOB(32K)、すなわち特殊タイプ列に割り当て可能なタイプであることを DB2 に通知します。なお、ホスト言語は特殊タイプをサポートしないので、特殊タイプのタイプのホスト変数を宣言することはできません。そのため、パラメーター・マーカーのタイプを特殊タイプと指定することはできません。
たとえば、米ドルおよびカナダドルの SUM をサポートする SUM 組み込み関数に、 例: 特殊タイプを使用したソース派生 UDF 中のユーロのソース派生 UDF と同じ 2 つの UDF を定義したとします。
CREATE FUNCTION SUM (CANADIAN_DOLLAR) RETURNS CANADIAN_DOLLAR SOURCE SYSIBM.SUM (DECIMAL()) CREATE FUNCTION SUM (US_DOLLAR) RETURNS US_DOLLAR SOURCE SYSIBM.SUM (DECIMAL())
ここで、各国における各製品についての 1 年間の総売上米ドルで、別々の表に保存するように上司から要求されたとします。
CREATE TABLE US_SALES_94 (PRODUCT_ITEM INTEGER, TOTAL US_DOLLAR) CREATE TABLE GERMAN_SALES_94 (PRODUCT_ITEM INTEGER, TOTAL US_DOLLAR) CREATE TABLE CANADIAN_SALES_94 (PRODUCT_ITEM INTEGER, TOTAL US_DOLLAR) INSERT INTO US_SALES_94 SELECT PRODUCT_ITEM, SUM (TOTAL) FROM US_SALES WHERE YEAR = 1994 GROUP BY PRODUCT_ITEM INSERT INTO GERMAN_SALES_94 SELECT PRODUCT_ITEM, US_DOLLAR (SUM (TOTAL)) FROM GERMAN_SALES WHERE YEAR = 1994 GROUP BY PRODUCT_ITEM INSERT INTO CANADIAN_SALES_94 SELECT PRODUCT_ITEM, US_DOLLAR (SUM (TOTAL)) FROM CANADIAN_SALES WHERE YEAR = 1994 GROUP BY PRODUCT_ITEM
異なる特殊タイプ同士を直接互いに割り当てることはできないので、カナダドルおよびユーロの金額を米ドルに明示的にキャストします。特殊タイプはそれ自体のソース・タイプにしかキャストできないので、キャスト指定構文を使用できません。
たとえば、米国のユーザーに自分の会社の全製品の総売上を含む視点を提供したいとします。
CREATE VIEW ALL_SALES AS SELECT PRODUCT_ITEM, MONTH, YEAR, TOTAL FROM US_SALES UNION SELECT PRODUCT_ITEM, MONTH, YEAR, US_DOLLAR (TOTAL) FROM CANADIAN_SALES UNION SELECT PRODUCT_ITEM, MONTH, YEAR, US_DOLLAR (TOTAL) FROM GERMAN_SALES
特殊タイプは、同じ特殊タイプ同士でないと一緒に比較できないので、カナダドルを米ドルに、そしてユーロを米ドルにキャストします。なお、キャスト指定では、特殊タイプおよびそのソース・タイプ間のキャストしかできないので、機能表記法を使用してキャストしなければなりません。