17.10 - ルーチンの生成 - FastExport

Teradata® FastExportリファレンス

Product
FastExport
Release Number
17.10
Release Date
2021年6月
Content Type
プログラミング リファレンス
Publication ID
B035-2410-061K-JPN
Language
日本語 (日本)

以下の3つのサンプル プログラム ファイルがFastExportユーティリティに付属しています。これらのファイルは、ワークステーション接続のWindowsクライアント システムにおいて、INMOD、OUTMOD、および通知出口ルーチンを生成し、FastExportジョブ スクリプトの中で使用するのに役立ちます。これらのサンプル ファイルのリストは、このトピックの後半で説明します。

サンプル ファイル 説明
feimod.c INMODルーチンのソース ファイルです。
feomod.c OUTMODルーチンのソース ファイルです。
fenotf.c 通知出口ルーチンのソース ファイルです。
これら3つのサンプル ファイルはWindows用の例ですが、各ファイルの注釈部分に記載されているように、共有オブジェクト ファイルにコンパイルおよび連係すれば、UNIXシステムにも有効です。

FastExportジョブでINMOD、OUTMOD、または通知出口ルーチンを生成して使用する方法

INMODルーチン、OUTMODルーチン、または通知出口ルーチンを生成して使用するためには、参考用サンプル ファイル リストを参照し、この手順に従います。

  1. ルーチンのソース ファイルを編集し、dynamn名が__declspecであることを確かめます。
  2. このトピックの後半の以下のサンプル ルーチン ファイルのリストを参照してください。
    • feimod.c
    • feomod.c
    • fenotf.c
  3. 次のコマンドを使用して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

  4. 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);
}