bcp from program variables
Lowden, James K
LowdenJK at bernstein.com
Fri Sep 1 13:38:05 EDT 2000
Specifics are no problem. I apologize, though, because it's hard to be
brief and clear.
>From what little I once knew about TDS and what I've gleaned from the code,
the protocol (inbound) is basically an instruction header followed by a
marked series of fields, where the marker indicates a size. The target
columns (and rows) are applied in order, and any failure to match buffer to
column leads to rejection of anything that follows until a new sequence is
begun. Do I have that right?
I'd like to support batches, and to rewrite _bcp_exec_in in terms of
bcp_sendrow. To do that, (assuming it's possible) I have to understand how
to bracket calls to the TDS. _bcp_exec_in seems to boil down to:
1. out_flag = 0x07
4. look for TDS_DONE_TOKEN
Is there a smaller unit of work than that? IOW, does every chunk of data
sent begin with 0x07 and end with tds_process_end? Is it tds_process_end
that actually commits the rows to the server?
Can I repeat these six steps every 1000 rows, say, or does something have to
Looking at tds/write.c, it looks like the author had in mind a sequence more
2. tds_put_bulk_data (per column per row)
4. look for TDS_DONE_TOKEN
except that tds_put_bulk_data doesn't call tds_put_smallint. Is it broken?
If bcp_sendrow were implemented similar to the above, it would leave the TDS
in a partially written state. A call to dbsqlexec, for instance, before
calling bcp_done would confuse the TDS. That's probably OK, but it should
be possible to cancel a batch dbcancel. I don't know how to cancel flushed
One solution would be to have bcp_sendrow buffer all its data (pending
bcp_batch or bcp_done) without talking to the TDS. If I knew how to
properly construct a TDS buffer of bulk rows, bcp_batch could make just one
call to tds_put_bulk_data, then flush the packet and wait for
TDS_DONE_TOKEN. Is that right, and if so, is there any way besides reading
the tds source code to learn how to do that?
Thanks for any guidance.
From: Brian Bruns [mailto:camber at ais.org]
Sent: September 1, 2000 8:02 AM
To: TDS Development Group
Subject: [freetds] Re: bcp from program variables
I wrote the original bcp stuff under contract, so I did little more than
what was necessary to fulfill that. I'd be happy to try and remember all
the gory details though. If you have specific questions, just post them
on the list and I'll try to answer.
On Thu, 31 Aug 2000, Lowden, James K wrote:
> A perusal of bcp.c told me I should have looked more closely at the code
> before asking for advice on how to use bcp_sendrow et. al. The code is
> obviously stubbed out.
> I've taken a crack at filling in the stubs. There are a couple of errors
> the functional prototypes, and bcp_batch in particular needs tds support.
> Most of the functionality can be borrowed from the existing static
> I've got it working up to the very end, when my version of bcp_done (taken
> directly from the tail of _bcp_exec_in) chokes on an error token (170)
> instead of TDS_DONE_TOKEN. Almost certainly, the problem lies in the
> sequence of calls to the tds layer or in the bindings (always the most
> tedious part of db-lib programming).
> Does anyone there want to see this functionality added to the dblib code?
> Would someone be willing to discuss some of the details off-line? I'm
> hoping to implement the db-lib functions by talking to someone who knows
> tds api. Or who can point me to documents not posted on the web site.
> My lawyer says he's never free but he's always reasonable. Me, just this
> once, I'm offering both. Any takers? It *could* be fun.
You are currently subscribed to freetds as: LowdenJK at bernstein.com
To unsubscribe, forward this message to
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the FreeTDS