ADO - ADO Field Value Conversion and Data Type Handling
ADO (ActiveX Data Objects) provides a common interface for applications to work with data returned from databases. One important aspect of ADO is handling the values stored in database fields and converting them into forms that an application can understand and process. Databases support many data types, such as integers, decimal numbers, strings, dates, Boolean values, binary data, and NULL values. ADO acts as an intermediate layer between the database provider and the application, so understanding how field values and data types are handled is essential for reliable database programming.
Understanding ADO Field Values
In ADO, the values retrieved from a database are generally accessed through the Value property of a Field object. A Recordset contains multiple fields, and each Field represents a column from the underlying database result.
For example:
Dim rs As ADODB.Recordset
Set rs = New ADODB.Recordset
rs.Open "SELECT EmployeeID, EmployeeName, Salary FROM Employees", _
connectionObject
MsgBox rs.Fields("EmployeeName").Value
Here, EmployeeName is a field in the Recordset. The Value property returns the value stored in that field for the current record.
ADO does not always return database values as exactly the same programming-language type used by the database. The OLE DB provider determines how database types are represented to ADO, and ADO commonly exposes values through the COM VARIANT type. This allows a single interface to accommodate many different types of database values.
Database Types and ADO Representations
Different database systems have different type systems. For example, a database may contain columns defined as INTEGER, DECIMAL, VARCHAR, DATE, or BIT. ADO and its underlying provider map these database types into corresponding ADO data types.
Some common examples include:
| Database Data | Typical ADO Representation |
|---|---|
| Integer | adInteger, adSmallInt, adBigInt, etc. |
| Decimal | adDecimal, adNumeric |
| Character/String | adChar, adVarChar, adLongVarChar |
| Unicode String | adWChar, adVarWChar, adLongVarWChar |
| Date/Time | adDate, adDBTimeStamp |
| Boolean | adBoolean |
| Binary | adBinary, adVarBinary, adLongVarBinary |
| Floating-point number | adSingle, adDouble |
| NULL | Null value |
The exact mapping can depend on the database provider. Therefore, applications should not blindly assume that a particular database type will always appear as one exact programming-language type.
The Importance of VARIANT Values
Classic ADO is based on COM, where a VARIANT can hold different types of values. This provides flexibility because the same Field.Value property can return a string for one field, a number for another field, and a date for another.
For example:
Dim employeeName As Variant
Dim salary As Variant
Dim joiningDate As Variant
employeeName = rs.Fields("EmployeeName").Value
salary = rs.Fields("Salary").Value
joiningDate = rs.Fields("JoiningDate").Value
The variables can contain different types of values depending on the corresponding database fields.
This flexibility is useful when working with different database providers, but it also means that applications should check or appropriately handle the returned data before performing operations on it.
Handling Numeric Values
Numeric database fields can represent integers, decimal values, or floating-point numbers. ADO provides different data types for these values.
For example:
Dim salary As Double
salary = CDbl(rs.Fields("Salary").Value)
The CDbl function explicitly converts the returned value into a Double.
Explicit conversion can be useful when an application needs to perform mathematical operations:
Dim salary As Double
Dim annualSalary As Double
salary = CDbl(rs.Fields("Salary").Value)
annualSalary = salary * 12
However, the application should ensure that the database field actually contains a valid numeric value before attempting the conversion.
Handling String Values
Text fields may contain ordinary characters, Unicode characters, or long text. ADO provides data types such as adChar, adVarChar, adWChar, and adVarWChar to represent different kinds of textual data.
A field can be assigned to a string variable as follows:
Dim name As String
name = CStr(rs.Fields("EmployeeName").Value)
Explicit conversion with CStr makes the programmer's intention clear. It is particularly useful when the value needs to be combined with other strings.
Dim message As String
message = "Employee: " & CStr(rs.Fields("EmployeeName").Value)
Care should be taken with NULL values because converting a database NULL directly into a string can produce an error or unexpected result.
Handling Date and Time Values
Databases frequently store dates and timestamps for employee joining dates, transaction dates, appointments, and other events.
ADO can expose these values through appropriate date/time types. An application can explicitly convert a field value to a date:
Dim joiningDate As Date
joiningDate = CDate(rs.Fields("JoiningDate").Value)
The resulting value can then be formatted for display:
MsgBox Format$(joiningDate, "dd-mm-yyyy")
It is important to distinguish between the database's storage format and the format used to display the value. A database may store a date as a date/time value while the application displays it as 28-08-2026.
Handling Boolean Values
Some databases use Boolean-like fields to represent conditions such as active/inactive, approved/not approved, or available/unavailable.
ADO can represent Boolean values using adBoolean.
For example:
Dim isActive As Boolean
isActive = CBool(rs.Fields("IsActive").Value)
The application can then use the result in conditional logic:
If isActive Then
MsgBox "Employee is active"
Else
MsgBox "Employee is inactive"
End If
The actual representation can vary between database systems and providers, so applications should account for provider-specific behavior when necessary.
Understanding NULL Values
One of the most important parts of ADO data handling is understanding the difference between a database NULL and an empty string or zero.
A database NULL means that a value is unknown, missing, or not applicable. It does not necessarily mean that the field contains an empty string.
For example:
Name = ""
means the field contains an empty string.
Whereas:
Name = NULL
means the database has no actual value for that field.
These values should not be treated as identical.
In Visual Basic-based ADO programming, the IsNull function can be used to check a value:
If IsNull(rs.Fields("MiddleName").Value) Then
MsgBox "Middle name is not available"
Else
MsgBox rs.Fields("MiddleName").Value
End If
Checking for NULL before performing conversions is especially important.
NULL and Data Conversion
Consider the following code:
Dim salary As Double
salary = CDbl(rs.Fields("Salary").Value)
If the database contains NULL in the Salary field, the conversion may fail because NULL cannot simply be treated as an ordinary numeric value.
A safer approach is:
Dim salary As Double
If IsNull(rs.Fields("Salary").Value) Then
salary = 0
Else
salary = CDbl(rs.Fields("Salary").Value)
End If
This explicitly defines how the application should behave when the database does not contain a salary value.
The appropriate replacement value depends on the application's requirements. Using zero is not always correct because zero and unknown are semantically different.
Inspecting Field Data Types
ADO allows developers to examine information about a field through properties such as Type, DefinedSize, Precision, and NumericScale.
For example:
Dim fieldObject As ADODB.Field
Set fieldObject = rs.Fields("Salary")
MsgBox fieldObject.Type
The Type property identifies the ADO data type associated with the field.
This can be useful when an application works with different database schemas or needs to inspect the structure of returned data dynamically.
A developer can also examine all fields:
Dim fieldObject As ADODB.Field
For Each fieldObject In rs.Fields
Debug.Print fieldObject.Name
Debug.Print fieldObject.Type
Next
This allows the application to discover the names and types of fields returned by a query.
Decimal and Numeric Precision
Financial and business applications often use decimal or numeric database types. These are different from ordinary floating-point values because precision and scale are important.
For example, a database column might store:
12345.67
Here, the number contains a certain total number of digits and a specific number of digits after the decimal point.
ADO exposes properties such as Precision and NumericScale for appropriate numeric fields. These properties help describe how numeric values are represented.
When working with monetary values, developers should be careful about converting decimal database values into floating-point types because floating-point representations can introduce precision issues.
Binary Data Handling
Databases can store binary information such as images, documents, and other files. ADO represents binary values through data types such as adBinary, adVarBinary, and adLongVarBinary.
Binary values should not normally be treated as ordinary text. For example, attempting to convert an image stored as binary data into a string can corrupt the information or produce meaningless output.
Applications dealing with binary fields should preserve the returned data in an appropriate binary representation and process it according to the application's requirements.
Provider-Dependent Type Conversion
ADO provides a standardized programming interface, but the underlying database provider is responsible for communicating with the database.
As a result, the same conceptual database value can sometimes be exposed differently depending on the provider.
For example, one provider might return a particular numeric database type using one ADO numeric type, while another provider may use a different but compatible representation.
Therefore, portable ADO applications should avoid making unnecessary assumptions about exact provider-specific type mappings.
Explicit Conversion Versus Automatic Conversion
There are two general approaches to data conversion.
Automatic conversion occurs when the programming environment converts a value when it is assigned to another compatible variable type.
Explicit conversion occurs when the developer deliberately uses a conversion function such as:
CStr()
CInt()
CLng()
CDbl()
CDate()
CBool()
Explicit conversion is generally easier to understand because it clearly communicates what type the application expects.
For example:
Dim employeeID As Long
employeeID = CLng(rs.Fields("EmployeeID").Value)
This makes the expected application type explicit.
However, explicit conversion should be performed only after considering NULL values and whether the underlying value can actually be converted.
Practical Example
The following example demonstrates basic field value handling:
Dim name As String
Dim salary As Double
Dim joiningDate As Date
If Not IsNull(rs.Fields("EmployeeName").Value) Then
name = CStr(rs.Fields("EmployeeName").Value)
End If
If Not IsNull(rs.Fields("Salary").Value) Then
salary = CDbl(rs.Fields("Salary").Value)
End If
If Not IsNull(rs.Fields("JoiningDate").Value) Then
joiningDate = CDate(rs.Fields("JoiningDate").Value)
End If
The example first checks each database value for NULL. Only after confirming that a value exists does it convert the value into the required application type.
This approach reduces conversion errors and makes the application's treatment of missing data explicit.
Common Problems in Data Type Handling
Several problems can occur when handling ADO field values. The first is attempting to convert NULL directly into another data type. The second is assuming that every database provider maps its types identically. The third is treating numeric, date, Boolean, and binary values as strings without considering their actual meaning.
Another common problem is losing precision when converting high-precision database numbers into inappropriate application types. Applications should also avoid unnecessary conversions because every conversion introduces another opportunity for an error or loss of information.
Best Practices
When working with ADO field values, developers should check for NULL before performing conversions, use explicit conversion when the expected application type is known, and inspect field metadata when dealing with dynamic or provider-independent applications.
It is also important to preserve the original meaning of database values. NULL should not automatically be replaced with zero or an empty string unless the application's business rules specifically require that behavior. Numeric values should retain sufficient precision, dates should remain date/time values during processing, and binary information should be handled as binary data rather than ordinary text.
Conclusion
ADO Field Value Conversion and Data Type Handling is an important concept for applications that retrieve information from databases. ADO provides a flexible mechanism for exposing database values through Field objects and COM VARIANT values, while data types such as strings, numbers, dates, Boolean values, binary data, and NULL require different handling approaches.
A strong understanding of these conversions helps developers avoid runtime errors, unexpected results, data loss, and incorrect interpretation of database information. By checking NULL values, understanding provider-dependent mappings, using appropriate explicit conversions, and respecting the original database data types, developers can build more reliable ADO-based database applications.