Re: dbbind failure on unknown bindtype

[email protected]
Newsgroups gmane.comp.db.tds.freetds
Message-ID <[email protected]>
On Tue, Dec 28, 2010 at 10:47:07PM -0800, Paul Thurston wrote:
> Here's the call sequence (on SQL Server 2008)
> 
> int iColType = dbcoltype(dproc, iColumn + 1);
> // The value is returned as iColType = 56
> 
> RETCODE errCode = dbbind(dbproc, iColumn + 1, iColType, iColType, iColSize, (BYTE*) csBuffer);
> //error message: Unknown bind type passed to DB-Library

Hi Paul,

The above code is wrong and the message correct!  

The third parameter of dbbind() is 

	INT vartype "a description of the binding's data type"
	
It's one of the defined constants I referred you to in sybdb.h.  

In your case, if csBuffer is a DBINT* (and thus iColSize == sizeof(DBINT)) then your vartype should be INTBIND, not SYBINT4.  

I know, it's not very consistent.  

dbbind() tells the library about the program's variables.  db-lib learns about the server's datatypes from the server before the dbbind() call, when the metadata are sent in response to dbresults().  dbbind() tells the library the type, size, and address of the program variable into which the each columns's data are to be copied.  The library then undertakes to place the server's data into the client's variables in the format prescribed by the value of the vartype parameter.  

I think many people confuse client and server datatypes.  We're used to living in an Intel IEEE world, with its way of representing numbers.  But database servers (should) define their types in machine-independent ways.  

http://msdn.microsoft.com/en-us/library/ms187745.aspx

SYBINT4 defines no bit pattern or size.  It refers to a T-SQL datatype that is defined by its *characteristics*, by what values it can hold.  The server is free to invent ways to store & transmit that integer as long as the type continues to behave as advertised.  

INTBIND denotes a C datatype.  It serves the same purpose in dbbind() as a format string of "%d" does in scanf(3).  It's needed because C has no typeof() operator and no function overloading, no built-in way to pass to a function the type of a variable.  

The vendors sometimes foment confusion by conflating the two.  Examples: 

1.  The above link includes "storage" in its description of each type, inviting the reader to think of the type in phyisical terms.  (It also uses the "-2^31 ... to 2^31-1" notation, which is neither mathematical, nor C, nor SQL.  But who really reads that page anyway?)  

2.  Both vendors provide a terrible table in the dbbind() documentation implying that e.g. INTBIND "refers to" SYBINT4.  It could also be used with SYBCHAR, to name just one.  

3.  The type parameters of dbconvert() are taken from the datatype domain, not the vartype domain, despite the fact that the destination at least must refer to a C program variable, not an abstract SQL datatype.  

Power being what it is, the weeds they sow sprout faster than I can root them out!  

(To its credit, btw, Microsoft's ODBC documentation does get it right: SQL_C_SLONG denotes an integer and SQLINTEGER defines one.  No mention of server datatypes when discussing C datatypes.  Cf. http://msdn.microsoft.com/en-us/library/ms714556(v=vs.85).aspx.)  

All said, I think you'll find bsqldb and the db-lib unit tests all work as expected with your server.  dbbind() is fine.  I hope my little sojourn in pedantry helps clarify the issue.  

--jkl
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.