Приложение 14. Пример выполнения хранимой процедуры

#include < stdio.h >
#include < stdlib.h >
#include < string.h >
#include "decimals.h"
#include "inter.h"
#include "tick.h"
#include "exlib.h"

static void AnalizeResult(L_BYTE * Buf);
static void show_value(L_CHAR * text, ARGPROC_OUT * ParInfo, L_BYTE * Buf);
static void show_except(L_LONG  except);

#ifndef WINCE
int    main(int argc, const char * argv[])
#else
int    exexec()
#endif
  {
  TCBL    CBL;
  L_BYTE    Buf[8192];
  L_CHAR    Name_Pass[] = "SYSTEM/MANAGER8";
  L_CHAR    Node[] = "        ";
  L_WORD    Priority = 0;
  L_LONG  PrzExe = M_EXCLUSIVE | Q_ENCODE | M_BINARY;
  L_LONG  Err;

  if (argc <  2)
    {
    fprintf(stderr, "Usage: exeproc < proccaller >\n");
    exit(-1);
    }

  memset(&CBL,0,sizeof(TCBL));
  Err = LinterOPEN(&CBL, Name_Pass, Node, Priority, PrzExe);
  if (Err != NORMAL)
    {
    fprintf(stderr, "Error open channel: %d\n", CBL.CodErr);
    exit(-1);
    }

  sprintf((L_CHAR *) Buf, "execute %s;", argv[1]);
  Err = LinterExec(&CBL, (L_CHAR *) Buf, Buf, sizeof(Buf));
  if (Err != NORMAL)
    {
    printf("Linter error code %d\n", Err);
    if (Err == Proc_Raised_Exception)
      show_except(CBL.SysErr);
    }
  if (Err == NORMAL || Err == Proc_Raised_Exception)
    AnalizeResult(Buf);

  LinterCLOS(&CBL);

  return 0;
  }

void    AnalizeResult(L_BYTE * Buf)
  {
  ARGPROC_OUT *ParInfo;
  L_WORD   *pCntArg;
  L_WORD    i;
  L_CHAR    str[100];
  L_WORD    Len;
  L_BYTE   *ptr;

  ParInfo = (ARGPROC_OUT *) Buf;
  show_value("Return value", ParInfo, Buf);
  pCntArg = (L_WORD *) (ParInfo + 1);
  ParInfo = (ARGPROC_OUT *) (pCntArg + 1);

  for (i = 0; i <  *pCntArg; ++i)
    {
    if (ParInfo- >Flags & PARM_FLAG_NAMESENT)
      {
      ptr = Buf + ParInfo- >Value;
      Len = *((L_WORD *) ptr);
      memcpy(str, ptr + sizeof(L_WORD), Len);
      str[Len] = 0;
      ParInfo- >Value += sizeof(L_WORD) + Len;
      }
    else
      sprintf(str, "Parameter number %d value",
	        (int) ParInfo- >Reserv);
    show_value(str, ParInfo, Buf);
    ParInfo++;
    }
  }

void    show_value(L_CHAR * text, ARGPROC_OUT * ParInfo, L_BYTE * Buf)
  {
  L_BYTE   *ptr = Buf + ParInfo- >Value;
  CR_INFO *cr;
  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(" = ");
  if (ParInfo- >Flags & PARM_FLAG_ISNULL)
    printf("NULL");
  else if (ParInfo- >Flags & PARM_FLAG_ISCURSOR)
    {
    cr = (CR_INFO *) ptr;
    printf("Cursor: NMRKAN = %d, RowId = %ld, KOLKOR = %ld,
	       LNBUFKOR = %d, CODERR = %ld\n", cr- >NumChan, cr- >RowId,
           cr- >RowCount, cr- >LnBufRow, cr- >CodErr);
    }
  else
    switch (ParInfo- >Type.ntyp)
      {
      case DT_CHAR:
        memcpy(StrBuf, ptr, ParInfo- >Type.length);
        StrBuf[ParInfo- >Type.length] = 0;
        printf(StrBuf);
        break;
      case DT_INTEGER:
        if (ParInfo- >Type.length == sizeof(L_WORD))
          {
          memcpy(&SmallBuf, ptr, sizeof(L_WORD));
          printf("%d", SmallBuf);
          }
        else
          {
          memcpy(&IntBuf, ptr, sizeof(L_LONG ));
          printf("%ld", IntBuf);
          }
        break;
      case DT_REAL:
        if (ParInfo- >Type.length == sizeof(L_REAL))
          {
          memcpy(&RealBuf, ptr, sizeof(L_REAL));
          printf("%g", RealBuf);
          }
        else
          {
          memcpy(&DblBuf, ptr, sizeof(L_DOUBLE));
          printf("%g", DblBuf);
          }
        break;
      case DT_DATE:
        memcpy(DecBuf, ptr, sizeof(L_DECIMAL));
        TICKTOSTRF(DecBuf, "dd.mm.yyyy:hh:mi:ss", StrBuf);
        printf(StrBuf);
        break;
      case DT_DECIMAL:
        memcpy(DecBuf, ptr, sizeof(L_DECIMAL));
        DecToDbl(DecBuf, &NumBuf);
        printf("%g", NumBuf);
        break;
      case DT_BYTE:
        for (i = 0; i <  ParInfo- >Type.length; ++i)
          printf("%2x ", (L_WORD) ptr[i]);
        break;
      case DT_BLOB:
        printf("@:BLOB:@");
        break;
        }
  printf("\n");
  }

void    show_except(L_LONG  except)
  {
  switch (except)
    {
 case EXC_DIVZERO:
      printf("DIVZERO");
      break;
    case EXC_UNDEFPROC:
      printf("UNDEFPROC");
      break;
    case EXC_BADPARAM:
      printf("BADPARAM");
      break;
    case EXC_BADRETVAL:
      printf("BADRETVAL");
      break;
    case EXC_NULLDATA:
      printf("NULLDATA");
      break;
    case EXC_NOMEM:
      printf("NOMEM");
      break;
    case EXC_BADCURSOR:
      printf("BADCURSOR");
      break;
    case EXC_CURNOTOPEN:
      printf("CURNOTOPEN");
      break;
    case EXC_BADCODE:
      printf("BADCODE");
      break;
    case EXC_TRIGQUERY:
      printf("SQL is still not supported in triggers");
      break;
    case EXC_APPENDNOTSTARTED:
      printf("APPENDNOTSTARTED");
      break;
    case EXC_QUERYWHENAPPEND:
      printf("QUERYWHENAPPEND");
      break;
    case EXC_APPENDACTIVE:
      printf("APPENDACTIVE");
      break;
    case EXC_APPLICATIONERROR:
      printf("APPLICATIONERROR");
      break;
    case EXC_INVTRSTATE:
      printf("Invalid transaction state");
      break;
    default:
      if (except < = EXC_CUSTOM)
        printf("CUSTOM (%d)", -except+EXC_CUSTOM+1);
      else
        printf("%d", except);
      break;
      }
  printf(" exception has been raised\n");
  }