📄 uni_rpc.c
字号:
/*
** RPC COMMAND EXAMPLE PROGRAM
** ---------------------------------------------
**
** Description
** -----------
** This is an unichar16 example program modified from rpc.c
** for unichar/univarchar datatype demo.
**
** This example program demonstrates sending a RPC command
** to a Server and the processing of row, parameter, and status
** results returned from the remote procedure.
**
** The example uses standard ANSI C for input/output and
** memory management.
**
** All work is performed synchronously.
**
** Routines Used
** -------------
** All the required routines required for establishing and closing
** a connection to a server, sending a language command to a
** server, and processing row results.
**
** In addition, the following routines were used to demonstrate
** sending and processing a RPC command:
**
** ct_param()
** ct_bind()
** cs_convert()
** ct_res_info()
** ct_command()
**
** Input
** -----
** No input is required. Information normally required
** from the user is retrieved from global variables defined
** in the example header files.
**
** Output
** ------
** The example program displays the row results
** status results, parameter results, and server message
** returned by the remote procedure.
**
** Server Dependencies
** -------------------
** If connecting to dataserver directly, the dataserver must be
** support unichar/univarchar datatype.
**
** If connecting to an Open Server, the Open Server must be able
** to handle language commands intended for a SQL Server.
**
** Server Version
** --------------
** 12.5
**
**
** Server Tables
** -------------
** This program requires the unipubs2.
**
** Algorithm
** ----------
** Initialize Client-Library.
**
** install message handling callbacks.
**
** Establish a connections.
**
** Create a database.
**
** Create a stored procedure.
**
** Execute the stored procedure.
**
** Retrieve and display the results returned from the stored
** procedure.
**
** Perform cleanup by dropping the database and the connection,
** deallocating memory allocated for commands, connections, and
** contexts, and exiting Client-Library.
**
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctpublic.h>
#include "example.h"
#include "exutils.h"
#if !lint
static char Sccsid[] = {"%Z% %M% %I% %G%"};
#endif /* !lint */
/*****************************************************************************
**
** defines and globals used.
**
*****************************************************************************/
/*
** Global names used in this module
*/
CS_CHAR *Ex_appname = "uni_rpc_program";
CS_CHAR *Ex_dbname = "unipubs2";
CS_CHAR *Ex_server = EX_SERVER;
CS_CHAR *Ex_username = EX_USERNAME;
CS_CHAR *Ex_password = EX_PASSWORD;
/*
** Prototypes for routines in the example code.
*/
CS_STATIC CS_RETCODE CreateStoredProcedure PROTOTYPE((
CS_CONNECTION *connection
));
CS_STATIC CS_RETCODE BuildRpcCommand PROTOTYPE((
CS_COMMAND *cmd
));
CS_STATIC CS_RETCODE DoRpc PROTOTYPE((
CS_CONNECTION *connection
));
/*
** main()
**
** Purpose:
** Entry point for example program.
**
** Parameters:
** None, argc and argv will not be used.
**
** Return:
** EX_EXIT_ERROR or EX_EXIT_SUCCEED
**
*/
int
main()
{
CS_CONTEXT *context;
CS_CONNECTION *connection;
CS_RETCODE retcode;
EX_SCREEN_INIT();
fprintf(stdout, "Unichar16 RPC Program\n");
fflush(stdout);
/*
** Allocate a context structure and initialize Client-Library
*/
retcode = ex_init(&context);
if (retcode != CS_SUCCEED)
{
ex_panic("ex_init failed");
}
/*
** Allocate a connection structure, set its properties, and
** establish a connection.
*/
retcode = ex_connect(context, &connection, Ex_appname,
Ex_username, Ex_password, Ex_server);
/*
** Create a stored procedure to execute
*/
if (retcode == CS_SUCCEED)
{
retcode = CreateStoredProcedure(connection);
}
/*
** Execute the the newly created RPC
*/
if (retcode == CS_SUCCEED)
{
retcode = DoRpc(connection);
}
/*
** Deallocate the allocated structures, close the connection,
** and exit Client-Library.
*/
if (connection != NULL)
{
retcode = ex_con_cleanup(connection, retcode);
}
if (context != NULL)
{
retcode = ex_ctx_cleanup(context, retcode);
}
return (retcode == CS_SUCCEED) ? EX_EXIT_SUCCEED : EX_EXIT_FAIL;
}
/*
** CreateStoredProcedure()
**
** Type of function:
** rpc program internal api
**
** Purpose:
** Create a stored procedure in the server for subsequent.
**
** Parameters:
** connection - Pointer to CS_CONNECTION structure.
**
** Return:
** CS_SUCCEED if rpc was created.
** Otherwise a Client-Library failure code.
*/
CS_STATIC CS_RETCODE
CreateStoredProcedure(connection)
CS_CONNECTION *connection;
{
CS_RETCODE retcode;
CS_CHAR *cmdbuf;
if ((retcode = ex_use_db(connection, Ex_dbname)) != CS_SUCCEED)
{
ex_error("CreateStoredProcedure: ex_use_db() failed");
return retcode;
}
/*
** Allocate the buffer for the command string.
*/
cmdbuf = (CS_CHAR *) malloc(EX_BUFSIZE);
if (cmdbuf == (CS_CHAR *)NULL)
{
ex_error("CreateTable: malloc() failed");
return CS_MEM_ERROR;
}
/*
** Build the command for creating the stored procedure.
** First, drop the stored procedure if it already exits.
*/
strcpy(cmdbuf, "if exists (select name from sysobjects \
where type = \"P\" and name = \"uni_sample_rpc\") \
Begin \
drop proc uni_sample_rpc \
End ");
if ((retcode = ex_execute_cmd(connection, cmdbuf)) != CS_SUCCEED)
{
ex_error("CreateStoredProcedure: ex_execute_cmd() failed");
free (cmdbuf);
return retcode;
}
/*
** Define the parameters.
*/
strcpy(cmdbuf, "create proc uni_sample_rpc \
@unicharparam unichar(2) output \
as ");
/*
** Define queries to return row results, assign parameter values,
** and return a message result.
*/
strcat(cmdbuf, "select au_lname, city \
from unipubs2..authors \
where state = @unicharparam");
if ((retcode = ex_execute_cmd(connection, cmdbuf)) != CS_SUCCEED)
{
ex_error("CreateStoredProcedure: ex_execute_cmd() failed");
}
free (cmdbuf);
return retcode;
}
/*
** BuildRpcCommand()
**
** Type of function:
** rpc program internal api
**
** Purpose:
** This routine contructs the parameters list for the rpc to execute
**
** Parameters:
** cmd - Pointer to CS_COMMAND structure.
**
** Return:
** CS_SUCCEED if rpc command was contructed
** Otherwise a Client-Library failure code.
**
*/
CS_STATIC CS_RETCODE
BuildRpcCommand(cmd)
CS_COMMAND *cmd;
{
CS_CONNECTION *connection;
CS_CONTEXT *context;
CS_RETCODE retcode;
CS_DATAFMT datafmt;
CS_UNICHAR unicharvar[2];
char rpc_name[15];
CS_INT destlen;
/*
** Assign values to the variables used for parameter passing.
*/
unicharvar[0] = (CS_UNICHAR)'C';
unicharvar[1] = (CS_UNICHAR)'A';
strcpy(rpc_name, "uni_sample_rpc");
/*
** Send the RPC command for our stored procedure.
*/
if ((retcode = ct_command(cmd, CS_RPC_CMD, rpc_name, CS_NULLTERM,
CS_NO_RECOMPILE)) != CS_SUCCEED)
{
ex_error("BuildRpcCommand: ct_command() failed");
return retcode;
}
/*
** Clear and setup the CS_DATAFMT structure, then pass
** each of the parameters for the RPC.
*/
memset(&datafmt, 0, sizeof (datafmt));
strcpy(datafmt.name, "@unicharparam");
datafmt.namelen = CS_NULLTERM;
datafmt.datatype = CS_UNICHAR_TYPE;
datafmt.maxlength = 4;
datafmt.status = CS_RETURN;
datafmt.usertype = USER_UNICHAR_TYPE;
datafmt.locale = NULL;
if((retcode = ct_param(cmd, &datafmt, (CS_UNICHAR *)unicharvar,
4, CS_UNUSED)) != CS_SUCCEED)
{
ex_error("BuildRpcCommand: ct_param(unichar) failed");
return retcode;
}
return retcode;
}
/*
** DoRpc()
**
** Type of function:
** rpc program internal api
**
** Purpose:
** This routine passes the parameters and runs
** the sample RPC on the server.
**
** Parameters:
** connection - Pointer to CS_CONNECTION structure.
**
** Return:
** CS_SUCCEED if rpc was executed.
** Otherwise a Client-Library failure code.
**
*/
CS_STATIC CS_RETCODE
DoRpc(connection)
CS_CONNECTION *connection;
{
CS_RETCODE retcode;
CS_COMMAND *cmd;
CS_SMALLINT msg_id;
CS_INT res_type; /* result type from ct_results */
if ((retcode = ct_cmd_alloc(connection, &cmd)) != CS_SUCCEED)
{
ex_error("DoRpc: ct_cmd_alloc() failed");
return retcode;
}
if ((retcode = BuildRpcCommand(cmd)) != CS_SUCCEED)
{
ex_error("DoRpc: BuildRpcCommand() failed");
return retcode;
}
/*
** Send the command to the server
*/
if (ct_send(cmd) != CS_SUCCEED)
{
ex_error("DoCompute: ct_send() failed");
return retcode;
}
/*
** Process the results of the RPC.
*/
while ((retcode = ct_results(cmd, &res_type)) == CS_SUCCEED)
{
switch ((int)res_type)
{
case CS_ROW_RESULT:
case CS_PARAM_RESULT:
case CS_STATUS_RESULT:
/*
** Print the result header based on the result type.
*/
switch ((int)res_type)
{
case CS_ROW_RESULT:
fprintf(stdout, "\nROW RESULTS\n");
break;
case CS_PARAM_RESULT:
fprintf(stdout, "\nPARAMETER RESULTS\n");
break;
case CS_STATUS_RESULT:
fprintf(stdout, "\nSTATUS RESULTS\n");
break;
}
fflush(stdout);
/*
** All three of these result types are fetchable.
** Since the result model for rpcs and rows have
** been unified in the New Client-Library, we
** will use the same routine to display them
*/
retcode = ex_fetch_data(cmd);
if (retcode != CS_SUCCEED)
{
ex_error("DoRpc: ex_fetch_data() failed");
return retcode;
}
break;
case CS_MSG_RESULT:
/*
**
*/
retcode = ct_res_info(cmd, CS_MSGTYPE,
(CS_VOID *)&msg_id, CS_UNUSED, NULL);
if (retcode != CS_SUCCEED)
{
ex_error("DoRpc: ct_res_info(msgtype) failed");
return retcode;
}
fprintf(stdout, "ct_result returned CS_MSG_RESULT where msg id = %d.\n", msg_id);
fflush(stdout);
break;
case CS_CMD_SUCCEED:
/*
** This means no rows were returned.
*/
break;
case CS_CMD_DONE:
/*
** Done with result set.
*/
break;
case CS_CMD_FAIL:
/*
** The server encountered an error while
** processing our command.
*/
ex_error("DoRpc: ct_results returned CS_CMD_FAIL.");
break;
default:
/*
** We got something unexpected.
*/
ex_error("DoRpc: ct_results returned unexpected result type");
return CS_FAIL;
}
}
/*
** We're done processing results. Let's check the
** return value of ct_results() to see if everything
** went ok.
*/
switch ((int)retcode)
{
case CS_END_RESULTS:
/*
** Everything went fine.
*/
retcode = CS_SUCCEED;
break;
case CS_FAIL:
/*
** Something failed happened.
*/
ex_error("DoRpc: ct_results() failed");
break;
default:
/*
** We got an unexpected return value.
*/
ex_error("DoRpc: ct_results returned unexpected result type");
break;
}
return retcode;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -