Приложение 5. Пример разбора спецификации выборки данных
#include < stdio.h > #include < stdlib.h > #include < string.h > #include "decimals.h" #include "inter.h" #include "tick.h" #ifdef WIN32 #include < float.h > #define isnan(f) _isnan(f) #define isinf(f) (!_finite(f)) #endif #include "exlib.h" void PrintError(TCBL*pCBL); void PrintResult(L_BYTE*Buf, L_BYTE*VarBuf); void Print_value(L_CHAR*text, P_TYPE Type, L_BYTE*Buf); char Query_Create_Table[]="create or replace table TEST (C1 char(10)," "C2 int,C3 real,C4 date,C5 decimal,C6 byte(10),C7 smallint,C8 double," "C9 bigint,C10 varchar(10),C11 varbyte(10),C12 boolean,C13 nchar(10)," "C14 nchar varying(10), C15 BLOB, C16 extfile);"; char Query_Create_TabNan[]="create or replace table TESTnan (" "C1 int,C2 real,C3 double);"; char Query_Insert_Table1[]="insert into test values ('azzabyybcc',12,-12.345670," "to_date('1998-12-01','YYYY-MM-DD'), 12.34," "hex('FFFEFDFCFBFAF9F8F7F6'),30000,30.01,182834584," "'azzabyybcc',hex('FFFEFDFCFBFAF9F8F7F6')," "true,n'абвгдеж',n'abcdefg', NULL, extfile('1.txt'));"; char Query_Insert_Table[]="insert into test values " "(NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL);"; char Query_InsNaN_Table[]="insert into test(c3,c8) " "values ( cast HEXTORAW('0000807F00000000') as real," "cast HEXTORAW('000000000000F07F0000000000000000') as double);"; char Query_InsNaN1_Table[]="insert into test(c3,c8) " "values ( cast HEXTORAW('000080FF00000000') as real," "cast HEXTORAW('000000000000F0FF0000000000000000') as DOUBLE);"; char Query_InsNaN2_Table[]="insert into test(c3,c8) " "values ( cast HEXTORAW('0000C0FF00000000') as real," "cast HEXTORAW('000000000000F8FF0000000000000000') as DOUBLE);"; void PrintResult(L_BYTE*Buf,L_BYTE*VarBuf) { L_WORD *pCntArg; P_TYPE Type; L_WORD i; L_CHAR str[100]; L_BYTE *ptr; L_BYTE *ptr1; L_BYTE *ptr2; pCntArg = (L_WORD *) Buf; ptr1 = Buf+sizeof(L_WORD); ptr = ptr1+*pCntArg*sizeof(P_TYPE); VarBuf += 2*sizeof(WORD); for (i = 0; i < *pCntArg; ++i) { if ((L_WORD)VarBuf[i]) sprintf(str, "field %d:< NULL >\n", i + 1); else sprintf(str, "field %d:\n", i + 1); Type = *(P_TYPE*)ptr1; ptr2 = ptr; if ( Type.ntyp == DT_VARCHAR || Type.ntyp == DT_VARBYTE || Type.ntyp == DT_NVARCHAR ) ptr2 += 2; Print_value(str, Type, ptr2); ptr += Type.length; if ( Type.ntyp == DT_VARCHAR || Type.ntyp == DT_VARBYTE || Type.ntyp == DT_NVARCHAR ) ptr += 2; ptr1 += sizeof(P_TYPE); } } void Print_value(L_CHAR*text, P_TYPE Type, L_BYTE*ptr) { L_WORD i; L_CHAR StrBuf[4000]; L_WORD SmallBuf; L_LONG IntBuf; L_REAL RealBuf; L_DOUBLE DblBuf; L_DECIMAL DecBuf; L_DOUBLE NumBuf; printf(text); printf("typ = %d, len = %d ", (L_WORD)Type.ntyp, (L_WORD)Type.length); switch (Type.ntyp) { case DT_CHAR: case DT_VARCHAR: memcpy(StrBuf, ptr, Type.length); StrBuf[Type.length] = 0; printf("value = '%s'",StrBuf); break; case DT_INTEGER: if (Type.length == sizeof(L_WORD)) { memcpy(&SmallBuf, ptr, sizeof(L_WORD)); printf("value = %d", SmallBuf); } else { memcpy(&IntBuf, ptr, sizeof(L_LONG)); printf("value = %ld", IntBuf); } break; case DT_REAL: if (Type.length == sizeof(L_REAL)) { memcpy(&RealBuf, ptr, sizeof(L_REAL)); if (isnan(RealBuf)) printf("value = %4s", RealBuf > 0 ? "nan" : "-nan"); else if (isinf(RealBuf)) printf("value = %4s", RealBuf > 0 ? "inf" : "-inf"); else printf("value = %g", RealBuf); } else { memcpy(&DblBuf, ptr, sizeof(L_DOUBLE)); if (isnan(DblBuf)) printf("value = %4s", DblBuf > 0 ? "nan" : "-nan"); else if (isinf(DblBuf)) printf("value = %4s", DblBuf > 0 ? "inf" : "-inf"); else printf("value = %g", DblBuf); } break; case DT_DATE: memcpy(DecBuf, ptr, sizeof(L_DECIMAL)); TICKTOSTRF(DecBuf, "value = dd.mm.yyyy:hh:mi:ss", StrBuf); printf(StrBuf); break; case DT_DECIMAL: memcpy(DecBuf, ptr, sizeof(L_DECIMAL)); DecToDbl(DecBuf, &NumBuf); printf("value = %g", NumBuf); break; case DT_BYTE: case DT_VARBYTE: case DT_NCHAR: case DT_NVARCHAR: printf("value = ' "); for (i = 0; i < Type.length; ++i) printf("%2x ", (L_WORD) ptr[i]); printf(" ' "); break; case DT_BLOB: printf("@:BLOB:@"); break; case DT_EXTFILE: printf("@:EXTFILE:@"); break; case DT_BOOL: { byte qqq = 0; memcpy(&qqq, ptr, 1); if (qqq) printf("value = < TRUE > "); else printf("value = < FALSE > "); } break; } printf("\n"); } void main() { TCBL CBLconnect; L_CHAR Name_Pass[] = "SYSTEM/MANAGER8"; L_CHAR Node[] = " "; L_WORD Priority = 0; L_LONG PrzExe = M_EXCLUSIVE | Q_ENCODE | M_SPEC; L_LONG Err; L_CHAR Query[] = "select * from test;"; L_CHAR QueryNaN[] = "select c3,c8 from test where c3 is nan or c8 is nan;"; L_BYTE Buf[4096]; L_BYTE VarBuf[20]; Err=LinterOPEN(&CBLconnect, Name_Pass, Node,Priority, PrzExe); if (Err != NORMAL) PrintError(&CBLconnect); printf("Connect to RDBMS Linter\n"); Err= LinterNotSelect(&CBLconnect, Query_Create_Table); if (Err != NORMAL) PrintError(&CBLconnect); Err= LinterNotSelect(&CBLconnect, Query_Insert_Table); if (Err != NORMAL) PrintError(&CBLconnect); Err= LinterNotSelect(&CBLconnect, Query_Insert_Table1); if (Err != NORMAL) PrintError(&CBLconnect); Err=LinterSLCT(&CBLconnect, PrzExe, Query, Buf,sizeof(Buf), VarBuf); if (Err != NORMAL) PrintError(&CBLconnect); else { printf("First Selected Row:\n"); PrintResult(Buf,VarBuf); } Err=LinterGETL(&CBLconnect, Buf,sizeof(Buf), VarBuf); if (Err != NORMAL) PrintError(&CBLconnect); else { printf("\nLast Selected Row:\n"); PrintResult(Buf,VarBuf); } Err= LinterNotSelect(&CBLconnect, Query_InsNaN_Table); if (Err != NORMAL) PrintError(&CBLconnect); Err= LinterNotSelect(&CBLconnect, Query_InsNaN1_Table); if (Err != NORMAL) PrintError(&CBLconnect); Err= LinterNotSelect(&CBLconnect, Query_InsNaN2_Table); if (Err != NORMAL) PrintError(&CBLconnect); Err=LinterSLCT(&CBLconnect, PrzExe, QueryNaN, Buf,sizeof(Buf), VarBuf); if (Err != NORMAL) PrintError(&CBLconnect); else { printf("\nFirst Selected NaN values:\n"); PrintResult(Buf,VarBuf); } Err=LinterGETN(&CBLconnect, Buf,sizeof(Buf), VarBuf); if (Err != NORMAL) PrintError(&CBLconnect); else { printf("Next Selected NaN values:\n"); PrintResult(Buf,VarBuf); } Err=LinterGETL(&CBLconnect, Buf,sizeof(Buf), VarBuf); if (Err != NORMAL) PrintError(&CBLconnect); else { printf("Last Selected NaN values:\n"); PrintResult(Buf,VarBuf); } printf("End Example\n"); }
Результаты выполнения примера.
Connect to RDBMS Linter First Selected Row: field 1:< NULL > typ = 1, len = 10 value = ' ' field 2:< NULL > typ = 2, len = 4 value = 0 field 3:< NULL > typ = 3, len = 4 value = 0 field 4:< NULL > typ = 4, len = 16 VALUE = 00.00.0000:00:00:00 field 5:< NULL > typ = 5, len = 16 value = 0 field 6:< NULL > typ = 6, len = 10 value = ' 0 0 0 0 0 0 0 0 0 0 ' field 7:< NULL > typ = 2, len = 2 value = 0 field 8:< NULL > typ = 3, len = 8 value = 0 field 9:< NULL > typ = 2, len = 8 value = 0 field 10:< NULL > typ = 8, len = 10 value = '' field 11:< NULL > typ = 9, len = 10 value = ' 0 0 0 0 0 0 0 0 0 0 ' field 12:< NULL > typ = 10, len = 1 value = < FALSE > field 13:< NULL > typ = 11, len = 20 value = ' 20 0 20 0 20 0 20 0 20 0 20 0 20 0 20 0 20 0 20 0 ' field 14:< NULL > typ = 12, len = 20 value = ' 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ' field 15: typ = 7, len = 24 @:BLOB:@ field 16:< NULL > typ = 13, len = 522 @:EXTFILE:@ Last Selected Row: field 1: typ = 1, len = 10 value = 'azzabyybcc' field 2: typ = 2, len = 4 value = 12 field 3: typ = 3, len = 4 value = -12.3457 field 4: typ = 4, len = 16 VALUE = 01.12.1998:00:00:00 field 5: typ = 5, len = 16 value = 12.34 field 6: typ = 6, len = 10 value = ' ff fe fd fc fb fa f9 f8 f7 f6 ' field 7: typ = 2, len = 2 value = 30000 field 8: typ = 3, len = 8 value = 30.01 field 9: typ = 2, len = 8 value = 182834584 field 10: typ = 8, len = 10 value = 'azzabyybcc' field 11: typ = 9, len = 10 value = ' ff fe fd fc fb fa f9 f8 f7 f6 ' field 12: typ = 10, len = 1 value = < TRUE > field 13: typ = 11, len = 20 value = ' 30 4 31 4 32 4 33 4 34 4 35 4 36 4 20 0 20 0 20 0 ' field 14: typ = 12, len = 20 value = ' 61 0 62 0 63 0 64 0 65 0 66 0 67 0 0 0 0 0 0 0 ' field 15: typ = 7, len = 24 @:BLOB:@ field 16: typ = 13, len = 522 @:EXTFILE:@ First Selected NaN values: field 1: typ = 3, len = 4 value = inf field 2: typ = 3, len = 8 value = inf Next Selected NaN values: field 1: typ = 3, len = 4 value = -inf field 2: typ = 3, len = 8 value = -inf Last Selected NaN values: field 1: typ = 3, len = 4 value = -nan field 2: typ = 3, len = 8 value = -nan End Example