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 09:31:33 -0000

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





Archive powered by MHonArc 2.6.24.

Top of Page