データをマスクするフィールド・プロシージャー・プログラムの例
フィールド・プロシージャー FP1 を列 C1 に追加します。 フィールド・プロシージャー FP1 には、フィールド・プロシージャーが操作の対象とする列のバイト数を示す 1 つの追加パラメーターがあります。
ALTER TABLE TESTTAB ALTER C1 SET FIELDPROC FP1(10)
#include "string.h"
#include <QSYSINC/H/SQLFP>
void reverse(char *in, char *out, long length);
main(int argc, void *argv[])
{
short *funccode = argv[1];
sqlfpFieldProcedureParameterList_T *optionalParms = argv[2];
char *sqlstate = argv[7];
sqlfpMessageText_T *msgtext = argv[8];
int bytesToProcess;
sqlfpOptionalParameterValueDescriptor_T *optionalParmPtr;
sqlfpInformation_T *info = argv[9];
int masked;
if (optionalParms->sqlfpNumberOfOptionalParms != 1)
{
memcpy(sqlstate,"38001",5);
return;
}
optionalParmPtr = (void *)&(optionalParms->sqlfpParmList);
bytesToProcess = *((int *)&optionalParmPtr->sqlfpParmData);
/*******************************************************************/
/* CREATE CALL */
/*******************************************************************/
if (*funccode == 8) /* create time */
{
sqlfpParameterDescription_T *inDataType = argv[3];
sqlfpParameterDescription_T *outDataType = argv[5];
if (inDataType->sqlfpSqlType !=452 &&
inDataType->sqlfpSqlType !=453 ) /* only support fixed length char */
{
memcpy(sqlstate,"38002",5);
return;
}
/* do something here to determine the result data type */
/* ..... */
/* in this example input and output types are exactly the same */
/* so just copy */
memcpy(outDataType, inDataType, sizeof(sqlfpParameterDescription_T));
}
/*******************************************************************/
/* ENCODE (WRITE) CALL */
/*******************************************************************/
else if (*funccode == 0) /* encode */
{
char *decodedData = argv[4];
char *encodedData = argv[6];
/* Detect that the value passed on encode is masked. */
/* Return 09501 to tell DB that: */
/* - The field should not be updated for an update operation */
/* - The default value should be used for an insert operation*/
if ( memcmp(decodedData, "XXXXXXXXXXXX", 12) == 0 )
{
memcpy(sqlstate,"09501",5);
}
else
{
reverse(decodedData, encodedData, bytesToProcess);
}
}
/*******************************************************************/
/* DECODE (READ) CALL */
/*******************************************************************/
else if (*funccode == 4) /* decode */
{
char *decodedData = argv[4];
char *encodedData = argv[6];
/* The 9th paramter indicates that the column must not be */
/* masked. For exmaple, during ALTER TABLE or RGZPFM. */
if ( info->sqlfpNoMask == '1' )
{
reverse(encodedData, decodedData, bytesToProcess);
return;
}
else
{
reverse(encodedData, decodedData, bytesToProcess);
/* Mask the data when appropriate */
/* Assume mask is set to 0 when it should not be masked */
/* and 1 when it shoulbe be masked */
if (masked == 1)
{
memcpy(decodedData, "XXXXXXXXXXXX", 12);
}
}
return;
}
/*******************************************************************/
/* ERROR- UNSUPPORTED OPTION */
/*******************************************************************/
else /* unsupported option -- error */
memcpy(sqlstate, "38003",5);
}
/*******************************************************************/
/* REVERSE */
/*******************************************************************/
void reverse(char *in, char *out, long length)
{
int i;
for (i=0;i<length; ++i) {
out[length - (i+1)] = in[i];
}
}