次に示すリクエストでは、std_devという名前のJavaの集約UDFを作成します。
CREATE FUNCTION std_dev( x FLOAT) RETURNS FLOAT CLASS AGGREGATE(79) LANGUAGE JAVA NO SQL PARAMETER STYLE JAVA EXTERNAL NAME 'UDF_JAR:UserDefinedFunctions.std_dev( com.teradata.fnc.Phase, com.teradata.fnc.Context[], double) returns java.lang.Double';
集約UDFの場合は、Javaメソッドの一部として2つのオブジェクト タイプ パラメータを追加で指定する必要があります。つまり、現在の集約フェーズを指定するためのcom.teradata.fnc.Phaseと、実行時にコンテキストを取得/設定するためのcom.teradata.fnc.Contextです。これら2つのパラメータの詳細について、<Teradata Vantage™ - SQL外部ルーチン プログラミング、B035-1147>を参照してください。
バイト ベースのアプローチかオブジェクト ベースのアプローチのいずれかを使用して、集約UDFの中間結果を格納できます。バイト ベースのアプローチはメモリの消費が少なくパフォーマンスを向上させることができますが、中間記憶域に格納されたバイト配列はシステムで自動的にエンコードおよびデコードされないため、ユーザーがこれをエンコードおよびデコードする必要があります。オブジェクト ベースのアプローチでは、バイト配列はJavaオブジェクト逐次化によりエンコードおよびデコードされるため、理解しやすい代わりにパフォーマンスに影響を与えます。
Java集約関数に対するオブジェクト ベースのアプローチでは、中間集約記憶域に必要なバイト数がデフォルト値64を超えたときには常にCLASS AGGREGATE句を指定してバイト数を指定する必要があります。
指定するCLASS AGGREGATE値は、中間集約記憶域がメモリで占有することができる最大バイト数です。値は関数のパフォーマンスに与える影響はCLASS AGGREGATEサイズと相関しているため、常にできるだけ小さい値を設定してください。
Java集約関数の場合、中間結果はバイト配列に逐次化されるオブジェクトとして格納されます。中間記憶域のサイズを小さくしておくには、INNERクラスを避け、クラスとそのデータ メンバーに短い名前を選択することです。また、オブジェクトの中間結果を格納するために必要なバイト数を計算して、そのバイト数をCLASS AGGREGATE句に指定する必要があります。次のコードは、オブジェクトの逐次化サイズ(バイト数)の計算方法を例示しています。
public static int getSize(Object obj){ int size=0; try{ ByteArrayOutputStream barr = new ByteArrayOutputStream(); ObjectOutput s = new ObjectOutputStream(barr); s.writeObject(obj); s.close(); size=barr.toByteArray().length; System.out.println("obj="+obj+",size="+size); }catch(IOException e){ e.printStackTrace(); } return size; }