Brendan,
Thanks a lot for pointing me in the right direction. I was able to get
Oracle stored procs working with some limitations.
Here is the code if anyone is interested. I know it's an ugly hack
(stored procs have to have a particular prefix name and REF CURSOR has
to be the last parameter) but it works.
public class OracleDataClientDriverWithSP : OracleDataClientDriver
{
public override IDbCommand GenerateCommand(CommandType type,
SqlString sqlString, SqlType[] parameterTypes)
{
IDbCommand cmd = base.GenerateCommand(type, sqlString,
parameterTypes);
if(sqlString.StartsWithCaseInsensitive("PROC"))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = ExtractStoredProcName(sqlString);
((OracleCommand) cmd).BindByName = false;
foreach (IDbDataParameter param in cmd.Parameters)
{
param.ParameterName = "";
}
((OracleCommand)cmd).Parameters.Add(new
OracleParameter("", OracleDbType.RefCursor,
ParameterDirection.Output));
}
return cmd;
}
private string ExtractStoredProcName(SqlString sqlCommandString)
{
int indexOfParamClouse =
sqlCommandString.IndexOfCaseInsensitive("(");
if(indexOfParamClouse > 0)
{
return
sqlCommandString.ToString().Remove(indexOfParamClouse);
}
return sqlCommandString.ToString();
}
and the mapping is
<sql-query name="selectAllEmploymentsForEmployee" callable="true">
<return class="Employment">
<return-property name="Employee" column="EMPLOYEE"/>
<return-property name="Employer" column="EMPLOYER"/>
<return-property name="StartDate" column="STARTDATE"/>
<return-property name="EndDate" column="ENDDATE"/>
<return-property name="RegionCode" column="REGIONCODE"/>
<return-property name="id" column="EMPID"/>
<return-property name="Salary">
<!-- as multi column properties are not supported via the
{}-syntax, we need to provide an explicit column list for salary
via <return-property> -->
<return-column name="VALUE"/>
<return-column name="CURRENCY"/>
</return-property>
</return>
PROC_selectAllEmploymentsFE(:EMPNAME)
</sql-query>
@ Ayende: Yes I understand the limitations once we start using stored
procs with NHIbenate. The idea is to offload few complex queries and
some cross system/cross database queries to stored procedures and
utilize NHibernate goodness (lazy load, change tracking, etc.) for the
rest of the application.
Dmitriy
On Jul 31, 9:06 pm, Brendan <
brendan.kow...@gmail.com> wrote:
> Dmitriy,
>
> I’m not an oracle expert either but, don’t bother with the examples
> for NHibernate executing oracle stored procedures. They just don’t
> work. In fact, they probably need to be reviewed / removed.
>
> As to your original question:>stored proc support is an importance part in "selling" NHibernate on my current project.
>
> =If most of your project is driven through stored procedures then
> NHibernate is NOT the tool for you. If your stored procs contain most
> of the logic around concurrency control, validation etc, then you’re
> circumventing NHibernate’s magic anyway. You’re probably better off
> just implementing your own datalayer with
ADO.NET.
>
> Back to the issue of Oracle Stored Proc support, I believe that the
> issue is a little more complicated. Mainly centred on the following
> points:
> 1. There is no way to add an OracleRefCursor as an OUT parameter.
> (Also revolves around being bound to the generic DbType)
> 2. There is no way of then feeding that ref cursor into the method
> that Hydrates the requested objects.
> 3. Need some way of doing this through a named sql query to support
> the return column mapping.
>
> The oracle support in NHibernate as suggested above is not perfect. If
> you’re simply using NHibernate as an ORM, then I’ve found that the
> oracle support works ok without too many issues. I added a ticket
> recently to try and get some of the changes we made back to the
> dialect (UInt Supporthttp://
jira.nhibernate.org/browse/NH-1382)
> > documentation that's the only syntax supportedhttp://
www.hibernate.org/hib_docs/reference/en/html/querysql.htmlhttp......