この例では、JSON型属性を持つ構造化ユーザー定義型(UDT)を作成する方法を示しています。この例のルーチンは、SYSUDTLIBデータベースで作成されます。このため、ユーザーにはSYSUDTLIBデータベースに対するUDTMETHOD権限が必要です。
SQL定義
このセクションでは、構造化されたUDTを作成するために必要なSQL DDL文を示します。
JSON属性を持つ構造化されたUDTの作成
次の文は、Att1という名前のJSON属性を持つjudtという名前の構造化UDTを作成します。JSON属性の最大長は100000文字で、JSON属性の文字セットはUNICODEです。
CREATE TYPE judt AS (Att1 JSON(100000) CHARACTER SET UNICODE) NOT FINAL CONSTRUCTOR METHOD judt (p1 JSON(100000) CHARACTER SET UNICODE) RETURNS judt SELF AS RESULT SPECIFIC judt_cstr LANGUAGE C PARAMETER STYLE TD_GENERAL RETURNS NULL ON NULL INPUT DETERMINISTIC NO SQL;
UDTのコンストラクタ メソッドの作成
次の文は、judt UDTのインスタンスを初期化するために使用するコンストラクタ メソッドを作成します。
CREATE CONSTRUCTOR METHOD judt (p1 JSON(100000) CHARACTER SET UNICODE) FOR judt EXTERNAL NAME 'CS!judt_cstr!judt_constructor.c!F!judt_cstr';
UDTの変換機能の作成
次の文は、tosqlおよびfromsql変換ルーチンを作成します。
REPLACE FUNCTION SYSUDTLIB.judt_fromsql (judt) RETURNS CLOB AS LOCATOR CHARACTER SET UNICODE NO SQL CALLED ON NULL INPUT PARAMETER STYLE SQL DETERMINISTIC LANGUAGE C EXTERNAL NAME 'CS!judt_fromsql!judt_fromsql.c!F!judt_fromsql';
CREATE FUNCTION SYSUDTLIB.judt_tosql (CLOB AS LOCATOR CHARACTER SET UNICODE) RETURNS judt NO SQL PARAMETER STYLE TD_GENERAL RETURNS NULL ON NULL INPUT DETERMINISTIC LANGUAGE C EXTERNAL NAME 'CS!judt_tosql!judt_tosql.c!F!judt_tosql';
次の文は、tosqlおよびfromsql変換ルーチンをjudt UDTに関連付けます。
CREATE TRANSFORM FOR judt judt_io (TO SQL WITH SPECIFIC FUNCTION SYSUDTLIB.judt_tosql, FROM SQL WITH SPECIFIC FUNCTION SYSUDTLIB.judt_fromsql);
UDTの並べ替え機能の作成
次の文は、judt値の比較に使用されるマップ順序付けルーチンを作成します。
CREATE FUNCTION SYSUDTLIB.judt_order (p1 judt) RETURNS INTEGER NO SQL PARAMETER STYLE SQL RETURNS NULL ON NULL INPUT DETERMINISTIC LANGUAGE C EXTERNAL NAME 'CS!judt_order!judt_order.c!F!judt_order';
CREATE ORDERING FOR judt ORDER FULL BY MAP WITH FUNCTION SYSUDTLIB.judt_order;
UDTのキャスト機能の作成
次の文はjudt UDTおよびCLOBに対するキャスト動作を定義します。
CREATE CAST (judt AS CLOB CHARACTER SET UNICODE) WITH FUNCTION judt_fromsql(judt) AS ASSIGNMENT;
CREATE CAST (CLOB CHARACTER SET UNICODE AS judt) WITH FUNCTION judt_tosql AS ASSIGNMENT;
Cソース ファイル
このセクションでは、前のセクションで作成されたメソッドおよび関数のCコードを示します。これは単にサンプルのコードなので、tosqlまたは順序付け関数に有意義な論理はありません。ただし、コンストラクタとfromsqlルーチンの例に基づいて、必要な機能を実行するように前のルーチンを強化できます。
judt_constructor.c
#define SQL_TEXT Latin_Text #include <sqltypes_td.h> #include <string.h> #include <stdio.h> #define buffer_size 64000 void judt_cstr( UDT_HANDLE *inUdt, JSON_HANDLE *file1, UDT_HANDLE *resultUdt, char sqlstate[6]) { char trunc_err[6] = "25001"; int actualInputLength = 0; BYTE input1[buffer_size] = {0}; int inputMaxLength = 0; charset_et inputCharSet = 0; int inNumLobs= 0; FNC_GetJSONInfo(*file1,&inputMaxLength,&inputCharSet,&inNumLobs); if (inNumLobs == 0) { FNC_GetInternalValue(*file1,input1,buffer_size, &actualInputLength); FNC_SetStructuredAttribute(*resultUdt, "Att1", input1, 0, actualInputLength); } else { LOB_LOCATOR inLOB; LOB_RESULT_LOCATOR outLob; LOB_CONTEXT_ID id; FNC_LobLength_t readlen, writelen; int trunc_err = 0; FNC_GetJSONInputLob(*file1,&inLOB); FNC_GetStructuredResultLobAttribute(*resultUdt, "Att1", &outLob); FNC_LobOpen(inLOB, &id, 0, 0); actualInputLength = FNC_GetLobLength(inLOB); while(FNC_LobRead(id, input1, buffer_size, &readlen) == 0 && !trunc_err ) { trunc_err = FNC_LobAppend(outLob, input1, readlen, &writelen); } } }
judt_fromsql.c
#define SQL_TEXT Latin_Text #include <sqltypes_td.h> #include <string.h> #define buffer_size 200000 void judt_fromsql(UDT_HANDLE *udt, LOB_RESULT_LOCATOR *result, int *inNull, int *outNull, char sqlstate[6]) { int nullIndicator,length; BYTE temp[buffer_size]; if (*inNull != -1) { FNC_LobLength_t readlen, writelen; attribute_info_t attrInfo; FNC_GetStructuredAttributeInfo(*udt,0,sizeof(attrInfo), &attrInfo); if (attrInfo.lob_length == 0) { FNC_GetStructuredAttribute(*udt, "Att1", temp, buffer_size, &nullIndicator, &length); readlen = length; FNC_LobAppend(*result, temp, readlen, &writelen); } else { LOB_LOCATOR inLob; LOB_CONTEXT_ID id; int trunc_err = 0; int remBufSize = buffer_size; BYTE *input1Ptr = temp; readlen = 0; FNC_GetStructuredInputLobAttribute(*udt, "Att1", &nullIndicator, &inLob); FNC_LobOpen(inLob, &id, 0, 0); length = FNC_GetLobLength(inLob); while(FNC_LobRead(id, temp, buffer_size, &readlen) == 0 && !trunc_err ) { trunc_err = FNC_LobAppend(*result, temp, readlen, &writelen); } FNC_LobClose(id); } *outNull = 0; } else *outNull = -1; }
judt_tosql.c
#define SQL_TEXT Latin_Text #include <sqltypes_td.h> #include <string.h> void judt_tosql (LOB_LOCATOR *p1, UDT_HANDLE *result, char sqlstate[6]) { /* Using the LOB FNC routines, read from 'p1' and load the data into the JSON attribute, depending on its length. See judt_cstr() for an example of loading the JSON attribute. */ }
judt_order.c
#define SQL_TEXT Latin_Text #include "sqltypes_td.h" #define buffer_size 512 void judt_order ( UDT_HANDLE *UDT, INTEGER *result, int *indicator_udt, int *indicator_result, char sqlstate[6], SQL_TEXT extname[129], SQL_TEXT specific_name[129], SQL_TEXT error_message[257]) { /* Read out as much data as necessary, using either FNC_GetStructuredAttribute or FNC_GetStructuredInputLobAttribute + LOB FNC routines, following the example in judt_fromsql. Then use this data to make the determination about the value of this instance in terms of ordering. */ }
例: judt型の使用
新しく作成されたjudt型の使用方法を次に示します。
CREATE TABLE judtTable(id INTEGER, j1 judt); INSERT INTO judtTable(1, NEW judt(NEW JSON('{"name":"Cameron"}', UNICODE))); INSERT INTO judtTable(2, NEW judt('{"name":"Melissa"}')); SELECT * FROM judtTable ORDER BY 1;
結果:
id j1 ----------- ---------------------------------------------------------- 1 {"name":"Cameron"} 2 {"name":"Melissa"}