reneyangs 发表于 2008-06-04 23:00

viptbl.ec执行停滞的问题(急)

环境:
Red Hat Linux release 9 (Shrike)
informix ids 9.4
SDK 2.81 UC2

下面是viptbl.ec程序:

int DB_viptbl_read_by_card_no( card_no, _a_data)
char *card_no;
Viptbl *_a_data;

{
      int r = 0;
      $char *Viptbl_card_no;
      $Viptbl p;

      Viptbl_card_no = card_no;
      memset(&p, 0, sizeof(p));
      EXEC SQL SELECT * INTO $p FROM viptbl
               WHEREcard_no = $Viptbl_card_no;

      if(sqlca.sqlcode){

                if(sqlca.sqlcode!=SQLNOTFOUND)
                        SMSlog_print(__FILE__,__LINE__,"error read_by: %d,sqlerrd1:%d",sqlc
a.sqlcode,sqlca.sqlerrd);
                return (sqlca.sqlcode);
      }

      Viptbl_EraseTailSpace(&p);
      memcpy(_a_data, &p, sizeof(p));

      return(r);
}


成功编译后,执行,但是执行到 “EXEC SQL SELECT * INTO $p FROM viptbl” 就停滞了,也不报错,也不执行下去了。
有没有高手帮我看看,是编译的问题,还是我安装informix的问题。

[ 本帖最后由 reneyangs 于 2008-6-5 08:50 编辑 ]

大梦 发表于 2008-06-06 00:57

感觉怪怪的!
应该都是基本问题,给两个例子你参考下吧!
/****************************************************************************
*
*                               IBM INC.
*
*                           PROPRIETARY DATA
*
* Licensed Material - Property Of IBM
*
* "Restricted Materials of IBM"
*
* IBM Informix Client SDK
*
* (c)Copyright IBM Corporation 1997, 2006. All rights reserved.
*
****************************************************************************
*/
/*
   This program prompts the user to enter a SELECT statement
   for the stores_demo database. It processes the statement using dynamic sql
   and system descriptor areas and displays the rows returned by the
   database server.
*/

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
EXEC SQL include sqltypes;
EXEC SQL include locator;
EXEC SQL include datetime;
EXEC SQL include decimal;

#define WARNNOTIFY      1
#define NOWARNNOTIFY      0

#define LCASE(c) (isupper(c) ? tolower(c) : (c))
#define BUFFSZ 256

extern char statement;

EXEC SQL BEGIN DECLARE SECTION;
    loc_t lcat_descr;
    loc_t lcat_picture;
EXEC SQL END DECLARE SECTION;

mint whenexp_chk();

main(mint argc,char *argv[])
{
    int4 ret, getrow();
    short data_found = 0;

    EXEC SQL BEGIN DECLARE SECTION;
      char ans, db_name;
      char name;
      mint sel_cnt, i;
      short type;
    EXEC SQL END DECLARE SECTION;

    printf("DYN_SQL Sample ESQL Program running.\n\n");

    EXEC SQL whenever sqlerror call whenexp_chk;

    if (argc > 2)                /* correct no. of args? */
        {
        printf("\nUsage: %s \nIncorrect no. of argument(s)\n",
          argv);
      printf("\nDYN_SQL Sample Program over.\n\n");
        exit(1);
        }
    strcpy(db_name, "stores_demo");
    if(argc == 2)
        strcpy(db_name, argv);

    sprintf(statement,"CONNECT TO %s",db_name);
    EXEC SQL connect to :db_name;

    printf("Connected to %s\n", db_name);
    ++argv;

    while(1)
        {
        /* prompt for SELECT statement */

        printf("\nEnter a SELECT statement for the %s database",
                     db_name);
        printf("\n\t(e.g.select * from customer;)\n");
        printf("\tOR a ';' to terminate program:\n>> ");
        if(!getans(ans, BUFFSZ))
          continue;
        if(*ans == ';')
          {
            strcpy(statement, "DISCONNECT");
            EXEC SQL disconnect current;
            printf("\nDYN_SQL Sample Program over.\n\n");
          exit(1);
          }

        /* prepare statement id */
      printf("\nPreparing statement (%s)...\n", ans);
      strcpy(statement, "PREPARE sel_id");
        EXEC SQL prepare sel_id from :ans;   

        /* declare cursor */
      printf("Declaring cursor 'sel_curs' for SELECT...\n");
      strcpy(statement, "DECLARE sel_curs");
        EXEC SQL declare sel_curs cursor for sel_id;

        /* allocate descriptor area */
      printf("Allocating system-descriptor area...\n");
      strcpy(statement, "ALLOCATE DESCRIPTOR selcat");
        EXEC SQL allocate descriptor 'selcat';   

        /* Ask the database server to describe the statement */
      printf("Describing prepared SELECT...\n");
      strcpy(statement,
            "DESCRIBE sel_id USING SQL DESCRIPTOR selcat");
        EXEC SQL describe sel_id using sql descriptor 'selcat';
        if(SQLCODE != 0)
          {
          printf("** Statement is not a SELECT.\n");
          free_stuff();
            strcpy(statement, "DISCONNECT");
            EXEC SQL disconnect current;
            printf("\nDYN_SQL Sample Program over.\n\n");
          exit(1);
          }

        /* Determine the number of columns in the select list */
      printf("Getting number of described values from ");
      printf("system-descriptor area...\n");
      strcpy(statement, "GET DESCRIPTOR selcat: COUNT field");
        EXEC SQL get descriptor 'selcat' :sel_cnt = COUNT;

      /* open cursor; process select statement */
      printf("Opening cursor 'sel_curs'...\n");
      strcpy(statement, "OPEN sel_curs");
        EXEC SQL open sel_curs;   

        /*
       * The following loop checks whether the cat_picture or
       * cat_descr columns are described in the system descriptor area.
       * If so, it initializes a locator structure to read the blob
       * data into memory and sets the address of the locator structure
       * in the system descriptor area.
       */       

      for(i = 1; i <= sel_cnt; i++)
          {
            strcpy(statement,
                "GET DESCRIPTOR selcat: TYPE, NAME fields");
          EXEC SQL get descriptor 'selcat' VALUE :i
                  :type = TYPE,
                  :name = NAME;
          if(type == SQLTEXT && !strncmp(name, "cat_descr",
               strlen("cat_descr")))
                {
                lcat_descr.loc_loctype = LOCMEMORY;
                lcat_descr.loc_bufsize = -1;
                lcat_descr.loc_oflags = 0;   
                strcpy(statement, "SET DESCRIPTOR selcat: DATA field");
                EXEC SQL set descriptor 'selcat' VALUE :i
                  DATA = :lcat_descr;
                }
          if(type == SQLBYTES && !strncmp(name, "cat_picture",
                     strlen("cat_picture")))
                {
                lcat_picture.loc_loctype = LOCMEMORY;
                lcat_picture.loc_bufsize = -1;
                lcat_picture.loc_oflags = 0;   
                strcpy(statement, "SET DESCRIPTOR selcat: DATA field");
                EXEC SQL set descriptor 'selcat' VALUE :i
                  DATA = :lcat_picture;   
                }
          }
        while(ret = getrow("selcat"))                /* fetch a row */
          {
            data_found = 1;
          if(ret < 0)
                {
                strcpy(statement, "DISCONNECT");
                EXEC SQL disconnect current;
                printf("\nDYN_SQL Sample Program over.\n\n");
                exit(1);
                }
          disp_data(sel_cnt, "selcat"); /* display the data */
          }
      if(!data_found)
            printf("** No matching rows found.\n");
        free_stuff();
        if(!more_to_do())                /* More to do? */
          break;                        /* no, terminate loop */
        }
    exit(0);
}

/* fetch the next row for selected items */

int4 getrow(sysdesc)
EXEC SQL BEGIN DECLARE SECTION;
    PARAMETER char *sysdesc;
EXEC SQL END DECLARE SECTION;
{
    int4 exp_chk();

    sprintf(statement, "FETCH %s", sysdesc);
    EXEC SQL fetch sel_curs using sql descriptor :sysdesc;
    return((exp_chk(statement)) == 100 ? 0 : 1);
}

/*
* This function loads a column into a host variable of the correct
* type and displays the name of the column and the value, unless the
* value is NULL.
*/

disp_data(col_cnt, sysdesc)
mint col_cnt;
EXEC SQL BEGIN DECLARE SECTION;
    PARAMETER char * sysdesc;
EXEC SQL END DECLARE SECTION;
{
    EXEC SQL BEGIN DECLARE SECTION;
      mint int_data, i;
      char *char_data;
      int4 date_data;
      datetime dt_data;
      interval intvl_data;
      decimal dec_data;
      short short_data;
      char name;
      short char_len, type, ind;
    EXEC SQL END DECLARE SECTION;

    int4 size;
    unsigned amount;
    mint x;
    char shdesc, str, *p;

    printf("\n\n");
    /* For each column described in the system descriptor area,
   * determine its data type. Then retrieve the column name and its
   * value, storing the value in a host variable defined for the
   * particular data type. If the column is not NULL, display the
   * name and value.
   */       
    for(i = 1; i <= col_cnt; i++)
        {
      strcpy(statement, "GET DESCRIPTOR: TYPE field");
      EXEC SQL get descriptor :sysdesc VALUE :i
          :type = TYPE;
        switch(type)
          {
          case SQLSERIAL:
          case SQLINT:
                strcpy(statement,
                  "GET DESCRIPTOR: NAME, INDICATOR, DATA fields");
                EXEC SQL get descriptor :sysdesc VALUE :i
                  :name = NAME,
                  :ind = INDICATOR,
                  :int_data = DATA;
                if(ind == -1)
                  printf("\n%.20s: NULL", name);
                else
                  printf("\n%.20s: %d", name, int_data);
                break;
          case SQLSMINT:
                strcpy(statement,
                  "GET DESCRIPTOR: NAME, INDICATOR, DATA fields");
                EXEC SQL get descriptor :sysdesc VALUE :i
                  :name = NAME,
                  :ind = INDICATOR,
                  :short_data = DATA;
                if(ind == -1)
                  printf("\n%.20s: NULL", name);
                else
                  printf("\n%.20s: %d", name, short_data);
                break;
          case SQLDECIMAL:
          case SQLMONEY:
                strcpy(statement,
                  "GET DESCRIPTOR: NAME, INDICATOR, DATA fields");
                EXEC SQL get descriptor :sysdesc VALUE :i
                  :name = NAME,
                  :ind = INDICATOR,
                  :dec_data = DATA;
                if(ind == -1)
                  printf("\n%.20s: NULL", name);
                else
                  {
                  if(type == SQLDECIMAL)
                        rfmtdec(&dec_data, "###,###,###.##", str);
                  else
                        rfmtdec(&dec_data, "$$$,$$$,$$$.$$", str);
                  printf("\n%.20s: %s", name, str);
                  }
                break;
          case SQLDATE:
                strcpy(statement,
                  "GET DESCRIPTOR: NAME, INDICATOR, DATA fields");
                EXEC SQL get descriptor :sysdesc VALUE :i
                     :name = NAME,
                     :ind = INDICATOR,
                     :date_data = DATA;
                if(ind == -1)
                  printf("\n%.20s: NULL", name);
                else
                  {
                  if((x = rfmtdate(date_data, "mmm. dd, yyyy",
                          str)) < 0)
                        printf("\ndisp_data() - DATE - fmt error");
                  else
                            printf("\n%.20s: %s", name, str);
                  }
                break;
          case SQLDTIME:
                strcpy(statement,
                  "GET DESCRIPTOR: NAME, INDICATOR, DATA fields");
                EXEC SQL get descriptor :sysdesc VALUE :i
                  :name = NAME,
                  :ind = INDICATOR,
                  :dt_data = DATA;
                if(ind == -1)
                  printf("\n%.20s: NULL", name);
                else
                  {
                  x = dttofmtasc(&dt_data, str, sizeof(str), 0);
                  printf("\n%.20s: %s", name, str);
                  }
                break;
          case SQLINTERVAL:
                strcpy(statement,
                  "GET DESCRIPTOR: NAME, INDICATOR, DATA fields");
                EXEC SQL get descriptor :sysdesc VALUE :i
                  :name = NAME,
                  :ind = INDICATOR,
                  :intvl_data = DATA;
                if(ind == -1)
                  printf("\n%.20s: NULL", name);
                else
                  {
                  if((x = intofmtasc(&intvl_data, str,
                          sizeof(str),
                            "%3d days, %2H hours, %2M minutes"))
                             < 0)
                        printf("\nINTRVL - fmt error %d", x);
                  else
                        printf("\n%.20s: %s", name, str);
                  }
                break;
          case SQLVCHAR:
          case SQLCHAR:
                strcpy(statement,
                  "GET DESCRIPTOR: LENGTH, NAME fields");
                EXEC SQL get descriptor :sysdesc VALUE :i
                  :char_len = LENGTH,
                     :name = NAME;
                amount = char_len;
                if(char_data = (char *)(malloc(amount + 1)))
                  {
                  strcpy(statement,
                        "GET DESCRIPTOR: NAME, INDICATOR, DATA fields");
                  EXEC SQL get descriptor :sysdesc VALUE :i
                        :char_data = DATA,
                        :ind =INDICATOR;
                  if(ind == -1)
                          printf("\n%.20s: NULL", name);
                  else
                        printf("\n%.20s: %s", name, char_data);       
                  }
                else
                  {       
                  printf("\n%.20s: ", name);
                  printf("Can't display: out of memory");
                  }
                free(char_data);
                break;
          case SQLTEXT:
                strcpy (statement,
                  "GET DESCRIPTOR: NAME, INDICATOR, DATA fields");
                EXEC SQL get descriptor :sysdesc VALUE :i
                        :name = NAME,
                        :ind = INDICATOR,
                        :lcat_descr = DATA;
                size = lcat_descr.loc_size;        /* get size of data */
                printf("\n%.20s: ", name);
                if(ind == -1)
                  {
                  printf("NULL");
                  break;
                  }
                p = lcat_descr.loc_buffer;        /* set p to buf addr */

                /* print buffer 80 characters at a time */
                while(size >= 80)
                  {
                  /* mv from buffer to shdesc */
                  ldchar(p, 80, shdesc);       
                  printf("\n%80s", shdesc);    /* display it */
                  size -= 80;                /* decrement length */
                  p += 80;                /* bump p by 80 */
                  }
                strncpy(shdesc, p, size);
                shdesc = '\0';
                printf("%-s\n", shdesc);        /* dsply last segment */
                break;
          case SQLBYTES:
                strcpy (statement,
                  "GET DESCRIPTOR: NAME, INDICATOR fields");
               EXEC SQL get descriptor :sysdesc VALUE :i
                  :name = NAME,
                  :ind = INDICATOR;
                if(ind == -1)
                  printf("%.20s: NULL", name);
               else
                  {
                  printf("%.20s: ", name);
                  printf("Can't display BYTE type value");
                  }
               break;
          default:
                printf("\nUnexpected data type: %d", type);
                EXEC SQL disconnect current;
                printf("\nDYN_SQL Sample Program over.\n\n");
                exit(1);
          }
        }
    printf("\n");
}

free_stuff()
{

    EXEC SQL free sel_id;        /* free resources for statement */
    EXEC SQL free sel_curs;        /* free resources for cursor */

    /* free system descriptor area */
    EXEC SQL deallocate descriptor 'selcat';
}

/*
* The inpfuncs.c file contains the following functions used in this
* program:
*    more_to_do() - asks the user to enter 'y' or 'n' to indicate
*                  whether to run the main program loop again.
*
*    getans(ans, len) - accepts user input, up to 'len' number of
*               characters and puts it in 'ans'
*/
#include "inpfuncs.c"

/*
* The exp_chk.ec file contains the exception handling functions to
* check the SQLSTATE status variable to see if an error has occurred
* following an SQL statement. If a warning or an error has
* occurred, exp_chk() executes the GET DIAGNOSTICS statement and
* displays the detail for each exception that is returned.
*/
EXEC SQL include exp_chk.ec;

大梦 发表于 2008-06-06 00:57

/****************************************************************************
*
*                               IBM INC.
*
*                           PROPRIETARY DATA
*
* Licensed Material - Property Of IBM
*
* "Restricted Materials of IBM"
*
* IBM Informix Client SDK
*
* (c)Copyright IBM Corporation 1997, 2006. All rights reserved.
*
****************************************************************************
*/
EXEC SQL define SUCCESS 0;
EXEC SQL define WARNING 1;
EXEC SQL define NODATA 100;
EXEC SQL define RTERROR -1;

char statement;

/*
* The sqlstate_err() function checks the SQLSTATE status variable to see
* if an error or warning has occurred following an SQL statement.
*/
int4 sqlstate_err()
{
    int4 err_code = RTERROR;

    if(SQLSTATE == '0') /* trap '00', '01', '02' */
      {
      switch(SQLSTATE)
            {
            case '0': /* success - return 0 */
                err_code = SUCCESS;
                break;
            case '1': /* warning - return 1 */
                err_code = WARNING;
                break;
            case '2': /* end of data - return 100 */
                err_code = NODATA;
                break;
            default: /* error - return SQLCODE */
                break;
            }
      }
    return(err_code);
}


/*
* The disp_sqlstate_err() function executes the GET DIAGNOSTICS
* statement and prints the detail for each exception that is returned.
*/
void disp_sqlstate_err()
{
mint j;

EXEC SQL BEGIN DECLARE SECTION;
    mint exception_count;
    char overflow;
    mint exception_num=1;
    char class_id;
    char subclass_id;
    char message;
    mint messlen;
    char sqlstate_code;
    mint i;
EXEC SQL END DECLARE SECTION;

    printf("---------------------------------");
    printf("-------------------------\n");
    printf("SQLSTATE: %s\n",SQLSTATE);
    printf("SQLCODE: %d\n", SQLCODE);
    printf("\n");

    EXEC SQL get diagnostics :exception_count = NUMBER,
      :overflow = MORE;
    printf("EXCEPTIONS:Number=%d\t", exception_count);
    printf("More? %s\n", overflow);
    for (i = 1; i <= exception_count; i++)
      {
      EXEC SQL get diagnosticsexception :i
            :sqlstate_code = RETURNED_SQLSTATE,
            :class_id = CLASS_ORIGIN, :subclass_id = SUBCLASS_ORIGIN,
            :message = MESSAGE_TEXT, :messlen = MESSAGE_LENGTH;
      printf("- - - - - - - - - - - - - - - - - - - -\n");
      printf("EXCEPTION %d: SQLSTATE=%s\n", i,
            sqlstate_code);
      message = '\0';
      printf("MESSAGE TEXT: %s\n", message);

      j = byleng(class_id, stleng(class_id));
      class_id = '\0';
      printf("CLASS ORIGIN: %s\n",class_id);

      j = byleng(subclass_id, stleng(subclass_id));
      subclass_id = '\0';
      printf("SUBCLASS ORIGIN: %s\n",subclass_id);
      }

    printf("---------------------------------");
    printf("-------------------------\n");
}

void disp_error(char *stmt)
{
    printf("\n********Error encountered in %s********\n",
      stmt);
    disp_sqlstate_err();
}

void disp_warning(stmt)
char *stmt;
{
    printf("\n********Warning encountered in %s********\n",
      stmt);
    disp_sqlstate_err();
}

void disp_exception(char *stmt,int4 sqlerr_code,mint warn_flg)
{
    switch (sqlerr_code)
      {
      case SUCCESS:
      case NODATA:
            break;
      case WARNING:
            if(warn_flg)
                disp_warning(stmt);
            break;
      case RTERROR:
            disp_error(stmt);
            break;
      default:
            printf("\n********INVALID EXCEPTION STATE for %s********\n",
                stmt);
            break;
      }
}

/*
* The exp_chk() function calls sqlstate_err() to check the SQLSTATE
* status variable to see if an error or warning has occurred following
* an SQL statement. If either condition has occurred, exp_chk()
* calls disp_sqlstate_err() to print the detailed error information.
*
* This function handles exceptions as follows:
*   runtime errors - call exit(1)
*   warnings - continue execution, returning "1"
*   success - continue execution, returning "0"
*   Not Found - continue execution, returning "100"
*/
int4 exp_chk(char *stmt,mint warn_flg)
{
    int4 sqlerr_code = SUCCESS;

    sqlerr_code = sqlstate_err();
    disp_exception(stmt, sqlerr_code, warn_flg);

    if(sqlerr_code == RTERROR)   /* Exception is a runtime error */
      {
      /* Exit the program after examining the error */
      printf("********Program terminated*******\n\n");
      exit(1);
      }
    else                        /* Exception is "success", "Not Found",*/
      return(sqlerr_code);    /*or "warning"                     */
}

/*
* The exp_chk2() function calls sqlstate_err() to check the SQLSTATE
* status variable to see if an error or warning has occurred following
* an SQL statement. If either condition has occurred, exp_chk2()
* calls disp_exception() to print the detailed error information.
*
* This function handles exceptions as follows:
*   runtime errors - continue execution, returning SQLCODE (<0)
*   warnings - continue execution, returning one (1)
*   success - continue execution, returning zero (0)
*   Not Found - continue execution, returning 100
*/
int4 exp_chk2(char *stmt,mint warn_flg)
{
    int4 sqlerr_code = SUCCESS;
    int4 sqlcode;

    sqlcode = SQLCODE;/* save SQLCODE in case of error */
    sqlerr_code = sqlstate_err();
    disp_exception(stmt, sqlerr_code, warn_flg);

    if(sqlerr_code == RTERROR)/* if runtime error, return SQLCODE */
      sqlerr_code = sqlcode;

    return(sqlerr_code);
}

/*
* The whenexp_chk() function calls sqlstate_err() to check the SQLSTATE
* status variable to see if an error or warning has occurred following
* an SQL statement. If either condition has occurred, whenerr_chk()
* calls disp_sqlstate_err() to print the detailed error information.
*
* This function is expected to be used with the WHENEVER SQLERROR
* statement: it executes an exit(1) when it encounters a negative
* error code. It also assumes the presence of the "statement" global
* variable, set by the calling program to the name of the statement
* encountering the error.
*/
whenexp_chk()
{
    int4 sqlerr_code = SUCCESS;
    mint disp = 0;

    sqlerr_code = sqlstate_err();

    if(sqlerr_code == WARNING)
      {
      disp = 1;
      printf("\n********Warning encountered in %s********\n",
            statement);
      }
    else
      if(sqlerr_code == RTERROR)
            {
            printf("\n********Error encountered in %s********\n",
                statement);
            disp = 1;
            }
    if(disp)
      disp_sqlstate_err();

    if(sqlerr_code == RTERROR)
      {
      /* Exit the program after examining the error */
      printf("********Program terminated*******\n\n");
      exit(1);
      }
    else
      {
      if(sqlerr_code == WARNING)
            printf("\n********Program execution continues********\n\n");
      return(sqlerr_code);
      }
}
页: [1]
查看完整版本: viptbl.ec执行停滞的问题(急)