[freetds] a question about RPC

=?gb2312?B?wO60usDX?= lichunlei at kingsoft.com
Fri Feb 17 00:27:25 EST 2006


hi£º

   According to your suggestion , i programmed a fucntion which use ct_param to transfer three parameters to a stored procedure .  i need your help to check if the programme could work and arrive at the result .  and  ,i just need a return code  ,not any return parmeter. 

a doubt about ct_param(cmd, datafmt, data, datalen, indicator) is that i donot know how to fill in the fourth arg of datalen if the parameter is  CS_CHAR_TYPE . 


struct LAddNewCardUser_t
{
 char                  username[32]; 
 char                  password[64];     
 int                   userip;       
    int                nRet;      
};
typedef struct AddNewCardUser_t *LAddNewCardUser_t;
LAddNewCardUser valIn;

/////////////////////////////////////////////////////////////////////////////

    memset(&datafmt, 0, sizeof (datafmt));
    strcpy(datafmt.name, "@username");
    datafmt.namelen = CS_NULLTERM;
    datafmt.datatype = CS_CHAR_TYPE;
    datafmt.maxlength = EX_MAXSTRINGLEN;
    datafmt.status = CS_INPUTVALUE;
    datafmt.locale = NULL;
    if ((retcode = ct_param(cmd, &datafmt, 
         (CS_VOID *)valIn->username,datalen, 0) != CS_SUCCEED)  return CS_FAIL;

/////////////////////////////////////////////////////////////////////////////////



FUNCTION :

static inline CS_RETCODE run_rpc_command(CS_COMMAND * cmd, LAddNewCardUser_t valIn,const char *rpcName )
{
 CS_RETCODE ret, results_ret;
 CS_INT result_type,retcode;
 CS_DATAFMT datafmt;
 CS_DATAFMT outdatafmt;
 CS_INT datalength;
 int num_cols;
 CS_SMALLINT ind;
 CS_INT count, row_count = 0;
 
 if (cmd == NULL) return CS_FAIL;
 if (ct_command(cmd, CS_RPC_CMD, rpcName, CS_NULLTERM, CS_NO_RECOMPILE) != CS_SUCCEED) return CS_FAIL;


 memset(&datafmt, 0, sizeof (datafmt));
 strcpy(datafmt.name, "@username");
    datafmt.namelen = CS_NULLTERM;
    datafmt.datatype = CS_CHAR_TYPE;
    datafmt.maxlength = EX_MAXSTRINGLEN;
    datafmt.status = CS_INPUTVALUE;
    datafmt.locale = NULL;
    if ((retcode = ct_param(cmd, &datafmt, 
         (CS_VOID *)valIn->username,32, 0) != CS_SUCCEED)  return CS_FAIL;

 strcpy(datafmt.name, "@password");
    datafmt.namelen = CS_NULLTERM;
    datafmt.datatype = CS_CHAR_TYPE;
    ddatafmt.maxlength = EX_MAXSTRINGLEN;
    datafmt.status = CS_INPUTVALUE;
    datafmt.locale = NULL;
    if ((retcode = ct_param(cmd, &datafmt, 
         (CS_VOID *)valIn->password,64, 0) != CS_SUCCEED)  return CS_FAIL;

 strcpy(datafmt.name, "@userip");
    datafmt.namelen = CS_NULLTERM;
    datafmt.datatype = CS_INT_TYPE;
    datafmt.maxlength = CS_UNUSED;
    datafmt.status = CS_INPUTVALUE;
    datafmt.locale = NULL;
    if ((retcode = ct_param(cmd, &datafmt, 
         (CS_VOID *)&valIn->userip,CS_SIZEOF(CS_INT), 0) != CS_SUCCEED)  return CS_FAIL;

 if (ct_send(cmd) != CS_SUCCEED) return CS_FAIL;

 while ((ret = ct_results(cmd, &res_type)) == CS_SUCCEED) 
 {

  switch ((int) res_type) 
  {
  case CS_CMD_SUCCEED:
   /*
    * This means no rows were returned.
    */
   break;

  case CS_CMD_DONE:
   /*
    * Done with result set.
    */
   break;

  case CS_CMD_FAIL:
   /*
    * The server encountered an error while
    * processing our command.
    */
 
   return E_NORMAL;
  /*
   *   case CS_ROW_RESULT:
        break;
   *   case CS_PARAM_RESULT:
         break;
   */
  case CS_STATUS_RESULT:

   ret = ct_res_info(cmd, CS_NUMDATA, &num_cols, CS_UNUSED, NULL);
   if (ret != CS_SUCCEED) {
    return CS_FAIL;
   }
   if (num_cols <= 0) {
    return CS_FAIL;
   }
   outdatafmt.count = 1;  //ÿ´Î·µ»ØÒ»ÐмǼ
   outdatafmt.format = CS_FMT_UNUSED;
   outdatafmt.datatype = CS_INT_TYPE;
   if (ct_describe(cmd, 1, &outdatafmt) != CS_SUCCEED)  return CS_FAIL;
   if (ct_bind(cmd, 1, &outdatafmt, &valIn->nRet, &datalength, &ind) != CS_SUCCEED) return CS_FAIL;

   count = 0;
   while (((ret = ct_fetch(cmd, CS_UNUSED, CS_UNUSED, CS_UNUSED, &count)) == CS_SUCCEED) || (ret == CS_ROW_FAIL)) 
   {
    row_count += count;
    if (ret == CS_ROW_FAIL) 
     return CS_FAIL;  
    count = 0;
   }

   switch ((int) ret) 
   {
   case CS_END_DATA:
    break;
   case CS_FAIL:
   default:
    return CS_FAIL;
   }

  default:
   /*
    * We got something unexpected.
    */
   return CS_FAIL;
  }
 }
 if(row_count != 1)
  return E_PROCEDURE;

 switch ( (int) results_ret ) 
 {
 case CS_END_RESULTS:
  break;
 case CS_FAIL:
 default:
  return CS_FAIL;
 }

 return CS_SUCCEED;
}
  
  


More information about the FreeTDS mailing list