Oracle Custom type parameter - c#

i am new to oracle .I have procedure which has a param like this
#param1 title_type.title_type_code%type
title_type is custom type
ok.. now
How do I pass the parameter from c# using ODAC( OracleParameter object)
%type is confusing do you need to pass as object or pass as string
Anyone know please help??

This is just a reference to the type that title_type.title_type_code is using, as an alternative to hardcoding the type in two places.
You need to look up the definition of that table, and pass the parameter as whatever that is (could be VARCHAR, could be NUMBER, I doubt that it is an object).

Related

WF 4.5: Is it possible to add variables dynamically at runtime?

We are writing a custom activity. In this activity it is possible to set a database connection string and a name for a stored procedure. At runtime the stored procedure is executing. Now we have some stored procedures which has input parameters.
Is it possible to generate variables dynamically in WF 4.5 for each input parameter in the stored procedure? Reading the parameters from the stored procedure is not the problem, but I dont have any idea how to generate the variables.
Example:
The user enters a name for the stored procedure to be executed (2 input params #Variable1 and #Variable2). Now in the variables tab should be 2 variables: #Variable1 and #Variable2. If the user changes the name in the stored procedure then in the variables tab should be the new params (for example only #Variable2)...
We spent a lot of time on this issue. But the only thing we have learned is that the activity has to be a NativeActivity and the variables should be added in the CacheMetadata method. But if I add a variable with AddVariable() method nothing happens :(
If you are open to including third-party libraries, you could try using an ORM tool like Dapper to accomplish this. A Dapper query generally takes an anonymous type to supply its parameters. Typical code for creating a custom object from fields in a database would look something like this:
IDbConnection db = New IDbConnection(...);
int id = 527; // normally passed in - using a hard coded value would defeat the purpose...
string myQuery = "SELECT Engine, Transmission, Make, Model, BodyStyle FROM Table WHERE ID = #ID";
Car result = db.Query<Car>(myQuery, new { ID = id }).First();
So I believe that you could use reflection to pass in the type ("Car") using reflection and create an anonymous object or pass in an actual object with an "ID" property at runtime. It will automatically create a custom Car object with the resulting data, assuming that the Car object has properties of Engine, Transmission, Make, Model, BodyStyle, etc.
Note that if you don't supply the type you expect to get back, you get an ExpandoObject: Creating an anonymous type dynamically? - you may also be able to pass one of these in for your input parameters, which would mean that you could create it at runtime.
This guy came up with a generic method for Dapper that may help you: http://www.bradoncode.com/blog/2012/12/creating-data-repository-using-dapper.html
What he came up with is something like this:
IEnumerable<T> items = null;
// extract the dynamic sql query and parameters from predicate
QueryResult result = DynamicQuery.GetDynamicQuery(_tableName, predicate);
using (IDbConnection cn = Connection)
{
cn.Open();
items = cn.Query<T>(result.Sql, (object)result.Param);
}
return items;

Get sql type name from DbType

I need to print real datbase type name from DbParameter.DbType, but when I do something like this DbParameter.DbType.ToString() I get for example Int32 instead of int, is there a command or a property to do that or am I going to need to write switch statement?
Here is code if someone will need it: DbType to real SQL type string
You will have to write your own converter
The data type mappings can be found here MSDN

how to access an Output parameter in the old SQLHelper.cs class?

i'm currently modifying a legacy application that uses the SqlHelper class in c#. how do you access the OUTPUT value using an executedatareader?
You need to pass a SqlParameter object with the correct name, then check the parameter's value after calling ExecuteDataReader.

Can i use a parameter multiple times in the same query?

i was wondering, can a parameter be used more then once in the same query, like this :
MySqlParameter oPar0 = new MySqlParameter("e164", MySqlDbType.String);
oPar0.Value = user.E164;
string sSQL0 = "Delete from callmone.call where (caller=?e164 or called=?e164);";
clsDatabase.ExecuteSQL(sSQL0, oPar0);
Is this possible or should i write 2 parameters?
If the database driver handles named parameters, then you can reuse the parameter.
If the database driver doesn't handle named parameters, the parameter names are ignored and you have to add one parameter values for each use, in the exact order that they are used.
From the code that you presented it looks like the driver supports named parameters. If the code runs without an error, it works. If the driver would not support names parameters, the code would cause an error as there is only one parameter value.
I don't know of any reason why you can't do that.

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 - i.e. 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?
e.g. 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.

Categories