i want use masm+odbc to store some text into the access database. the length of the text item is longer than 256 byte, so i need sqlputdata fuction.
when i searched MSDN, i found one example for me:

#define MAX_DATA_LEN 1024
SQLINTEGER    cbPartID = 0, cbPhotoParam, cbData;
SQLUINTEGER    sPartID;
              szPhotoFile;
SQLPOINTER    pToken, InitValue;
SQLCHAR        Data;
SQLRETURN      retcode;
SQLHSTMT      hstmt;

retcode = SQLPrepare(hstmt,
        "INSERT INTO PICTURES (PARTID, PICTURE) VALUES
        (?, ?)", SQL_NTS);
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {

  /* Bind the parameters. For parameter 2, pass */
  /* the parameter number in ParameterValuePtr instead of a buffer */   
  /* address. */

  SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_ULONG,
                  SQL_INTEGER, 0, 0, &sPartID, 0, &cbPartID);
  SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT,
                  SQL_C_BINARY, SQL_LONGVARBINARY,
                  0, 0, (SQLPOINTER) 2, 0, &cbPhotoParam);

  /* Set values so data for parameter 2 will be */
  /* passed at execution. Note that the length parameter in */
  /* the macro SQL_LEN_DATA_AT_EXEC is 0. This assumes that */
  /* the driver returns "N" for the SQL_NEED_LONG_DATA_LEN */
  /* information type in SQLGetInfo. */

  cbPhotoParam = SQL_LEN_DATA_AT_EXEC(0);

  sPartID = GetNextID();  /* Get next available employee ID */
                  /* number. */

  retcode = SQLExecute(hstmt);

  /* For data-at-execution parameters, call SQLParamData to */
  /* get the parameter number set by SQLBindParameter. */
  /* Call InitUserData. Call GetUserData and SQLPutData */
  /* repeatedly to get and put all data for the parameter. */
  /* Call SQLParamData to finish processing this parameter */

  while (retcode == SQL_NEED_DATA) {
      retcode = SQLParamData(hstmt, &pToken);
      if (retcode == SQL_NEED_DATA) {
        InitUserData((SQLSMALLINT)pToken, InitValue);
        while (GetUserData(InitValue, (SQLSMALLINT)pToken, Data,
                            &cbData))
            SQLPutData(hstmt, Data, cbData);
      }
  }
}

VOID InitUserData(sParam, InitValue)
SQLPOINTER InitValue;
{
  SQLCHAR szPhotoFile;

  /* Prompt user for bitmap file containing employee */
  /* photo. OpenPhotoFile opens the file and returns the */
  /* file handle. */

  PromptPhotoFileName(szPhotoFile);
  OpenPhotoFile(szPhotoFile, (FILE *)InitValue);
  break;
  }

BOOL GetUserData(InitValue, sParam, Data, cbData)
SQLPOINTER    InitValue;
SQLCHAR *      Data;
SQLINTEGER *  cbData;
BOOL          Done;

{

  /* GetNextPhotoData returns the next piece of photo */
  /* data and the number of bytes of data returned */
  /* (up to MAX_DATA_LEN). */

  Done = GetNextPhotoData((FILE *)InitValue, Data,
        MAX_DATA_LEN, &cbData);
  if (Done) {
      ClosePhotoFile((FILE *)InitValue);
      return (TRUE);
  }
  return (FALSE);
  }


the point is, SQL_LEN_DATA_AT_EXEC is a macro which doesn't exist in Masm's odbc32.inc or any inc. may anybody help me to tell me how to implement this macro in masm? thank you very much.
Posted on 2007-02-03 17:41:26 by zhihui
Found in sqlext.h

#define SQL_LEN_DATA_AT_EXEC_OFFSET  (-100)
#define SQL_LEN_DATA_AT_EXEC(length) (-(length)+SQL_LEN_DATA_AT_EXEC_OFFSET)
Posted on 2007-02-03 19:28:12 by sinsi
thanks, i'll have a try.
Posted on 2007-02-04 00:47:18 by zhihui