win32all odbc/MS SQLServer/bigint

M.-A. Lemburg mal at
Mon Apr 14 16:53:01 CEST 2003

Bjorn Pettersen wrote:
>>From: M.-A. Lemburg [mailto:mal at] 
>>Sure, but __int64 is only available in VC C++ AFAIK. Many
>>compilers have a "long long" type which could be used, but
>>then again, how do you know whether the ODBC driver was
>>compiled with the same C type and layout as the application
>>using it ?
> I haven't found a compiler without a long long type, but then I haven't
> checked e.g. the Palm or Cray's, so I'm assuming they're out there :-)
> This isn't a concern for the win32all odbc module of course, but all
> cross platform projects I've seen so far has a #define LONGLONG to
> either long long or __int64 somewhere (with an appropriate comment
> <wink>).

Sure, but the ODBC standard docs only refer to __int64 and
as a result ODBC drivers and managers on other platforms
have to use some other notion of "give me an integer
with at least 64 bits".

Here's an example of what unixODBC does:

#if (ODBCVER >= 0x0300)
#if (SIZEOF_LONG == 8)
#  define ODBCINT64         long
#  define UODBCINT64    unsigned long
#  define ODBCINT64         long long
#  define UODBCINT64    unsigned long long
# else
  * may fail in some cases, but what else can we do ?
struct __bigint_struct
     int             hiword;
     unsigned int    loword;
struct __bigint_struct_u
     unsigned int    hiword;
     unsigned int    loword;
#  define ODBCINT64         struct __bigint_struct
#  define UODBCINT64    struct __bigint_struct_u
# endif
#ifdef ODBCINT64
typedef ODBCINT64       SQLBIGINT;
#ifdef UODBCINT64

This is what the SAP DB ODBC driver uses:

/* the ODBC C types for SQL_C_SBIGINT and SQL_C_UBIGINT */
#if (ODBCVER >= 0x0300)
#if (_MSC_VER >= 900)
#define ODBCINT64       __int64

#if defined(_WIN32) || defined(_WIN64)
#   if defined (BIT64)
#      define   ODBCINT64   long      /* integer (8 byte, signed)   */
#   else
#      define   ODBCINT64   long long     /* integer (8 byte, signed)   */
#   endif
#endif /* UNIX(tm) tested on AIX,DEC,LINUX,HP,SNI and SUN ;-) from sapdb_types.h */

/* If using other compilers, define ODBCINT64 to the
         approriate 64 bit integer type */
#ifdef ODBCINT64
typedef ODBCINT64       SQLBIGINT;
typedef unsigned ODBCINT64      SQLUBIGINT;
#endif  /* ODBCVER >= 0x0300 */

The introduction of Unicode has similar
problems. Unicode on Windows is actually UCS2 (two bytes)
or UTF-16 (depending on the app's view). Now, on other
platforms such as Linux wchar_t has 4 bytes. As a result,
some ODBC drivers use 4 bytes per character on Linux while
other use 2 bytes.

> If you call
>   SQLColAttribute(hstmt, n, SQL_DESC_TYPE, NULL, 0, NULL,
> (SQLPOINTER)&sqlType);
> and sqlType == SQL_BIGINT, that would be a good indication for result
> sets, and if

Right. That's what mxODBC uses.

>   SQLBindParameter(hstmt, num, SQL_PARAM_INPUT,
>                    SQL_C_SBIGINT, SQL_BIGINT, 
>                    sizeof(__int64), 0, 
>                    (void*)val, sizeof(__int64), &m_nullInd);
> returns either SQL_SUCCESS or SQL_SUCCESS_WITH_INFO that ought to be
> good enough for parameters?

Yes, but only if __int64 is available. I suppose that mxODBC
could use __int64 on Windows without any problems...

>>It's one of those MS things again... the half cooked, "works
>>for me" kind of attitude.
> And here I thought it was the "everyone else did it that way, so we'll
> do it different just because we can" attitude <wink>.

The "everyone else" part doesn't fit: MS defines what the ODBC
standard is, not everybody else :-/

Marc-Andre Lemburg

Professional Python Software directly from the Source  (#1, Apr 14 2003)
 >>> Python/Zope Products & Consulting ...
 >>> mxODBC, mxDateTime, mxTextTools ...
EuroPython 2003, Charleroi, Belgium:                        71 days left

More information about the Python-list mailing list