Step 2: Using the Numeric as Object Mode

In this step you will see the following items:

The Numeric as Object Mode

The numeric as object mode is similar to the date as object mode. Instead of handling the numeric value as a string (which depends on the LOCALE setting for the decimal separator), or as a C float data type (which implies a loss of precision, since database numeric types can handle a precision much greater than a float), DB Link contains a C++ class called IlNumeric. This class provides an intuitive interface to numeric values. DB Link converts the value in an RDBMS-specific structure without any loss of precision and independently of LOCALE settings.

Two other possible modes are:

  • With the default mode, numeric values are handled as basic C++ types—either integers or float values. Since large numbers cannot be represented in this mode, precision may be lost. You can return to this default mode by using either IldIldBase::setNumericMode(IldFalse) or IldIldBase::setStringNumericMode(IldFalse).

  • With the numeric as string mode, numeric values are handled as strings. While there is no loss of precision, the string representation will depend on the LOCALE settings. The IldIldBase::setStringNumericUse(IldTrue) method activates this mode.

The best way to handle large floating values is to use the numeric as object mode, which does not lose precision and is independent of the LOCALE settings. This mode is activated with method IldIldBase::setNumericUse(IldTrue).

Setting the Numeric Mode

The following code demonstrates how to set the numeric mode. It also demonstrates the effect of this mode on the results set retrieved from the database. In method checkNumericMode, a new request is opened and then successively set to the three different modes. For each mode, a description of the mode is printed. Here is an excerpt from this method:

request->setStringNumericUse(IldTrue) ;

displayNumericMode(dbms, request, "Mode \"Numeric as String\" is activated :",

IldStringType) ;

 

request->setNumericUse(IldTrue) ;

displayNumericMode(dbms, request, "Mode \"Numeric as Object\" is activated :",

IldNumericType) ;

Displaying the Current Numeric Mode

The displayNumericMode method displays the current numeric mode using the methods IldIldBase::useNumeric and IldIldBase::useStringNumeric. Then, it runs a select query to select a numeric value from the database. Depending on the current numeric mode, this column will be of type IldRealType (default mode), IldStringType (numeric as string mode), or IldNumericType (numeric as object mode).

Here is the code of the displayNumericMode method:

static const char* selectStr = "select N from PORTS2" ;

cout << message << endl ;

<< "* request->useNumeric() = "

<<(request->useNumeric() ? "IldTrue" : "IldFalse")

<<", request->useStringNumeric() = "

(request->useStringNumeric() ? "IldTrue" : "IldFalse") << endl ;

if (!request->execute(selectStr)) {

IldDisplayError("Select execution failed : ", request) ;

Ending(dbms) ;

exit(1) ;

}

Inserting Data Using the Numeric as Object Mode

Data is now inserted in the table using the numeric as object mode. This is done with method insertData. First, numeric as object mode is activated:

request->setNumericUse(IldTrue) ;

The insert query is prepared as in previous steps. To bind the parameter, IldNumericType is used to specify the parameter in numeric as object mode. An array of two parameters is used:

if (!request->parse(insertStr)) {

IldDisplayError("Could not parse insert query : ", request) ;

Ending(dbms) ;

exit(1) ;

}

if (!request->bindParam((IldUShort)0, IldNumericType, sizeof(IlNumeric), nums,

numNulls)) {

IldDisplayError("Bind parameter failed : ", request) ;

Ending(dbms) ;

exit(1) ;

}

Executing the Query

The two numeric objects are initialized with a string of characters. They can also be initialized with a double-precision value, but this is not as precise. The query is then executed:

// Set the values for the numbers :

nums[0].set("1234567890.456") ;

nums[1].set("-86420.13579") ;

 

// Initialize null buffers :

memset(numNulls, 0, sizeof(short) * nbParam) ;

 

if (!request->execute(&rowCount, nbParam)) {

IldDisplayError("Could not execute insert query : ", request) ;

Ending(dbms) ;

exit(1) ;

}

Conclusion

This step demonstrated the use of the IlNumeric class. This class provides an intuitive way to handle large floating values with the RDBMS, regardless of LOCALE settings and with no loss of precision. Without DB Link, this requires knowledge of the specific structures used by the RDBMS API. Such code is complicated and is not portable to other RDBMSs. This step also demonstrated how the three different numeric modes are activated.

See source code.