2008-09-17 8 views
1

J'essaie d'utiliser SQLBindParameter pour préparer mon pilote pour l'entrée via SQLPutData. Le champ de la base de données est un champ TEXT. Ma fonction est basée sur l'exemple de MS ici: http://msdn.microsoft.com/en-us/library/ms713824(VS.85).aspx.SQLBindParameter pour préparer SQLPutData en utilisant C++ et SQL Native Client

J'ai installé l'environnement, a fait la connexion, et préparé ma déclaration avec succès, mais quand je l'appelle SQLBindParam (en utilisant le code ci-dessous), il échoue régulièrement des rapports: [Microsoft][SQL Native Client]Invalid precision value

int col_num = 1; 
SQLINTEGER length = very_long_string.length(); 
retcode = SQLBindParameter(StatementHandle, 
      col_num, 
      SQL_PARAM_INPUT, 
      SQL_C_BINARY, 
      SQL_LONGVARBINARY, 
      NULL, 
      NULL,    
      (SQLPOINTER) col_num,  
      NULL,     
      &length); 

Le repose ci-dessus sur le conducteur utilisez le retour "N" pour le type d'information SQL_NEED_LONG_DATA_LEN dans SQLGetInfo. Mon chauffeur retourne "Y". Comment lier pour que je puisse utiliser SQLPutData?

+0

l'exemple MSDN casse à chaque fois, je continue mes havnt appris à travailler :(- – NTDLS

Répondre

2

Bien qu'il ne semble pas comme le code exemple de la documentation, j'ai trouvé la solution suivante pour travailler pour ce que je suis en train d'accomplir. Merci à gbjbaanb de m'avoir fait retester mes combinaisons d'entrées à SQLBindParameter.

SQLINTEGER length; 
    RETCODE retcode = SQLBindParameter(StatementHandle, 
     col_num,  // position of the parameter in the query 
     SQL_PARAM_INPUT, 
     SQL_C_CHAR, 
     SQL_VARCHAR, 
     data_length,  // size of our data 
     NULL,    // decimal precision: not used our data types 
     &my_string,   // SQLParamData will return this value later to indicate what data it's looking for so let's pass in the address of our std::string 
     data_length, 
     &length);   // it needs a length buffer 

    // length in the following operation must still exist when SQLExecDirect or SQLExecute is called 
    // in my code, I used a pointer on the heap for this. 
    length = SQL_LEN_DATA_AT_EXEC(data_length); 

Après une instruction est exécutée, vous pouvez utiliser SQLParamData pour déterminer quelles données SQL vous veut l'envoyer comme suit:

std::string* my_string; 
    // set string pointer to value given to SQLBindParameter 
    retcode = SQLParamData(StatementHandle, (SQLPOINTER*) &my_string); 

Enfin, utilisez SQLPutData pour envoyer le contenu de votre chaîne à SQL :

// send data in chunks until everything is sent 
    SQLINTEGER len; 
    for (int i(0); i < my_string->length(); i += CHUNK_SIZE) 
    { 
     std::string substr = my_string->substr(i, CHUNK_SIZE); 

     len = substr.length(); 

     retcode = SQLPutData(StatementHandle, (SQLPOINTER) substr.c_str(), len); 
    } 
+0

+1 pour le commentaire « longueur dans l'opération suivante doit toujours exister lorsque SQLExecDirect ou SQLE xecute s'appelle ". Comme ODBC semble optimiser en envoyant les résultats des appels Bind et Execute ensemble, j'ai rencontré quelques erreurs de portée en cours de route. – rstackhouse

Questions connexes