# ADO.NET Drivers

SQL support in the PPJ Framework is entirely based on the abstract interfaces that are part of the ADO.NET specifications. Therefore, the PPJ Framework is fully driver independent and can work with any compliant ADO.NET driver, including the drivers for OLEDB, ODBC, Sql Server and Oracle that are already available in the basic .NET Framework.

Additionally, the specialized *SqlOra\** functions can work with both Oracle ODP ADO.NET driver or Microsoft's Oracle ADO.NET driver. The only limitation is that to pass array parameters and receive array parameters to stored procedures you have to use Oracle's ODP driver.

Various peculiarities in the specific ADO.NET driver can be [configured ](/general/framework/sql-support/configuration.md)in the sql.config file or set programmatically using the PPJ.Runtime.Sql.SqlProperty class.

{% hint style="info" %}
Since the PPJ is driver independent and a minimally compliant ADO.NET driver can be implemented directly in .NET, it is possible to easily add fully custom drivers to an application.
{% endhint %}

## Exposing ADO.NET objects

The *SalSqlHandle* and *SalSqlSessionHandle* types expose their inner ADO.NET objects through few and simple properties.

You can access the internal ADO.NET objects using the following members exposed by SalSqlHandle:

<table><thead><tr><th width="175"></th><th></th></tr></thead><tbody><tr><td>Connection</td><td>The instance of <em>System.Data.IDbConnection</em> corresponding to the Sql Handle. When the multiple connection option is off (default) and for connections using the same user/password, multiple Sql Handle instances share the same <em>IDbConnection</em> object.</td></tr><tr><td>Command</td><td>The instance of <em>System.Data.IDbCommand</em> corresponding to the statement that has been prepared or executed.</td></tr><tr><td>DataReader</td><td>The instance of <em>System.Data.IDataReader</em> that is connected to the database and returns the result set generated by the last executed statement. It's null when ResultSet mode is on.</td></tr><tr><td>DataSet</td><td>The instance of <em>System.Data.DataSet</em> populated with the entire result set generated by the last executed statement. It's null when ResultSet mode is off.</td></tr></tbody></table>

You can access the internal ADO.NET objects using the following members exposed by *SalSqlSessionHandle*:

<table><thead><tr><th width="179"></th><th></th></tr></thead><tbody><tr><td>Connection</td><td>The instance of <em>System.Data.IDbConnection</em> corresponding to the Sql Session Handle.</td></tr></tbody></table>

## Error Codes

Error codes returned by the PPJ Framework are the original codes returned by the database to the ADO.NET layer. This is different from SQLWindows/Team Developer behavior, which adds a certain predefined constant to the error code returned by the database. I.e., if Oracle return 01017, Gupta changes it to 21017.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.iceteagroup.com/general/framework/sql-support/ado.net-drivers.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
