Skip to Content.
Sympa Menu

freetds - RE: [freetds] stored proc parameters

freetds AT lists.ibiblio.org

Subject: FreeTDS Development Group

List archive

Chronological Thread  
  • From: "ZIGLIO, Frediano, VF-IT" <Frediano.Ziglio AT vodafone.com>
  • To: "FreeTDS Development Group" <freetds AT lists.ibiblio.org>
  • Subject: RE: [freetds] stored proc parameters
  • Date: Fri, 3 Dec 2004 13:57:58 +0100

>
> Josh,
>
> Your technique of passing a NULL pointer as the value
> parameter, to indicate a NULL paremeter is not documented for
> dbrpcparam in either Sybase or SQL Server. That doesn't mean
> it doesn't work, though.
>
> The accepted method of passing a NULL parameter is to set
> datalen to 0 .
>
> The question is: should we implement the undocumented
> technique of passing a NULL parameter or not ?
>
> Bill
>

Try this patch (I changed 0.64)

diff -u -1 -0 -r1.33 rpc.c
--- src/dblib/rpc.c 1 Dec 2004 03:55:13 -0000 1.33
+++ src/dblib/rpc.c 3 Dec 2004 12:55:38 -0000
@@ -178,22 +178,24 @@

/* TODO add other tests for correctness */

/* allocate */
param = (DBREMOTE_PROC_PARAM *)
malloc(sizeof(DBREMOTE_PROC_PARAM));
if (param == NULL)
return FAIL;

if (paramname) {
name = strdup(paramname);
- if (name == NULL)
+ if (name == NULL) {
+ free(param);
return FAIL;
+ }
}

/* initialize */
param->next = (DBREMOTE_PROC_PARAM *) NULL; /* NULL
signifies end of linked list */
param->name = name;
param->status = status;
param->type = type;
param->maxlen = maxlen;
param->datalen = datalen;
param->value = value;
@@ -260,27 +262,32 @@
rpc_clear(dbproc->rpc);
dbproc->rpc = NULL;

return SUCCEED;
}

/**
* Tell the TDSPARAMINFO structure where the data go. This is a kind
of "bind" operation.
*/
static const unsigned char *
-param_row_alloc(TDSPARAMINFO * params, TDSCOLUMN * curcol, void *value,
int size)
+param_row_alloc(TDSPARAMINFO * params, TDSCOLUMN * curcol, int i_col,
void *value, int size)
{
const unsigned char *row = tds_alloc_param_row(params, curcol);

if (!row)
return NULL;
- memcpy(&params->current_row[curcol->column_offset], value,
size);
+
+ if (size <= 0) {
+ tds_set_null(params->current_row, i_col);
+ } else {
+ memcpy(&params->current_row[curcol->column_offset],
value, size);
+ }

return row;
}

/**
* Allocate memory and copy the rpc information into a TDSPARAMINFO
structure.
*/
static TDSPARAMINFO *
param_info_alloc(TDSSOCKET * tds, DBREMOTE_PROC * rpc)
{
@@ -322,25 +329,25 @@
tds_free_param_results(params);
return NULL;
}
pcol->column_size = p->maxlen;

/* actual data */
pcol->column_cur_size = p->datalen;
}
pcol->column_output = p->status;

- prow = param_row_alloc(params, pcol, p->value,
pcol->column_cur_size);
+ prow = param_row_alloc(params, pcol, i, p->value,
pcol->column_cur_size);

if (!prow) {
tds_free_param_results(params);
- fprintf(stderr, "out of memory for rpc row!");
+ tdsdump_log(TDS_DBG_ERROR, "out of memory for
rpc row!");
return NULL;
}

}

return params;

}

/**

freddy77




Archive powered by MHonArc 2.6.24.

Top of Page