以下の3つのサンプル プログラム ファイルがFastExportユーティリティに付属しています。これらのファイルは、ワークステーション接続のWindowsクライアント システムにおいて、INMOD、OUTMOD、および通知出口ルーチンを生成し、FastExportジョブ スクリプトの中で使用するのに役立ちます。これらのサンプル ファイルのリストは、このトピックの後半で説明します。
| サンプル ファイル | 説明 |
|---|---|
| feimod.c | INMODルーチンのソース ファイルです。 |
| feomod.c | OUTMODルーチンのソース ファイルです。 |
| fenotf.c | 通知出口ルーチンのソース ファイルです。 |
FastExportジョブでINMOD、OUTMOD、または通知出口ルーチンを生成して使用する方法
INMODルーチン、OUTMODルーチン、または通知出口ルーチンを生成して使用するためには、参考用サンプル ファイル リストを参照し、この手順に従います。
- ルーチンのソース ファイルを編集し、dynamn名が__declspecであることを確かめます。
- このトピックの後半の以下のサンプル ルーチン ファイルのリストを参照してください。
- feimod.c
- feomod.c
- fenotf.c
- 次のコマンドを使用してDLLを作成します。
cl.exe /nologo /MTd /W3 /Zp1 /c /O2 -D _WINDOWS -D _MBCS -D _USRDLL -D _CRT_SECURE_NO_DEPRECATE -D WIN64 -D _WIN64 -D WIN32 -D TA_nt_x8664=1 /Fo sourcefilename.obj sourcefilename.c
link.exe -largeaddressaware -incremental:no -debug -nologo /machine:X64 -dll -subsystem:windows,5.02 /out:sourcefilename.dll sourcefilename.obj
ここで、sourcefilenameはINMODまたは通知出口ルーチンのソース ファイルの名前です。
コマンドの実行が成功すると、ソース ファイルと同じ名前にファイル拡張子.dllが付いた次のようなファイルが生成されます。
sourcefilename.dll
- FastExportジョブ スクリプトの中で、以下のようにsourcefilename.dllを使用します。
ルーチンのタイプ sourcefilename.dllファイルの指定方法 INMOD IMPORTコマンドのINMOD modulename OUTMOD EXPORTコマンドのOUTMOD modulename 通知出口 BEGIN EXPORTコマンドのNOTIFYオプションのEXIT name指定
サンプルINMODルーチン
以下に挙げるのは、FastExportユーティリティ ソフトウェアに付属のサンプルINMODルーチンfeimod.cのリストです。
#include <stdio.h>
#include <stdlib.h>
/**********************************************************************/
/* */
/* feimod.c - Sample Inmod for FastExport. */
/* */
/* Copyright1996-2007, 2016 by Teradata Corporation. */
/* All Rights Reserved. */
/* TERADATA CONFIDENTIAL AND TRADE SECRET */
/* */
/* Purpose - This inmod generates two integers per record. The */
/* first is even and the second number is odd. */
/* */
/* Note - The number of records per file is determined by the */
/* variable NUM_RECORDS */
/* */
/* Execute - Build Inmod on a Unix system */
/* compile and link into shared object */
/* cc -G feimod.c - o feimod.so */
/* */
/* - Build Inmod on a Win32 system */
/* compile and link into dynamic link library */
/* cl /DWIN32 /LD feimod.c */
/* */
/**********************************************************************/
static int msg_cnt = 0;
typedef struct {
int ioseq;
short len;
char param[2000];
} param_type;
/* This structure is used to pass an odd and an even integer */
/* back to multiload
*/
typedef struct {
int code;
int len;
char data[32768];
} data_type;
#ifdef WIN32 /* Change for WIN32 */
__declspec(dllexport) void _dynamn(data_type *data_buf , param_type *parm_buf)
#else
void _dynamn(data_buf, parm_buf)
data_type *data_buf;
param_type *parm_buf;
#endif
{
char *myptr;
int i;
static int RECNUM = 0; /* number of records to load */
static int odd_counter = 0; /* odd integer counter */
static int even_counter = 0; /* even integer counter */
#ifdef DEBUG
printf("\n");
printf("jmod2: on input:\n");
printf("jmod2: message code: %d\n", data_buf->code);
printf("jmod2: data bytes: %d\n", data_buf->len);
if (data_buf->len)
printf("jmod2: data: *%s*\n", data_buf->data);
printf("jmod2: param ioseq: %d\n", parm_buf->ioseq);
printf("jmod2: param bytes: %d\n", parm_buf->len);
if (parm_buf->len)
printf("jmod2: param str: %s\n", parm_buf->param);
printf("jmod2: message cnt: %d\n", ++msg_cnt);
#endif
switch (data_buf->code)
{
case 0: printf("jmod2: initializing and returning 1st record:\n");
RECNUM = 6;
printf("jmod2: Records requested = %ld\n", RECNUM);
if ( RECNUM <= 0 ) {
printf("jmod2: numbers of records is <= 0 [%ld]\n", RECNUM);
}
/* initialize the counters */
odd_counter = 1;
even_counter = 2;
/* copy the counters to the data buffer */
myptr = (char *) &odd_counter;
for (i=0; i<4; ++i, ++myptr) {
data_buf->data[i] = *myptr;
}
myptr = (char *) &even_counter;
for (i=4; i<8; ++i, ++myptr) {
data_buf->data[i] = *myptr;
}
/* go to next values and increment the counters */
odd_counter += 2;
even_counter +=2;
--RECNUM;
/* return the results */
data_buf->code = 0;
data_buf->len = 8;
break;
case 1:
#ifdef DEBUG
printf("jmod2: returning a record:\n");
#endif
if (RECNUM) {
/* copy the counters to the data buffer */
myptr = (char *) &odd_counter;
for (i=0; i<4; ++i, ++myptr) {
data_buf->data[i] = *myptr;
}
myptr = (char *) &even_counter;
for (i=4; i<8; ++i, ++myptr) {
data_buf->data[i] = *myptr;
}
/* increment to next values and decrement record counter */
odd_counter += 2;
even_counter += 2;
--RECNUM;
/* return the results */
data_buf->code = 0;
data_buf->len = 8;
break;
} else {
/* done sending records, return non-zero result */
printf("jmod2: all records sent\n");
data_buf->code = 1;
break;
}
case 2: printf("jmod2: repositioning to last checkpoint (HOST)\n");
data_buf->code = 0;
data_buf->len = 0;
break;
case 3: printf("jmod2: taking a checkpoint\n");
data_buf->code = 0;
data_buf->len = 0;
break;
case 4: printf("jmod2: repositioning to last checkpoint (DBC)\n");
data_buf->code = 0;
data_buf->len = 0;
break;
case 5: printf("jmod2: terminating:\n");
data_buf->code = 0;
data_buf->len = 0;
break;
case 6: printf("jmod2: initializing and receiving 1st record:\n");
data_buf->data[1] = '%';
data_buf->code = 0;
break;
case 7: printf("jmod2: receiving a record:\n");
data_buf->data[1] = '%';
data_buf->code = 0;
break;
}
#ifdef DEBUG
printf("jmod2: on output:\n");
printf("jmod2: message code: %d\n", data_buf->code);
printf("jmod2: data bytes: %d\n", data_buf->len);
if (data_buf->len)
printf("jmod2: data: *%s*\n", data_buf->data);
printf("\n");
#endif
}
サンプルOUTMODルーチン
以下に挙げるのは、FastExportユーティリティ ソフトウェアに付属のサンプルOUTMODルーチンfeomod.cのリストです。
#include <stdio.h>
#include <stdlib.h>
/**********************************************************************/
/* */
/* feomod.c - Sample Outmod for FastExport. */
/* */
/* Copyright1996-2007, 2016 by Teradata Corporation. */
/* All Rights Reserved. */
/* TERADATA CONFIDENTIAL AND TRADE SECRET */
/* */
/* Purpose - This outmod deletes the data passed to it. */
/* */
/* Execute - Build Outmod on a Unix system */
/* compile and link into shared object */
/* cc -G feomod.c - o feomod.so */
/* */
/* - Build Outmod on a Win32 system */
/* compile and link into dynamic link library */
/* cl /DWIN32 /LD feomod.c */
/* */
/* */
/**********************************************************************/
typedef unsigned short Int16;
typedef unsigned char Int8;
typedef unsigned int UInt32;
#ifdef WIN32 /* Change for WIN32 */
__declspec(dllexport) UInt32 _dynamn( int *code,
int *stmno,
int *InLen,
char *InBuf,
int *OutLen,
char *OutBuf
)
#else
UInt32 _dynamn(code, stmno, InLen, InBuf, OutLen, OutBuf)
int *code;
int *stmno;
int *InLen;
char *InBuf;
int *OutLen;
char *OutBuf;
#endif
{
/* case on entry code
*/
switch (*code) {
case 1: /* Initialization, no other values */
printf ("OUTMOD Initial Entry\n");
break;
case 2: /* Cleanup call, no other values */
printf ("OUTMOD End of Responses Entry\n");
break;
case 3: /* Process response record */
*InLen=0;
*OutLen=0;
break;
case 4:
/* Checkpoint, no other values */
printf ("OUTMOD Checkpoint Entry\n");
break;
case 5:
/* DBC restart - close and reopen the output files */
printf ("OUTMOD DBC Restart Entry\n");
break;
case 6:
/* Host restart */
printf ("OUTMOD Host Restart Entry\n");
break;
default:
printf ("OUTMOD Invalid Entry code\n");
break;
}
return (0);
}
サンプル通知出口ルーチン
次に、FastExportユーティリティ ソフトウェアに付属するサンプル通知出口ルーチンfenotf.cのリストを示します。
/**********************************************************************/
/* */
/* fenotf.c - Sample Notify Exit for FastExport. */
/* */
/* Copyright1996-2013, 2016 by Teradata Corporation. */
/* All Rights Reserved. */
/* TERADATA CONFIDENTIAL AND TRADE SECRET */
/* */
/* Purpose - This is a sample notify exit for FastExport. */
/* */
/* Execute - Build Notify on a Unix system */
/* compile and link into shared object */
/* cc -G fenotf.c - o fenotf.so */
/* */
/* - Build Notify on a Win32 system */
/* compile and link into dynamic link library */
/* cl /DWIN32 /LD fenotf.c */
/* */
/**********************************************************************/
#include <stdio.h>
typedef unsigned int UInt32;
typedef int Int32;
#define NOTIFYID_FASTLOAD 1
#define NOTIFYID_MULTILOAD 2
#define NOTIFYID_FASTEXPORT 3
#define NOTIFYID_BTEQ 4
#define NOTIFYID_TPUMP 5
#define MAXVERSIONIDLEN 32
#define MAXUTILITYNAMELEN 32
#define MAXUSERNAMELEN 64
#define MAXUSERSTRLEN 80
#define MAXFILENAMELEN 256
#define MAXREQUESTLEN 32000
#define MAXDBNAMELEN 62
#define MAXUINT64 24
typedef enum {
NXEventInitialize = 0,
NXEventFileInmodOpen = 1,
NXEventDBSRestart = 9,
NXEventCLIError = 10,
NXEventDBSError = 11,
NXEventExit = 12,
NXEventExportBegin = 31,
NXEventReqSubmitBegin = 32,
NXEventReqSubmitEnd = 33,
NXEventReqFetchBegin = 34,
NXEventFileOutmodOpen = 35,
NXEventStmtFetchBegin = 36,
NXEventStmtFetchEnd = 37,
NXEventReqFetchEnd = 38,
NXEventExportEnd = 39,
NXEventBlockCount = 40,
NXEventExportEnd64 = 41,
NXEventInitializeEON = 42,
NXEventReqSubmitBeginEON = 43,
NXEventExportBeginEON = 44
} NfyExpEvent;
typedef struct _FXNotifyExitParm {
UInt32 Event;
union {
struct {
UInt32 VersionLen;
char VersionId[MAXVERSIONIDLEN];
UInt32 UtilityId;
UInt32 UtilityNameLen;
char UtilityName[MAXUTILITYNAMELEN];
UInt32 UserNameLen;
char UserName[MAXUSERNAMELEN];
UInt32 UserStringLen;
char UserString[MAXUSERSTRLEN];
}Initialize;
struct {
UInt32 VersionLen;
char VersionId[MAXVERSIONIDLEN];
UInt32 UtilityId;
UInt32 UtilityNameLen;
char UtilityName[MAXUTILITYNAMELEN];
UInt32 UserNameLen;
char *UserName;
UInt32 UserStringLen;
char UserString[MAXUSERSTRLEN];
} InitializeEON;
struct {
UInt32 FileNameLen;
char FileOrInmodName[MAXFILENAMELEN];
UInt32 dummy;
} FileInmodOpen ;
struct {
UInt32 dummy;
} DBSRestart;
struct {
UInt32 ErrorCode;
} CLIError;
struct {
UInt32 ErrorCode;
} DBSError;
struct {
UInt32 ReturnCode;
} Exit;
struct {
UInt32 dummy;
char DatabaseName[MAXDBNAMELEN];
} ExportBegin;
struct {
UInt32 dummy;
char *DatabaseName;
} ExportBeginEON;
struct {
UInt32 RequestLen;
char Request[MAXREQUESTLEN];
} ReqSubmitBegin;
struct {
UInt32 RequestLen;
char *Request;
} ReqSubmitBeginEON;
struct {
UInt32 StatementCnt;
UInt32 BlockCnt;
} ReqSubmitEnd;
struct {
UInt32 dummy;
} ReqFetchBegin;
struct {
UInt32 FileNameLen;
char FileOrOutmodName[MAXFILENAMELEN];
} FileOutmodOpen;
struct {
UInt32 StatementNo;
UInt32 BlockCnt;
} StmtFetchBegin;
struct {
UInt32 Records;
} StmtFetchEnd;
struct {
UInt32 RecsExported;
UInt32 RecsRejected;
} ReqFetchEnd;
struct {
UInt32 RecsExported;
UInt32 RecsRejected;
} ExportEnd;
struct {
char RecsExported[MAXUINT64];
UInt32 RecsRejected;
}ExportEnd64;
struct {
UInt32 BlockCount;
} BlockCount;
} Vals;
} FXNotifyExitParm;
extern Int32 FXNotifyExit(
#ifdef __STDC__
FXNotifyExitParm *Parms
#endif
);
#ifdef WIN32
__declspec(dllexport) Int32 _dynamn(FXNotifyExitParm *P)
#else
Int32 _dynamn( FXNotifyExitParm *P)
#endif
{
FILE *fp;
if (!(fp = fopen("NFYEXIT.OUT", "a")))
return(1);
switch(P->Event) {
case NXEventInitialize : /* Nothing */
fprintf(fp, "exit called @ fexp init.\n");
fprintf(fp, "Version: %s\n", P->Vals.Initialize.VersionId);
fprintf(fp, "Utility: %s\n", P->Vals.Initialize.UtilityName);
fprintf(fp, "User: %s\n", P->Vals.Initialize.UserName);
if (P->Vals.Initialize.UserStringLen)
fprintf(fp, "UserString: %s\n", P->Vals.Initialize.UserString);
break;
case NXEventInitializeEON :
fprintf(fp, "exiteon called @ fexp init.\n");
fprintf(fp, "Version: %s\n", P->Vals.InitializeEON.VersionId);
fprintf(fp, "Utility: %s\n", P->Vals.InitializeEON.UtilityName);
fprintf(fp, "User: %s\n", P->Vals.InitializeEON.UserName);
if (P->Vals.InitializeEON.UserStringLen)
fprintf(fp, "UserString: %s\n", P->Vals.InitializeEON.UserString);
break;
case NXEventFileInmodOpen:
fprintf(fp, "exit called @ input file open: %s\n",
P->Vals.FileInmodOpen.FileOrInmodName);
break;
case NXEventDBSRestart :
fprintf(fp, "exit called @ RDBMS restart detected\n");
break;
case NXEventCLIError :
fprintf(fp, "exit called @ CLI error %d\n",
P->Vals.CLIError.ErrorCode);
break;
case NXEventDBSError :
fprintf(fp, "exit called @ DBS error %d\n",
P->Vals.DBSError.ErrorCode);
break;
case NXEventExit :
fprintf(fp,
"exit called @ fexp notify out of scope: return code %d.\n",
P->Vals.Exit.ReturnCode);
break;
case NXEventExportBegin :
fprintf(fp, "exit called @ export beginning.\n");
fprintf(fp, "exit called @ export beginning - Database Name : %s\n",P->Vals.ExportBegin.DatabaseName); break;
case NXEventExportBeginEON :
fprintf(fp, "exiteon called @ export beginning.\n");
fprintf(fp, "exit called @ export beginning - Database Name : %s\n",
P->Vals.ExportBeginEON.DatabaseName);
break;
case NXEventReqSubmitBegin :
fprintf(fp, "exit called @ request submitted: '%s'.\n",
P->Vals.ReqSubmitBegin.Request);
break;
case NXEventReqSubmitBeginEON :
fprintf(fp, "exiteon called @ request submitted: '%s'.\n",
P->Vals.ReqSubmitBeginEON.Request);
break;
case NXEventReqSubmitEnd :
fprintf(fp, "exit called @ request done: %d statement(s), \
%d blocks.\n",
P->Vals.ReqSubmitEnd.StatementCnt,
P->Vals.ReqSubmitEnd.BlockCnt);
break;
case NXEventReqFetchBegin :
fprintf(fp, "exit called @ request fetch beginning.\n");
break;
case NXEventFileOutmodOpen:
fprintf(fp, "exit called @ output file open: %s\n",
P->Vals.FileOutmodOpen.FileOrOutmodName);
break;
case NXEventStmtFetchBegin :
fprintf(fp, "exit called @ statement fetch beginning: stmt #%d, \
%d blocks.\n",
P->Vals.StmtFetchBegin.StatementNo,
P->Vals.StmtFetchBegin.BlockCnt);
break;
case NXEventStmtFetchEnd :
fprintf(fp, "exit called @ statement fetch end: %d records.\n",
P->Vals.StmtFetchEnd.Records);
break;
case NXEventReqFetchEnd :
fprintf(fp, "exit called @ request fetch ends: \
Records exported: %d, Records rejected: %d\n",
P->Vals.ReqFetchEnd.RecsExported,
P->Vals.ReqFetchEnd.RecsRejected);
break;
case NXEventExportEnd :
fprintf(fp, "exit called @ export ends: \
Records exported: %d, Records rejected: %d\n",
P->Vals.ExportEnd.RecsExported,
P->Vals.ExportEnd.RecsRejected);
break;
case NXEventExportEnd64 :
fprintf(fp, "exit64 called @ export ends: \
Records exported: %s, Records rejected: %d\n",
P->Vals.ExportEnd64.RecsExported,
P->Vals.ExportEnd64.RecsRejected);
break;
case NXEventBlockCount :
fprintf(fp, "exit called @ request done in Nospool mode: %d \
blocks.\n", P->Vals.BlockCount.BlockCount);
break;
}
fclose(fp);
return(0);
}