jiangwen365 / pypyodbc

A pure Python Cross Platform ODBC interface module
MIT License
179 stars 73 forks source link

ODBC Driver Manager Invalid string or buffer error #31

Open melloajello opened 8 years ago

melloajello commented 8 years ago

I am using pypyodbc from within a specialized called Motionbuilder, and recently I've been getting this strange error:

pypyodbc.Error: (u'HY090', u'[HY090] [Microsoft][ODBC Driver Manager] Invalid string or buffer length')

It doesn't happen every time, only sometimes. Any ideas?

bobim commented 5 years ago

I comment here instead of opening a similar issue, even if it's been opened for years...

Same issue here, happening with 64 bits python 2.7 using 64 bits ODBC driver. On the same platform, 32 bits python using 32 bit ODBC drivers gives no error.

The error happens during the call to SQLBindCol which, after tracing ODBC transactions, receives a negative number for BufferLength (SQLLEN below):

wfastcgi 1d34-15fc EXIT SQLBindCol with return code -1 (SQL_ERROR) HSTMT 0x0000000004B52FE0 UWORD 1 SWORD 1 PTR 0x00000000024E2CB0 SQLLEN -4294967146 SQLLEN * 0x00000000038A4310

  DIAG [HY090] [Microsoft][ODBC Driver Manager] Invalid string or buffer length (0)

The corresponding call in pypyodbc is sitting around line 1728:

ret = ODBC_API.SQLBindCol(self.stmt_h, col_num + 1, target_type, ADDR(alloc_buffer), total_buf_len, ADDR(used_buf_len))

And the arguments passed were ok, especially the buffer length of 150:

STMT 4b52fe0 COL NUM 1 TARGET TYPE 1 ADDR ALLOC BUF 24e2cb0 TOTAL BUF LEN 150 ADDR USED BUF LEN 38a4310

The stack probably have a funny state when calling the API function, hence the negative value for SQLLEN originating from a total_buf_len of 150. Maybe 64 bits ODBC expect 64 bits integers, so modifying the function call to convert total_buf_len to a long integer can help smoothing it a bit:

ret = ODBC_API.SQLBindCol(self.stmt_h, col_num + 1, target_type, ADDR(alloc_buffer), long(total_buf_len), ADDR(used_buf_len))

I don't know if it's the ultimate solution but for my case it looks like the error is gone.