简体   繁体   中英

Type safe binding to an Oracle Stored Procedure in C#?

We are deploying multiple projects in C# with Oracle databases behind. I would like to implement all of the database logic in Oracle stored procedures as this

  • keeps all of the database logic in the database
  • makes it easier to maintain when database structures change
  • allows re-use of the stored procedures more easily across programming languages

I have test code running where I return rows using a SYS_REFCURSOR and I manually do the data bind on the results as SYS_REFCURSOR could be returning anything - ie its not type safe

My question is - is there any way I can define correct types in the stored procedure return type and correctly bind to that type safely in my C# code?

eg my PL/SQL procedure looks like this - the return part is not type safe - it could be anything. If I wanted to re-use it from another Oracle package then it will not have the correct type checking

PROCEDURE get_risk (p_process_id IN NUMBER, p_risk OUT sys_refcursor);

and my C# code looks something like the following. I have cludged this together from several classes so hopefully it makes sense. When I extract the data from the DB call I am manually defining the data types - I need to know in the C# code what the Oracle data types are

// setup procedure call
_oracleCommand = new OracleCommand("risk_pkg.get_risk", _conn.OracleConnection);
_oracleCommand.Parameters.Add(new OracleParameter("p_process_id", OracleDbType.Int64, processId, ParameterDirection.Input));
_oracleCommand.Parameters.Add(new OracleParameter("p_risk", OracleDbType.RefCursor, null, ParameterDirection.Output));

_oracleDataAdapter = new OracleDataAdapter(_oracleCommand);
_dataSet = new DataSet();

// call Oracle
_oracleDataAdapter.Fill(_dataSet);

// extract data - hand coded binding
Int64 dbRiskId = (Int64)_dataSet.Tables[0].Rows[0][_dataSet.Tables[0].Columns["risk_id"]];
Int64 dbClientId = (Int64)_dataSet.Tables[0].Rows[0][_dataSet.Tables[0].Columns["client_id"]];

return new Risk(dbRiskId, dbClientId);

This isn't necessarily a problem - I just want to know if there is a better way of doing this to make my PL/SQL more obvious in what it is returning, and making my C# code not have to know the Oracle data types - encapsulating me from database structure changes

Accepted solution : this seems to be the practical solution. I'm still slightly unsatisfied that my Oracle procedure isn't defining its return type explicitly, but that life

(You should post a sample of your to test code. Because I'm not sure, if I understand your question correctly.)

The returned type is Object to serve any possible return value. You have to convert it manually. But you could generate the code for the conversions. Define a table or a file with this meta information: which stored procedure returns which types and in which .Net types they shall be converted. Use this meta information to create the C# code.

We fill our RefCursors into a DataTable . The code to assign the table fields to their appropriate member variables is generated out of our meta tables.

I have used T4 text templating to do this with SQL server. Works incredibly well.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM