简体   繁体   中英

Implementing odbc wrapper for Sql server. Reading database data as characters or asking driver to convert the data to C type

I have written a database wrapper using odbc to communicate with sql server database. It is working but how i am doing is I am reading all the data types as characters(number of characters specified while binding the column using SQLBindCol) and changing the returned characters to the required datatype in my application.

I know this method is not very efficient as i am converting the returned characters every time to the required datatype in my application, i can imagine this would take an extra time for conversion.

I see the microsoft reference for SQLBindCol stating

When it is retrieving data from the data source with SQLFetch, SQLFetchScroll, SQLBulkOperations, or SQLSetPos, the driver converts the data to this type

which is what i need and i think which will be efficient compared to my code (reading everything as characters.)

sqlbindcol sqlfetch

Below is the order of ODBC API Function calls

  • SQLAllocHandle (to allocate environment handle)
  • SQLSetEnvAttr
  • SQLAllocHandle (to allocate database handle)
  • SQLDriverConnect
  • SQLAllocHandle (to allocate statement handle)
  • SQLExecDirect
  • SQLBindCol
  • SQLFetch.

Every time when I bind the column, I am specifying, TargetType as sql_char and the number of characters to be pushed to the application buffer (*void) when sqlfetch is called.

When I want to read the data which is a big string (for example xml data) and of unknown size, this method is not workable.

I want to know if I read the all the datatypes as characters like how i did? How to read all the data in the returned result column without specifying the number characters to be pushed into buffer?

I read from the documents we can ask the driver to do the conversion to the specified C type in SQLBindCol. How to achieve this? My structure to store the column information is

struct ColValInfo
{
    ColValInfo(): pValue(0){}

    SQLPOINTER pValue; // typedef void * SQLPOINTER;
    SQLINTEGER StrLen_or_Ind; // typedef long  SQLINTEGER;
};

pValue is a void pointer. if driver want to do the conversion and return the data to pValue. what all the necessary things to be done.

I think you are missing a call to SQLDescribeCol before SQLBindCol call.

It will both give you the column type and the column size. You will then allocate your buffers accordingly using a C type corresponding to the SQL type of the column and will not convert any data.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM