Question : MS SQL Stored procedure call problem

I tried to invoke MS SQL Server stored procedure via ODBC. I wanted to both send data-at-execution and get an output parameter. When the data was send by SQLPutData the return value was unavailable

create procedure AddImage
     @pvchName varchar(80),
     @pData image,
     @pnID integer output

C code:
//***********************************************************
long CBergenStoredProcs::AddImage(
      LPCSTR/*[80]*/ pvchName,
      CLongBinary *pData,
      long *pnID)
{
      long              lnRetVal, lnStrLen_or_IndPtr[4];
      SQLRETURN     lSQLres = SQL_SUCCESS;
      int lcbParamSize;

      EnsureStmt();
      DBTRY(SQLPrepare(m_hstmt, SQL_TEXT("{?=call AddImage(?,?,?)}"), SQL_NTS));

      //====================================================
      //      Parametry

      //      RETURN_VALUE
      lnStrLen_or_IndPtr[0] = 0;
      DBTRY(SQLBindParameter(m_hstmt, 1, SQL_PARAM_OUTPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &lnRetVal, sizeof(long), &lnStrLen_or_IndPtr[0]));

      // pvchName
      lnStrLen_or_IndPtr[1] = SQL_TEXTTYPE(pvchName);
      DBTRY(SQLBindParameter(m_hstmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, 80, 0, (LPVOID)pvchName, 80, &lnStrLen_or_IndPtr[1]));

      // pData
      lcbParamSize = pData->m_dwDataLength;
      lnStrLen_or_IndPtr[2] = SP_BLOB(lcbParamSize);
      DBTRY(SQLBindParameter(m_hstmt, 3, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_LONGVARBINARY, lcbParamSize, 0, (LPVOID)pData, lcbParamSize, &lnStrLen_or_IndPtr[2]));

      // pnID
      lnStrLen_or_IndPtr[3] = sizeof(long);
      DBTRY(SQLBindParameter(m_hstmt, 4, SQL_PARAM_OUTPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, (LPVOID)pnID, sizeof(long), &lnStrLen_or_IndPtr[3]));
      //====================================================
      //      Teraz wykonaj
      DBTRY(SQLExecute(m_hstmt));

      if (lSQLres==SQL_NEED_DATA){
            lSQLres = SaveBLOBs();
      }

      while (::SQLMoreResults(m_hstmt)!=SQL_NO_DATA)
            {};


      DBTRY(SQLFreeStmt(m_hstmt, SQL_RESET_PARAMS));

      if (lSQLres!=SQL_SUCCESS)
            AfxThrowDBException(lSQLres, m_pDatabase, m_hstmt);

      return lnRetVal;
};

//**********************************************************************
SQLRETURN CBergenStoredProcs::SaveBLOBs(){
      CLongBinary *lpData;
      SQLRETURN lres = ::SQLParamData(m_hstmt, (SQLPOINTER*)&lpData);
      //======================================================
      while (lres==SQL_NEED_DATA){
            int lcbSize = lpData->m_dwDataLength;
            LPBYTE lpbyData = (LPBYTE)GlobalLock(lpData->m_hData);
            //----------------------------------------------
            if (SQLPutData(m_hstmt, lpbyData, lcbSize)==SQL_ERROR){
                  ::SQLCancel(m_hstmt);
                  return SQL_ERROR;
            }
            //----------------------------------------------
            GlobalUnlock(lpData->m_hData);
            lres = ::SQLParamData(m_hstmt, (SQLPOINTER*)&lpData);
      }
      //======================================================
      return lres;
}

//**************************************************************
#define DBTRY(x)\
      if (lSQLres==SQL_SUCCESS)\
            lSQLres = (::x)

#define SQL_TEXTTYPE(x)\
      ((x)==NULL ? SQL_NULL_DATA : SQL_NTS)

#define SP_BLOB(x)\
      (x==0 ? SQL_NULL_DATA : SQL_LEN_DATA_AT_EXEC(x))

#define SQL_TEXT(x) (SQLCHAR*)(x)
#define DB_TIMESTAMP_PRECISION 23


Unfortunately the return state was SQL_SUCCESS and SQLGetDiagRec didn't return any additional information.

Answer : MS SQL Stored procedure call problem

Hi Pawel_Bujak

Found an example here:

http://doc.ddart.net/mssql/sql2000/html/mdacxml/htm/mdmthappendxvc.htm


The sql server part will still be the same.

Alan
Random Solutions  
 
programming4us programming4us