An Open SQL Stored Procedure Example
This example illustrates how a stored procedure can be executed using an RWDBOSql object. The stored procedure used here is assumed to take one input-output parameter of type int, and to return two result sets, the first consisting of character strings and the second of two columns of types int and RWDecimalPortable. This stored procedure has a return value of type int.
This example assumes that an error handler is associated with the connection, and therefore doesn’t check for any errors after calls to the RWDBOSql object.
 
#define NUMBER_OF_ROWS 10 // Indicates the number of rows
// for the buffer
#define MAXSTRING_SIZE 255 // Maximum length of a string
// in the buffer
 
RWDBOSql openSql;
 
int inputParam = 100;
RWDBNullIndicator indA = 0;
 
RWDBTBuffer<int> paramBuffer(&inputParam, &indA, 1); //1
 
paramBuffer.paramType(RWDBColumn::inOutParameter); //2
 
char aString[NUMBER_OF_ROWS][MAXSTRING_SIZE];
memset(aString, 0, NUMBER_OF_ROWS * MAXSTRING_SIZE );
 
RWDBNullIndicator nullInd[NUMBER_OF_ROWS];
 
RWDBTBuffer<char> outCharBuffer(aString[0], nullInd,
NUMBER_OF_ROWS, MAXSTRING_SIZE); //3
 
RWDBTBuffer<int> outIntBuff(NUMBER_OF_ROWS); //4
RWDBTBuffer<RWDecimalPortable> outDecBuff(NUMBER_OF_ROWS); //5
 
RWCString sybaseSyntaxSql("mySelectStoredProc"); //6
openSql.statement(sybaseSyntaxSql, RWDBOSql::Procedure); //7
 
openSql << paramBuffer; //8
 
openSql[0] >> outCharBuffer; //9
 
openSql[1] >> outIntBuff >> outDecBuff; //10
 
openSql.execute(conn); // Execute the stored procedure
 
long count = 0;
while ( (count = openSql.fetch().rowsFetched() ) > 0 ) { //11
 
for( int row = 0; row < count; row++ ){
cout << "STRING VALUE :" << &outCharBuffer[row] << endl;
}
}
 
while ( (count = openSql.fetch().rowsFetched() ) > 0 ) { //12
 
for( int row = 0; row < count; row++ ){
cout << "INT VALUE: " << outIntBuffer[row] << endl;
cout << "DECIMAL VALUE: " << outDecBuff[row] << endl;
}
}
 
openSql.fetchReturnParams(); //13
cout << "RETURN PARAM VALUE : "<< inputParam << endl;
 
RWDBValue returnValue = openSql.returnValue(); //14
 
cout << "RETURN VALUE :" << returnValue.asInt() << endl;
 
//1 Creates a buffer for input parameters. Note the difference between this buffer creation and the buffer creation in An Open SQL Insert Example. In this case, an application address space is bound to the buffer.
//2 Indicates that the input buffer is intended to be an INPUT-OUTPUT parameter buffer. OUTPUT or INPUT-OUTPUT should be specified only if the parameter is expecting any return parameter values from the stored procedure execution.
//3 Creates a buffer for output values. The first result set this stored procedure returns consists of string columns less than 255 characters long. Like the input buffer example, this example uses application address space for the buffer.
//4 Creates an output buffer of type int for the second result set the stored procedure returns. Note that the buffers created here and on line //5 are not supplied the application address space. The RWDBTBuffer objects allocate and manage memory for storing the data. Each buffer has NUM_OF_ROWS entries.
//5 Creates an output buffer of type RWDecimalPortable for the second result set returned by the stored procedure.
//6 Creates a Sybase-specific SQL syntax for stored procedure invocation. In this case, the name of the stored procedure invokes the stored procedure. See //7.
//7 Associates the SQL statement with the RWDBOSql object. Note the hint provided as RWDBOSql::Procedure. Sybase in general treats all SQL statements as queries unless specified otherwise. Specifying the SQL statement as a stored procedure allows the stored procedure to be passed as an RPC command. RPC commands for stored procedure invocation result in better performance, per Sybase documentation.
//8 Associates an input buffer for the input parameter.
//9 Associates the output buffer for the first result set with the openSql object. This output buffer is bound to the first result set, indicated by the index 0.
//10 Associates the output buffers for the second result set with the openSql object. These output buffers are bound to the second result set, indicated by index 1. The buffers are bound in the order of the result set columns.
//11 Fetches rows from the first result set. Rows are fetched inside a while loop until all rows are fetched, indicated when fetch() returns 0 rows. A successful fetch places the rows in the buffer bound to the openSql object. In this case, the buffer is outCharBuffer. Note that the number of rows fetched is guaranteed to be less than or equal to the buffer's row size.
//12 Once a fetch() call returns 0 rows, the next fetch() call fetches rows from the next result set. The while loop fetches rows from the second result set into the buffers outIntBuff and outDecBuff.
//13 Makes an explicit call to fetch the return parameters. After this call, the return parameters can be expected to be available. Note that this call is made after completely processing the returned result sets.
//14 Gets the return value.