Não estou familiarizado com a programação ODBC, mas à primeira vista, um problema que posso ver é que você assume que o comprimento dos dados é múltiplo do tamanho do buffer. Mas não é garantido que a última leitura retorne exatamente 500 bytes de dados.
Você deveria escrever algo assim. Pode ser:
string str;
SQLCHAR buf[500];
SQLLEN cbLeft; // #bytes remained
while ((SQL_SUCCEEDED(SQLGetData(StmtHandle,
colnum,
SQL_C_BINARY,
buf,
sizeof(buf),
&cbLeft))))
// ^^^^^^^
{
string data(reinterpret_cast< const char* >(buf),
reinterpret_cast< const char* >(buf)
+ cbLeft);
// ^^^^^^
str = str + data;
Reserve alguns minutos para revisar Usando comprimento /Valores do indicador para verificar como o valor de comprimento/indicador é usado.