Initiate a language, package, RPC, message, or send-data command.
CS_RETCODE ct_command(cmd, type, buffer, buflen, option) CS_COMMAND *cmd; CS_INT type; CS_VOID *buffer; CS_INT buflen; CS_INT option;
A pointer to the CS_COMMAND structure managing a client/server operation.
The type of command to initiate. Table 3-9 lists the symbolic values for type.
A pointer to data space. Table 3-9 lists the datatypes and meanings for *buffer values.
The length, in bytes, of the *buffer data, or CS_UNUSED if *buffer represents a fixed-length or symbolic value.
The option associated with this command.
Language, RPC (remote procedure call), send-data, and send-bulk-data commands take options. For all other types of commands, pass option as CS_UNUSED.
The following table lists the symbolic values for option:
type is |
Value of option |
Meaning |
---|---|---|
CS_LANG_CMD |
CS_MORE |
The text in buffer is only part of the language command to be executed. |
CS_END |
The text in buffer is the last part of the language command to be executed. |
|
CS_UNUSED |
Equivalent to CS_END. |
|
CS_RPC_CMD |
CS_RECOMPILE |
Recompile the stored procedure before executing it. |
CS_NO_RECOMPILE |
Do not recompile the stored procedure before executing it. |
|
CS_UNUSED |
Equivalent to CS_NO_RECOMPILE. |
|
CS_SEND_DATA_CMD |
CS_COLUMN_DATA |
The data will be used for a text or image column update. |
CS_BULK_DATA |
For internal Sybase use only. The data will be used for a bulk copy operation. |
|
CS_SEND_BULK_CMD |
CS_BULK_INIT |
For internal Sybase use only. Initialize a bulk copy operation. |
CS_BULK_CONT |
For internal Sybase use only. Continue a bulk copy operation. |
ct_command returns the following values:
Returns |
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”. |
/*
** ex_execute_cmd()
**
** Type of function:
** example program utility api
**
** Purpose:
** Sends a language command to the server.
*/
CS_RETCODE CS_PUBLIC
ex_execute_cmd(connection, cmdbuf)
CS_CONNECTION *connection;
CS_CHAR *cmdbuf;
{
CS_RETCODE retcode;
CS_INT restype;
CS_COMMAND *cmd;
CS_RETCODE query_code;
/*
** Get a command structure,store the command string in it,
** and send it to the server.
*/
if ((retcode = ct_cmd_alloc(connection, &cmd)) !=
CS_SUCCEED)
{
ex_error("ex_execute_cmd: ct_cmd_alloc() failed");
return retcode;
}
if ((retcode = ct_command(cmd, CS_LANG_CMD, cmdbuf,
CS_NULLTERM, CS_UNUSED)) != CS_SUCCEED)
{
ex_error("ex_execute_cmd: ct_command() failed");
(void)ct_cmd_drop(cmd);
return retcode;
}
/* Now send the command and process the results */
... ct_send, ct_results, and so forth deleted ...
return CS_SUCCEED;
}
This code excerpt is from the exutils.c sample program.
Table 3-9 summarizes ct_command usage.
Value of type |
Command initiated |
buffer is |
buflen is |
---|---|---|---|
CS_LANG_CMD |
A language command |
A pointer to a CS_CHAR array that contains all or part of the language command text. Use the CS_MORE and CS_END options to build the command text in pieces. See Table 3-8 for details. |
The length of the *buffer data or CS_NULLTERM. |
CS_MSG_CMD |
A message command |
A pointer to a CS_INT variable that contains the message ID. |
CS_UNUSED |
CS_PACKAGE_CMD |
A package command |
A pointer to a CS_CHAR array that contains the name of the package. |
The length of the *buffer data or CS_NULLTERM. |
CS_RPC_CMD |
A remote procedure call command |
A pointer to a CS_CHAR array that contains the name of the remote procedure. |
The length of the *buffer data or CS_NULLTERM. |
CS_SEND_DATA_CMD |
A send-data command |
NULL. |
CS_UNUSED. |
CS_SEND_DATA_NOCMD |
A send-data command |
NULL. |
CS_UNUSED. |
CS_SEND_BULK_CMD |
A Sybase internal send-bulk-data command |
A pointer to a CS_CHAR array that contains the database table name. |
The length of the *buffer data or CS_NULLTERM. |
ct_command initiates several types of server commands.
For an overview of Client-Library command types, see Chapter 5, “Choosing Command Types,” in the Open Client Client-Library/C Programmers Guide.
Initiating a command is the first step in sending it to a server. For a client application to execute a server command, Client-Library must convert the command to a symbolic command stream that can be sent to the server. The command stream contains information about the type of the command and the data needed for execution. For example, an RPC command requires a procedure name, the number of parameters, and (if needed) parameter values.
The steps for executing a server command with ct_command are as follows:
Initiate the command by calling ct_command. This step sets up internal structures that are used in building a command stream to send to the server.
Pass parameters for the command (if required) by calling ct_param or ct_setparam once for each parameter that the command requires.
Not all commands require parameters. For example, a remote procedure call command may or may not require parameters, depending on the stored procedure being called.
Send the command to the server by calling ct_send. ct_send writes the symbolic command stream onto the command structure’s parent connection.
Handle the results of the command by calling ct_results repeatedly until it no longer returns CS_SUCCEED. See Chapter 6, “Writing Results-Handling Code,” in the Open Client Client-Library/C Programmers Guide for a discussion of processing results.
ct_command command types other than send-data commands or send-bulk commands can be resent by calling ct_send immediately after the application has processed the results of the previous execution. Client-Library saves the initiated command information in the command structure until the application initiates a new command with ct_command, ct_cursor, ct_dynamic, or ct_sendpassthru. If parameter source variables for the command were specified with ct_setparam, then the application can change the parameter values without calling ct_setparam again. See “Resending commands”.
An application can call ct_cancel with type as CS_CANCEL_ALL to clear a command that has been initiated but not yet sent.
The following rules apply to the use of ct_command:
When a command structure is initiated, an application must either send the initiated command or clear it before a new command can be initiated with ct_command, ct_cursor, ct_dynamic, or ct_sendpassthru.
After sending a command, an application must completely process or cancel all results returned by the command’s execution before initiating a new command on the same command structure.
An application cannot call ct_command to initiate a command on a command structure that is managing a cursor. The application must deallocate the cursor first (or use a different command structure).
Each section below contains information about one of the types of commands that ct_command can initiate.
A language command contains a character string that represents one or more command in a server’s own language. For example, the following language command contains a Transact-SQL command:
ct_command(cmd, CS_LANG_CMD,
"select * from pubs2..authors",
CS_NULLTERM,
CS_UNUSED);
ct_command’s CS_MORE and CS_END option values allow the application to append text to the language buffer. Language command text can be assembled in pieces with consecutive calls.
The language buffer can represent more than one server commands. For example, the following sequence builds a language command containing three Transact-SQL statements:
ct_command(cmd, CS_LANG_CMD,
“select * from pubs2..titles ”,
CS_NULLTERM, CS_MORE);
ct_command(cmd, CS_LANG_CMD,
“select * from pubs2..authors ”,
CS_NULLTERM, CS_MORE);
ct_command(cmd, CS_LANG_CMD,
“select * from pubs2..publishers ”,
CS_NULLTERM, CS_END);
ct_command does not add white space when appending to the command buffer and the space must therefore be specified by the user.
When the CS_UNUSED option is specified, Client-Library requires the application to pass the entire language text in one call to ct_command.
A language command can be in any language, as long as the server to which it is directed can understand it. Adaptive Server Enterprise understands Transact-SQL, but an Open Server application constructed with Server-Library can be written to understand any language.
If the language command string contains host variables, an application can pass values for these variable by calling ct_param or ct_setparam once for each variable that the language string contains. Use ct_setparam if the command will be sent to the server more than once. See “Resending commands”.
Transact-SQL variables must begin with an @ sign.
An Adaptive Server Enterprise language cursor generates a regular row result set when an application calls ct_command to execute a fetch language command against the cursor. The Transact-SQL fetch command generates regular row results containing a number of rows equal to the current “cursor rows” setting for the language cursor.
Message commands and results provide a way for clients and servers to communicate specialized information to one another. A message command is similar to an RPC command, but the command is identified by a number (called the message ID) rather than by an RPC name.
A message command has an ID, which an application provides in a CS_INT variable. The application passes the address of the CS_INT as ct_command’s buffer parameter.
A custom Open Server application can be programmed with an event handler that responds to user-defined messages. IDs for user-defined messages must be greater than or equal to CS_USER_MSGID and less than or equal to CS_USER_MAX_MSGID.
If a message requires parameters, the application calls ct_param or ct_setparam once for each parameter that the message requires. Use ct_setparam if the RPC command will be sent to the server more than once. See “Resending commands” .
A package command instructs an IBM DB/2 database server to execute a package. A package is similar to a remote procedure. It contains precompiled SQL statements that are executed as a unit when the package is invoked.
If the package requires parameters, the application calls ct_param or ct_setparam once for each parameter that the package requires. Use ct_setparam if the package command will be sent to the server more than once. See “Resending commands”.
An RPC (remote procedure call) command instructs a server to execute a stored procedure either on this server or a remote server.
An application initiates an RPC command by calling ct_command with *buffer as the name of the stored procedure to execute.
If an application is using an RPC command to execute a stored procedure that requires parameters, the application must call ct_param or ct_setparam once for each parameter required by the stored procedure. Use ct_setparam if the RPC command will be sent to the server more than once. See “Resending commands”.
After sending an RPC command with ct_send, an application processes the stored procedure’s results with ct_results and ct_fetch. ct_results and ct_fetch are used to process both the result rows generated by the stored procedure and the return parameters and status from the procedure, if any.
An alternative way to call a stored procedure is by executing a language command containing a Transact-SQL execute statement. When a stored procedure is executed through a language command, parameter values may be converted to character format (if necessary) and passed as part of the language command text, or they may be included in the command as host variables. With an RPC command, parameters can be passed in their declared datatypes with ct_param or ct_setparam.
An application uses a send-data command to write large amounts of text or image data to a server.
An application typically calls:
ct_command to initiate the send-data command.
ct_data_info to set the I/O descriptor for the operation.
ct_send_data to write the value, in chunks, to the data stream.
ct_send to send the command to the server.
Send-data commands cannot be re-sent.
Internally, Sybase uses send-bulk-data commands as part of its implementation of the Bulk-Library routines.
Send-bulk-data commands cannot be re-sent.
To update a text or image column, a client application typically calls the ct_command routine to initiate a send-data command. The client then calls the ct_data_info command to retrieve the CS_IODESC and determine the appropriate SQL command to generate (update or writetext) in a subsequent call to the ct_send_data routine.
To simplify this process and potentially improve performance, a client can suppress the generation of the SQL command (update or writetext) and send data directly to the server bulk handler. The client must initiate the send-data command by calling the ct_command routine with the type parameter set to CS_SEND_DATA_NOCMD. The client application can then use send-data commands to send only text or image data to the server bulk handler. When a bulk event occurs at the server, a 4-byte field is sent indicating the total number of bytes to be sent, followed by the text or image data. The bulk handler reads the total number of bytes expected using srv_text_info and the data using srv_get_data.
The server must define a stored procedure, sp_mda, to indicate whether or not it supports the ct_send_data routine sending only text or image data without a SQL command. The server sp_mda procedure is called only if the client application sets certain properties—for example, ct_con_props(CS_SENDDATA_NOCMD)—before the ct_connect routine is called. If any of these properties (such as CS_PARTIAL_TEXT or the CS_SENDDATA_NOCMD connection property) is set, the server sp_mda procedure is called during execution of ct_connect. If sp_mda indicates that the server does not support the ct_send_data routine sending only text or image data without a SQL command, any calls to the ct_command routine with the type parameter set to CS_SEND_DATA_NOCMD fail.
If the server can receive text or image data without a SQL command, sp_mda returns the following:
Parameter |
Value |
---|---|
mdinfo |
“SENDDATA_NOCMD” |
querytype |
2 |
query |
senddata no cmd |
Adaptive Server cannot receive image or text data without a SQL command.
ct_cmd_alloc, ct_cursor, ct_dynamic, ct_param, ct_send, ct_setparam