Supplies values for a server command’s input parameters.
CS_RETCODE ct_param(cmd, datafmt, data, datalen, indicator); CS_COMMAND *cmd; CS_DATAFMT *datafmt; CS_VOID *data; CS_INT datalen; CS_SMALLINT indicator;
A pointer to the CS_COMMAND structure managing a client/server operation.
A pointer to a CS_DATAFMT structure that describes the parameter.
For information about how to set these fields for specific uses of ct_param, see “Usage” on page 476.
The address of the parameter data.
There are two ways to indicate a parameter with a null value:
Pass indicator as -1. In this case, data and datalen are ignored.
Pass data as NULL and datalen as 0 or CS_UNUSED.
The length, in bytes, of the parameter data.
If datafmt−>datatype indicates that the parameter is a fixed-length type, datalen is ignored. CS_VARBINARY and CS_VARCHAR are considered to be fixed-length types.
An integer variable used to indicate a parameter with a null value. To indicate a parameter with a null value, pass indicator as -1. If indicator is -1, data and datalen are ignored.
ct_param returns the following values:
Return value |
Meaning |
---|---|
CS_SUCCEED |
The routine completed successfully. |
CS_FAIL |
The routine failed. |
CS_BUSY |
An asynchronous operation is already pending for this connection. See “Asynchronous programming”. |
This code excerpt is from the rpc.c sample program.
/*
** BuildRpcCommand()
**
** Purpose:
** Builds an RPC command but does not send it.
**
*/
CS_STATIC CS_RETCODE
BuildRpcCommand(cmd)
CS_COMMAND *cmd;
{
CS_CONNECTION *connection;
CS_CONTEXT *context;
CS_RETCODE retcode;
CS_DATAFMT datafmt;
CS_DATAFMT srcfmt;
CS_DATAFMT destfmt;
CS_INT intvar;
CS_SMALLINT smallintvar;
CS_FLOAT floatvar;
CS_MONEY moneyvar;
CS_BINARY binaryvar;
char moneystring[10];
char rpc_name[15];
CS_INT destlen;
/*
** Assign values to the variables used for
** parameter passing.
*/
intvar = 2;
smallintvar = 234;
floatvar = 0.12;
binaryvar = (CS_BINARY)0xff;
strcpy(rpc_name, "sample_rpc");
strcpy(moneystring, "300.90");
/*
** Clear and setup the CS_DATAFMT structures used
** to convert datatypes.
*/
memset(&srcfmt, 0, sizeof (CS_DATAFMT));
srcfmt.datatype = CS_CHAR_TYPE;
srcfmt.maxlength = strlen(moneystring);
srcfmt.precision = 5;
srcfmt.scale = 2;
srcfmt.locale = NULL;
memset(&destfmt, 0, sizeof (CS_DATAFMT));
destfmt.datatype = CS_MONEY_TYPE;
destfmt.maxlength = sizeof(CS_MONEY);
destfmt.precision = 5;
destfmt.scale = 2;
destfmt.locale = NULL;
/*
** Convert the string representing the money value
** to a CS_MONEY variable. Since this routine
** does not have the context handle, we use the
** property functions to get it.
*/
if ((retcode = ct_cmd_props(cmd, CS_GET,
CS_PARENT_HANDLE, &connection, CS_UNUSED,
NULL)) != CS_SUCCEED)
...error checking deleted ...
if ((retcode = ct_con_props(connection, CS_GET,
CS_PARENT_HANDLE, &context, CS_UNUSED,
NULL)) != CS_SUCCEED)
...error checking deleted ...
retcode = cs_convert(context, &srcfmt,
(CS_VOID *)moneystring, &destfmt, &moneyvar,
&destlen);
if (retcode != CS_SUCCEED)
...error checking deleted ...
/*
** Initiate the RPC command for our stored
** procedure.
*/
if ((retcode = (cmd, CS_RPC_CMD,
rpc_name, CS_NULLTERM, CS_NO_RECOMPILE)) !=
CS_SUCCEED)
...error checking deleted ...
/*
** Clear and set up the CS_DATAFMT structure, then
** pass each of the parameters for the RPC.
*/
memset(&datafmt, 0, sizeof (datafmt));
strcpy(datafmt.name, "@intparam");
datafmt.namelen = CS_NULLTERM;
datafmt.datatype = CS_INT_TYPE;
datafmt.maxlength = CS_UNUSED;
datafmt.status = CS_INPUTVALUE;
datafmt.locale = NULL;
if ((retcode = ct_param(cmd, &datafmt,
(CS_VOID *)&intvar, sizeof(CS_INT),0))
!= CS_SUCCEED)
...error checking deleted ...
strcpy(datafmt.name, "@sintparam");
datafmt.namelen = CS_NULLTERM;
datafmt.datatype = CS_SMALLINT_TYPE;
datafmt.status = CS_RETURN;
datafmt.locale = NULL;
if ((retcode = ct_param(cmd, &datafmt,
(CS_VOID *)&smallintvar,
sizeof(CS_SMALLINT), 0))
!= CS_SUCCEED)
...error checking deleted ...
strcpy(datafmt.name, "@floatparam");
datafmt.namelen = CS_NULLTERM;
datafmt.datatype = CS_FLOAT_TYPE;
datafmt.status = CS_RETURN;
datafmt.locale = NULL;
if((retcode = ct_param(cmd, &datafmt,
(CS_VOID *)&floatvar,sizeof(CS_FLOAT),0))
!= CS_SUCCEED)
...error checking deleted ...
strcpy(datafmt.name, "@moneyparam");
datafmt.namelen = CS_NULLTERM;
datafmt.datatype = CS_MONEY_TYPE;
datafmt.status = CS_RETURN;
datafmt.locale = NULL;
if((retcode = ct_param(cmd, &datafmt,
(CS_VOID *)&moneyvar, sizeof(CS_MONEY),0))
!= CS_SUCCEED)
...error checking deleted ...
strcpy(datafmt.name, "@dateparam");
datafmt.namelen = CS_NULLTERM;
datafmt.datatype = CS_DATETIME4_TYPE;
datafmt.status = CS_RETURN;
datafmt.locale = NULL;
/*
** The datetime variable is filled in by the RPC
** so pass NULL for the data, 0 for data length,
** and -l for the indicator arguments.
*/
if((retcode = ct_param(cmd, &datafmt, NULL, 0,
-1)) != CS_SUCCEED)
...error checking deleted ...
strcpy(datafmt.name, "@charparam");
datafmt.namelen = CS_NULLTERM;
datafmt.datatype = CS_CHAR_TYPE;
datafmt.maxlength = EX_MAXSTRINGLEN;
datafmt.status = CS_RETURN;
datafmt.locale = NULL;
/*
** The character string variable is filled in by
** the RPC so pass NULL for the data 0 for data
** length, and -l for the indicator arguments.
*/
if((retcode = ct_param(cmd, &datafmt, NULL, 0,
-1)) != CS_SUCCEED)
...error checking deleted ...
strcpy(datafmt.name, "@binaryparam");
datafmt.namelen = CS_NULLTERM;
datafmt.datatype = CS_BINARY_TYPE;
datafmt.maxlength = EX_MAXSTRINGLEN;
datafmt.status = CS_RETURN;
datafmt.locale = NULL;
if((retcode = ct_param(cmd, &datafmt,
(CS_VOID *)&binaryvar,
sizeof(CS_BINARY), 0))
!= CS_SUCCEED)
...error checking deleted ...
return retcode;
}
Table 3-46 summarizes ct_param usage.
Type of command |
Purpose of ct_param call |
datafmt->status is |
*data, datalen are |
---|---|---|---|
Cursor declare |
To identify update columns |
CS_UPDATECOL |
The name of the update column and the name’s length |
Cursor declare |
To define host variable formats |
CS_INPUTVALUE |
NULL and CS_UNUSED |
Cursor open |
To pass parameter values |
CS_INPUTVALUE |
The parameter value and length |
Cursor update |
To pass parameter values |
CS_INPUTVALUE |
The parameter value and length |
Dynamic SQL execute |
To pass parameter values |
CS_INPUTVALUE |
The parameter value and length |
Language |
To pass parameter values |
CS_INPUTVALUE |
The parameter value and length |
Message |
To pass parameter values |
CS_INPUTVALUE |
The parameter value and length |
RPC |
To pass parameter values |
CS_RETURN to pass a return parameter; CS_INPUTVALUE to pass a non-return parameter. |
The parameter value and length |
ct_param supplies parameter values for an initiated command.
Initiating a command is the first step in executing it. Some commands require the application to define input parameters with ct_param or ct_setparam before calling ct_send to send the command to the server. For a description of this feature, see “Resending commands”.
ct_setparam and ct_param perform the same function, with the following exceptions:
ct_param copies the contents of program variables.
ct_setparam copies the address of program variables, and subsequent calls to ct_send read the contents of the variables. ct_setparam allows the application to change parameter values when resending a command.
Calls to ct_param and ct_setparam can be mixed.
An application may need to call ct_param:
To identify update columns for a cursor declare command.
To define host variable formats for a cursor declare command.
To pass input parameter values for a cursor open, cursor update, dynamic SQL execute, language, message, or RPC command.
An application calls ct_command to initiate a language, RPC or message command, calls ct_cursor to initiate a cursor declare or cursor open command, and calls ct_dynamic to initiate a Dynamic SQL execute command.
For specific information about these uses, see the following sections:
Client-Library does not perform any conversion on parameters before passing them to the server. The application must supply parameters in the datatype required by the server. If necessary, the application can call cs_convert to convert parameter values into the required datatype.
Some servers require a client application to identify update columns for a cursor declare command if the cursor is updatable, but not all of the columns are “for update.” Update columns can be used to change values in underlying database tables.
Adaptive Server does not require the application to specify update columns with additional ct_param/ct_setparam calls as described in this section. In fact, Adaptive Server ignores requests to identify update columns as described here. The application must use the Transact-SQL for read only or for update of syntax in the select statement to specify which columns are updatable (see the Adaptive Server Enterprise for a description of this syntax). Depending on its design, an Open Server application may require clients to specify a cursor’s update columns as described in this section.
If all of the cursor’s columns are “for update,” an application does not need to call ct_param to specify them individually.
To identify an update column for a cursor declare command, an application calls ct_param with datafmt−>status as CS_UPDATECOL and *data as the name of the column.
The following table lists the fields in *datafmt that are used when identifying update columns for a cursor declare command:
Field name |
Set to |
---|---|
status |
CS_UPDATECOL |
All other fields are ignored. |
An application needs to define host variable formats for cursor declare commands when the text of the cursor being declared is a SQL string that contains host variables.
To define the format of a host variable, an application calls ct_param with datafmt−>status as CS_INPUTVALUE, datafmt−>datatype as the datatype of the host variable, data as NULL and datalen as CS_UNUSED.
An application defines host variable formats during a cursor declare command but does not pass data values for the variables until cursor open time.
When defining host variable formats, the variables can either be named or unnamed. If one variable is named, all variables must be named. If variables are not named, they are interpreted positionally.
The following table lists the fields in *datafmt that are used when defining host variable formats:
Name |
Set To |
---|---|
name |
The name of the host variable. |
namelen |
The length, in bytes, of name, or 0 to indicate an unnamed parameter. |
datatype |
The datatype of the host variable. All standard Client-Library types are valid except for CS_TEXT_TYPE, CS_UNITEXT_TYPE, CS_IMAGE_TYPE, CS_XML_TYPE, and Client-Library user-defined types. If datatype is CS_VARCHAR_TYPE or CS_VARBINARY_TYPE then data must point to a CS_VARCHAR or CS_VARBINARY structure. |
status |
CS_INPUTVALUE |
All other fields are ignored. |
An application may need to pass input parameter values for:
Client-Library cursor open commands
Client-Library cursor update commands
Dynamic SQL execute commands
Language commands
Message commands
Package commands
RPC commands
When passing input parameter values, parameters can either be named or unnamed. If one parameter is named, all parameters must be named. If parameters are not named, they are interpreted positionally.
In some cases, an application may need to pass a parameter that has a null value. For example, an application might pass parameters with null values to a stored procedure that assigns default values to null input parameters.
There are two ways to indicate a parameter with a null value:
Pass indicator as -1. ct_param ignores data and datalen.
Pass data as NULL and datalen as 0 or CS_UNUSED.
Client-Library cursor open commands require input parameter values when:
The body of the cursor is a SQL text string containing host variables.
The body of the cursor is a stored procedure that requires parameters. In this case, datafmt−>status should be CS_INPUTVALUE.
The cursor is declared on a prepared dynamic SQL statement that contains placeholders (indicated by the ? character).
Client-Library cursor update commands require input parameter values when the SQL text representing the update command contains host variables.
Dynamic SQL execute commands require input parameter values when the prepared statement being executed contains dynamic parameter markers.
Language commands require input parameter values when the text of the language command contains host variables.
Message commands require input parameters values when the message takes parameters.
RPC and package commands require input parameter values when the stored procedure or package being executed takes parameters.
Message, package, and RPC commands can take return parameters, indicated by passing datafmt−>status as CS_RETURN.
A command that takes return parameters may generate a parameter result set that contains the return parameter values. See ct_results for a description of how an application retrieves values from a parameter result set.
The following table lists the fields in *datafmt that are used when passing input parameter values:
Name |
Set to |
---|---|
name |
The name of the parameter. name is ignored for dynamic SQL execute commands. |
namelen |
The length, in bytes, of name, or 0 to indicate an unnamed parameter. namelen is ignored for dynamic SQL execute commands. |
datatype |
The datatype of the input parameter value. All standard Client-Library types are valid except for CS_TEXT_TYPE, CS_UNITEXT_TYPE, CS_IMAGE_TYPE, CS_XML_TYPE, and Client-Library user-defined types. If datatype is CS_VARCHAR_TYPE or CS_VARBINARY_TYPE then data must point to a CS_VARCHAR or CS_VARBINARY structure. |
maxlength |
When passing return parameters for RPC commands, maxlength represents the maximum length, in bytes, of data to be returned for this parameter. maxlength is not used when passing input parameter values for other types of commands. |
status |
CS_RETURN when passing return parameters for RPC commands; otherwise CS_INPUTVALUE. |
All other fields are ignored. |