Db2 luwでのEBCDIC照合順序のサポート
アプリケーションの都合によってEBCDIC並びをluwプラットフォームで実現したい場合があります。Db2luwでは、CREATE DATABASEを行うときにCODESE、TERRITORYとCOLLATEを指定することで決まりますが、EBCDICについてはサポートされていません。そのため、ユーザー定義の照合順序を使用する必要があります。
ユーザー定義の照合順序を指定したCREATE DBを行うために、~/sqllib/samples/c/dbcreate.cがサンプルとして用意されているので、これを利用してEBCDIC照合順序を使用できるDBを作成してみます。
ソースコードの作成
操作はDb2のインスタンスオーナーで行っています。~/sqllib/samples/c/dbcreate.cを適当なディレクトリーにコピーします。インスタンスオーナーでのCREATE DBだけをサポートできればよいので、ソースコードを改変します。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sqle932b.h>
#include <sqlutil.h>
#include <sqlenv.h>
int DbCreate(char *, char *, char *);
int main(int argc, char *argv[])
{
int rc = 0;
char dbName[SQL_DBNAME_SZ + 1];
char dbLocalAlias[SQL_ALIAS_SZ + 1];
char dbPath[SQL_PATH_SZ + 1];
switch(argc)
{
case 2:
strcpy(dbName, argv[1]);
strcpy(dbLocalAlias, "");
strcpy(dbPath, "");
break;
case 3:
strcpy(dbName, argv[1]);
strcpy(dbLocalAlias, argv[2]);
strcpy(dbPath, "");
break;
case 4:
strcpy(dbName, argv[1]);
strcpy(dbLocalAlias, argv[2]);
strcpy(dbPath, argv[3]);
break;
default:
printf("Check usage.\n");
return 1;
}
rc = DbCreate(dbName, dbLocalAlias, dbPath);
return rc;
} /* main */
int DbCreate(char *dbName, char *dbLocalAlias, char *dbPath)
{
struct sqlca sqlca;
struct sqledbdesc dbDescriptor;
SQLEDBTERRITORYINFO territoryInfo;
strcpy(dbDescriptor.sqldbdid, SQLE_DBDESC_2);
dbDescriptor.sqldbccp = 0;
dbDescriptor.sqldbcss = SQL_CS_USER;
memcpy(dbDescriptor.sqldbudc, sqle_932_5026, SQL_CS_SZ);
strcpy(dbDescriptor.sqldbcmt, "EBCDIC ORDER DB");
dbDescriptor.sqldbsgp = 0;
dbDescriptor.sqldbnsg = 10;
dbDescriptor.sqltsext = -1;
dbDescriptor.sqlcatts = NULL;
dbDescriptor.sqlusrts = NULL;
dbDescriptor.sqltmpts = NULL;
strcpy(territoryInfo.sqldbcodeset, "IBM-943");
strcpy(territoryInfo.sqldblocale, "JP");
sqlecrea(dbName,
dbLocalAlias,
dbPath,
&dbDescriptor,
&territoryInfo,
'\0',
NULL,
&sqlca);
printf("%s\n",sqlca.sqlstate);
return sqlca.sqlcode;
}
もとのソースコードにあったutilapi、utilembなどは今回の場合には必要ないので削除しました。次にMakefileを作成し、makeしてdbcreateモジュールを作成します。
CC = gcc
CFLAGS = -O4 -Wall -I/home/db2inst1/sqllib/include
LDFLAGS = -Wl,-rpath,/home/db2inst1/sqllib/lib64 -L/home/db2inst1/sqllib/lib64
LIBS = -ldb2
OBJ = dbcreate.o
PROGRAM = dbcreate
SRC = dbcreate.c
all: $(PROGRAM)
$(PROGRAM) : $(OBJ)
$(CC) -o $(PROGRAM) $(OBJ) $(LDFLAGS) $(LIBS)
$(OBJ) : $(SRC)
$(CC) -c $(SRC) $(CFLAGS)
clean:; rm -f *.o *~ $(PROGRAM)
DBの作成
作成したモジュールを実行し、list db directoryコマンドで作成できていることを確認します。
./dbcreate TESTEBC
db2 list db directory
Database 3 entry:
Database alias = TESTEBC
Database name = TESTEBC
Local database directory = /home/db2inst1
Database release level = 15.00
Comment = EBCDIC order db2
Directory entry type = Indirect
Catalog database partition number = 0
Alternate server hostname =
Alternate server port number =
照合順序の確認
db2 "select C from T order by C"で並び順を確認します。table Tについては適当に作成し、データも適当に入れました。
db2 "create table T (C char(1))"
db2 "select C from T order by C"
EBCDIC照合順序のテーブル ASCII照合順序のテーブル
C C
- -
+ +
a 3
A A
Z Z
3 a
EBCIDIC照合順序のテーブルでは、数字が後ろになっている、英小文字がCAPS文字より前にきているなど、EBCDICの特徴を反映できました。
注意点としては、この方法は半角文字についてだけ適用できる方法で、DBCS文字については適用できません。多くの場合、並べ替えのキー項目は半角文字で作成されているので、事足りるのだと思います。