Generic Data Access Component???

The following URL details an article regarding the build of a generic data access component using factory patterns

The data access component seems to allow the use of providers like SqlClient and OleDB. I believe the idea is that you can extend this to support other providers by adding the additional provider types within each of the share arrays _connectionTypes() , _commandTypes(), _dataAdapterTypes() and _dataParameterTypes()
Private Shared _connectionTypes() As Type = {GetType(OleDbConnection), GetType(SqlConnection), GetType(OtherProviderType)}

I have added the new Oracle provider (System.Data.OracleClient) rather than using OleDB to access Oracle stored procedures. I have used this and all is good although i've come across a problem regarding the calling of stored procedures which return special data provider types i.e. Cursor object from the PLSQL Stored procedure for example.

An idea how you could call a PLSQL stored procedure returning cursor object(s) using this generic data access component via the oracle provider (System.Data.OracleClient)??

One of the functions within the component is CreateDataParameter i.e.
Public Function CreateDataParameter(parameterName As String, dataType As DbType) As IDbDataParameter

which expects a parameter of type DbType. Unfortunately the DbType does not have an similar OracleClientType.Cursor type to specify when creating the parameter object.

Can anyone give me a coded solution to this??
Many Thanks!
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

I think you'll have to rewrite the generic portion to handle more, or else just use a more specific Data Access Component.  DbType is used because it conforms to both OleDBConnection and SqlConnection.  Now you want to use a type that is no longer consistent with those.  You could create your own enumeration to deal with types and re-implement all of the existing DbType, plus add your new Cursor, but then you have the problem that if you try connecting to anything other than Oracle that there is a type of Cursor which will not be handled properly.   Thus you really need an Oracle specific DAC.  You can build it based on the existing generic one, but add the Oracle specific functionality where needed.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial

As I see it, you have two choices:

1) Do as SRigney suggests and re-write your data access component

2) Edit your stored procedure.

While doing suggestion 1 might be a good long term solution, I think redoing your stored procedure to return a query instead of cursor might be a faster/easier solution.

A cursor really is just a subset of data.  Why not simply (as part of your stored procedure) create a temp table.

Then your final steps just before ending your stored procedure will be to:

1) for each row in cursor insert into tempTbl
2) Select * from tempTbl

This is what I do in SQL server to avoid returning arrays of data, I just return a query of the tempTable I have created.

smlo88Author Commented:

I believe that the DbType conforms to Sql, oledb and oracle types.
The following url details a table and shows you what Dbtypes to use depending on the provider that you are using:

Although, in saying seems to only cover basic types. Specific provider types such as Cursor from OracleClient provider are not detailed.
I have managed to modify the generic data access component to acommodate the new OracleClient provider. I have been successful in calling a PLSQL stored procedure that takes basic input parameter types and output a number of PLSQL binary tables i.e. a recordset. This has been done using the OracleClient provider via the generic component.

But rather than using PLSQL tables to return a recordset we can use a single cursor object as an output parameter within the stored procedure. Coding the stored procedure is far quicker and easier....All you do is open the defined cursor and assign it to the defined output cursor parameter. Done...


You suggestion in changing the stored procedure is specific for SQL Server is it not? I know in SQL Server the only way of return a recordset of data is to do a select * from table/joined tables. But i dont believe you can do this in Oracle using a PLSQL stored proc. To get a recordset out of an Oracle stored proc, you need to use either:

1) PLSQL Binary tables as output parameters
2) A cursor object as output parameter      

These are the only possible options within Oracle as i understand it.
And as i describe above, using a single cursor output parameter is far quicker and easier to implement.....within the PLSQL stored proc, you open the defined cursor and simply assign it to the output cursor parameter and thats it done.

Learn SQL Server Core 2016

This course will introduce you to SQL Server Core 2016, as well as teach you about SSMS, data tools, installation, server configuration, using Management Studio, and writing and executing queries.

I understand that Oracle uses the standard types for input parameters, but as you state yourself, it has the ability to return a Cursor type.  Microsoft SQL cannot return a cursor type, thus if you modify your generic DAC to handle a type of Cursor and try connecting to MicrosoftSQL then it will not work.  

You probably need to modify
Public Function CreateDataParameter(parameterName As String, dataType As DbType) As IDbDataParameter

to use Oracle specific objects rather than the basic DbType.  

You are at the point that many people get to.  Do I write my code generic so it can be ported, or do I write me code specific so I can get things done the most efficiently.  Up until now you have been using generic, but if you want to deal with a Cursor, then you MUST write your code to be specific to Oracle.  Access and MSSQL cannot handle this type.  Look for the corresponding Oracle object that lists all types.  There's probably some kind of enumeration within the Oracle object that deals with all of the types including cursor.  Use it instead of DbType.


I'm afraid you are correct.  I was pretty sure I had returned a select statement from a stored procedure in Oracle (like I do with SQL server), but after looking in some old code I am returning a cursor object(Oracle 7.3.4 and VB 6).

smlo88Author Commented:

Can i just confirm, if we modify the function
Public Function CreateDataParameter(parameterName As String, dataType As DbType) As IDbDataParameter

to make use of the OracleType rather than DbType then we will also be returning the OracleDbDataParameter instead of the IDbDataParameter.
And if this is the case, we wont be able to use any of the existing generic methods such as this returns an IDdCommand object.  The CreateParameter method of the IDbCommand object would expect an IDbDataParameter rather than the OracleDbDataParameter.

Therefore, none of the methods within the generic DAC would be of any use as these all return interface types. We would moreorless need to rewrite all of the generic methods to be specific to the OracleClient provider i.e. create connection, command, dataadaptor and parameter....
Is this what you are saying? So we cant do what i was hoping for, all within the same generic DAC. Its pretty poor if this is the case :(

I don't think so...

If you use your WinCV.exe and query that class you should be able to see whether the class interfaces IDBCommand or not.

OleDbCommand Interfaces IDBCommand.... there for a statement like:

IDBCommand iComm = New OleDbCommand(<params>);  

will be a valid command and will compile properly.


If you haven't used WinCV.exe before you can find it in your visual studio directory (it comes with the .Net framework).

here is where I found it on my computer:
C:\Program Files\Microsoft Visual Studio .NET 2003\SDK\v1.1\Bin\WinCV.exe

Open up this application and where it says <search string>  type in the name of the class.

This will list all dependecies methods, properties, interfaces, etc.
If TADs suggestion doesn't show that IDbDataParameter is supported by the Oracle object, then yes you'll have to have everything be Oracle specific and rewrite the entire class.  I know it stinks, but it is what I was saying all along.
Bob LearnedCommented:
No comment has been added lately, so it's time to clean up this TA.
I will leave the following recommendation for this question in the Cleanup topic area:

Split: SRigney {http:#9782288} & _TAD_ {http:#9783473}

Please leave any comments here within the next seven days.

EE Cleanup Volunteer
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
.NET Programming

From novice to tech pro — start learning today.