Skip to Content.
Sympa Menu

freetds - RE: [freetds] Status: bcp

freetds AT lists.ibiblio.org

Subject: FreeTDS Development Group

List archive

Chronological Thread  
  • From: "Thompson, Bill D (London)" <bill_d_thompson AT ml.com>
  • To: "'FreeTDS Development Group'" <freetds AT lists.ibiblio.org>
  • Subject: RE: [freetds] Status: bcp
  • Date: Thu, 18 Dec 2003 10:53:24 -0000

Hey James,

Well I've solved the issue that I was getting with bcp_sendrow() /
bcp_batch() / bcp_done()

Hopefully this will be the cause of your woes as well.

If not, at least I've proved there's nothing generically wrong with this
functionality.

Here's the patch. It's not what I expected at all... :-)

bcp_batch(DBPROCESS * dbproc)
{
TDSSOCKET *tds = dbproc->tds_socket;
int rows_copied = 0;

if (dbproc->bcp.direction == 0) {
_bcp_err_handler(dbproc, SYBEBCPI);
return -1;
}

tds_flush_packet(tds);

+ tds->state = TDS_QUERYING;

if (tds_process_simple_query(tds) != TDS_SUCCEED)
return FAIL;
rows_copied = tds->rows_affected;

_bcp_start_new_batch(dbproc);


return (rows_copied);
}

/* end the transfer of data from program variables */

DBINT
bcp_done(DBPROCESS * dbproc)
{
TDSSOCKET *tds = dbproc->tds_socket;
int rows_copied = -1;

if (dbproc->bcp.direction == 0) {
_bcp_err_handler(dbproc, SYBEBCPI);
return -1;
}
tds_flush_packet(tds);

+ tds->state = TDS_QUERYING;

if (tds_process_simple_query(tds) != TDS_SUCCEED)
return FAIL;
rows_copied = tds->rows_affected;

_bcp_clear_storage(dbproc);

return (rows_copied);



HTH,

Bill




> -----Original Message-----
> From: Thompson, Bill D (London)
> Sent: 18 December 2003 10:10
> To: 'FreeTDS Development Group'
> Subject: RE: [freetds] Status: bcp
>
> Houston,
>
> we DO have a problem, but I can reproduce here.
> I'm working on it....
>
> Bill
>
> > -----Original Message-----
> > From: Thompson, Bill D (London)
> > Sent: 18 December 2003 09:32
> > To: 'FreeTDS Development Group'
> > Subject: RE: [freetds] Status: bcp
> >
> > James,
> >
> > STOP! STOP!
> >
> > let me run some tests on bcp_sendrow() and see if there's a generic
> > problem.
> >
> > your understanding is not complete.
> >
> > bcp_exec and bcp_sendrow work essentially the same way, with one
> > difference.
> > bcp_exec reads data from a file, whereas bcp_sendrow gets the data from
> > your
> > bcp_bind()-ed host variables.
> > Thereafter they should use the same code.
> >
> > the "insert bulk" statement is sent in both cases, - It's key to the bcp
> > conversation on SQL server.
> > It (and the metadata token that follows it) are sent when a new bcp
> > operation is started or after bcp_batch() is called to "commit" a buch
> of
> > previously sent data.
> >
> > see this code in bcp_sendrow():
> >
> >
> > /* The first time sendrow is called after bcp_init, */
> > /* there is a certain amount of initialisation to be */
> > /* done... */
> >
> > if (!(dbproc->sendrow_init)) {
> >
> > /* first call the start_copy function, which will */
> > /* retrieve details of the database table columns */
> >
> > if (_bcp_start_copy_in(dbproc) == FAIL)
> > return (FAIL);
> >
> > /* set packet type to send bulk data */
> > tds->out_flag = 0x07;
> >
> > if (IS_TDS7_PLUS(tds)) {
> > _bcp_send_colmetadata(dbproc);
> > }
> >
> > dbproc->sendrow_init = 1;
> >
> > }
> >
> >
> > bcp_batch() says "I'm done" , sends the packet, and then starts a new
> > "transaction" (a new INSERT BULK statement and metadata).
> >
> >
> > There is a problem with tds7_put_bcpcol(), which is called to construct
> > the
> > wire data for each column. here's the code:
> >
> > if (bcpcol->data_size == 0) {
> > if (!bcpcol->db_nullable) {
> > /* too bad if the column is not nullable */
> > return TDS_FAIL;
> > }
> >
> > and here's how tds7_put_bcpcol is called from bcp_sendrow:
> >
> > if (_bcp_get_prog_data(dbproc) == SUCCEED) {
> >
> > if (IS_TDS7_PLUS(tds)) {
> > tds_put_byte(tds, row_token); /* 0xd1 */
> >
> > for (i = 0; i < dbproc->bcp.db_colcount; i++) {
> >
> > /* send the data for each column */
> > ret = tds7_put_bcpcol(tds, dbproc->bcp.db_columns[i]);
> >
> > if (ret == TDS_FAIL) {
> > _bcp_err_handler(dbproc, SYBEBCNN);
> > }
> >
> > }
> > return SUCCEED;
> >
> > If the error condition is hit in tds7_put_bcpcol a BAD ROW will be
> > constructed (the bad column having neen nissed out....)
> >
> >
> >
> > HTH,
> >
> >
> > Bill
> >
> >
> >
> > > -----Original Message-----
> > > From: James K. Lowden [SMTP:jklowden AT schemamania.org]
> > > Sent: 18 December 2003 05:22
> > > To: TDS Development Group
> > > Subject: [freetds] Status: bcp
> > >
> > > I haven't been able to bcp from host variables using current FreeTDS.
> > In
> > > comparing my home-grown application to freebcp, it became clear why
> > > freebcp works and mine doesn't. Or, at least, it became clear how
> > they're
> > > different.
> > >
> > > freebcp relies on bcp_exec(), which in turn is written directly to
> > libtds.
> > >
> > >
> > > My application uses bcp_bind() and bcp_sendrow(). Apparently,
> > > bcp_sendrow() causes the "insert bulk" statement (or the row metadata;
> > the
> > > dump is at the office) to be sent. This is not what the server
> expects,
> > > and the session is quickly terminated.
> > >
> > > AIUI, bcp_sendrow() shouldn't have any effect on the packet. It only
> > > means, OK, I'm done, that's it for this row. db-lib reads the bound
> > host
> > > variable buffers, constructs a row image, and feeds it to the regular
> > > packetizer. As rows are fill the packets, they're sent (with the
> > > more_date indicator). The only short packet would be at a bcp_batch()
> > > boundary.
> > >
> > > If I have any of that wrong, please stop me before I code again....
> > >
> > > I'm writing a bcp unit test I'll use to debug the problem.
> > >
> > > --jkl
> > > _______________________________________________
> > > FreeTDS mailing list
> > > FreeTDS AT lists.ibiblio.org
> > > http://lists.ibiblio.org/mailman/listinfo/freetds
> >
> > _______________________________________________
> > FreeTDS mailing list
> > FreeTDS AT lists.ibiblio.org
> > http://lists.ibiblio.org/mailman/listinfo/freetds
>
> _______________________________________________
> FreeTDS mailing list
> FreeTDS AT lists.ibiblio.org
> http://lists.ibiblio.org/mailman/listinfo/freetds





Archive powered by MHonArc 2.6.24.

Top of Page