c# - How to get ODP.NET to return null value for User Defined Type from out parameter in Oracle stored procedure? -


i having trouble odp.net regards udt (user defined type) behavior.

my problem arises when have a procedure containing out parameter returns specific udt.

when return an instantiated udt out parameter there no problem.

when return a null value out parameter i nullreference error:

a first chance exception of type 'system.nullreferenceexception' occurred in oracle.dataaccess.dll

i have tried setting isnullable = true on relevant oraclecommand parameter without success.

i have no problem sending , receiving rather complex udt's, e.g. udt's nested udt's , collections of objects , udt's witgh nested collections of objects.

any ideas if can solved using odp.net other making oracle procedure return instance of object type?

update - solved:

the issue udt type nested udt type not correctly initialized null. using auto generated code solved problem.using oracle user-defined types .net , visual studio

christian shay, thank resolving issue - auto generated code perhaps better choice implementing base classes handle of behavior, although possible.

the oracle stored procedure signature is:

procedure create_definitions_for_group(     p_grp_no             in     number    ,p_date               in     date    ,p_error_code         out    myschema.error_code); 

i call code in c# using odp.net after opening connection:

using (var ocmd = new oraclecommand        {            commandtext = "myschema.mypackage.create_definitions_for_group",            connection = oconn,            commandtype = commandtype.storedprocedure         }) {     try     {         ocmd.parameters.add(oracleparameterfactory.createinparam(             "p_grp_no", oracledbtype.int64, value: groupno));         ocmd.parameters.add(oracleparameterfactory.createinparam(             "p_date", oracledbtype.date, value: dateofgroup));         ocmd.parameters.add(oracleparameterfactory.createoutparamforudttype(             "p_error_code", "myschema.error_code"));          ocmd.executenonquery();          var report = ocmd.parameters["p_error_code"].value dberrorcode;          return report;     }         {         commandhelpers.disposeparameters(ocmd);     } } 

the udt type defined valid udt type in .net this:

public class dberrorcode : typetemplate {     [oracleobjectmapping("error_code")]     public decimal code { get; set; }      [oracleobjectmapping("description")]     public string description { get; set; } } 

the base typetemplate class defined this:

public class typetemplate : ioraclecustomtype, inullable {     public virtual void fromcustomobject(oracleconnection con, intptr pudt)     {         foreach (var p in gettype().getproperties())         {             // must ignore these 2 properties             if (p.name == "null" || p.name == "isnull") continue;              var oracleobjectmappingattribute = p.getcustomattributes(typeof(oracleobjectmappingattribute), false)[0] oracleobjectmappingattribute;              if (oracleobjectmappingattribute == null) continue;              var attributename = oracleobjectmappingattribute.attributename;              if (p.getcustomattributes(typeof(ignoreattribute), false).length == 0)             {                 if (p.getcustomattributes(typeof(nullableattribute), false).length == 0)                 {                     oracleudt.setvalue(con, pudt, attributename, p.getvalue(this, null));                 }                 else                 {                     if (p.getvalue(this, null) != null)                     {                         oracleudt.setvalue(con, pudt, attributename, p.getvalue(this, null));                     }                 }             }         }     }      public virtual void tocustomobject(oracleconnection con, intptr pudt)     {         foreach (var p in gettype().getproperties())         {             // must ignore these 2 properties             if (p.name == "null" || p.name == "isnull") continue;              var oracleobjectmappingattribute = p.getcustomattributes(typeof(oracleobjectmappingattribute), false)[0] oracleobjectmappingattribute;              if (oracleobjectmappingattribute == null) continue;              var attributename = oracleobjectmappingattribute.attributename;              if (!oracleudt.isdbnull(con, pudt, attributename))             {                 p.setvalue(this, oracleudt.getvalue(con, pudt, attributename), null);             }         }     }      #region inullable members      public bool isnull { get; private set; }      public static typetemplate null     {                 {             var obj = new typetemplate { isnull = true };             return obj;         }     }      #endregion } 

the method in oracleparameterfactory udt parameter follows (exception handling removed code present clean code possible - error produced not come exception handling):

public static oracleparameter createoutparamforudttype(    string paramname, string udtname, object value, bool isnullable = false) {     var param = new oracleparameter     {         parametername = paramname,         udttypename = udtname.toupperinvariant(),         oracledbtype = oracledbtype.object,         direction = parameterdirection.output,         isnullable = isnullable     };      if (value != null)     {         param.value = value;     }      return param; } 

problem solved: issue udt type nested udt type not correctly initialized null. using auto generated code solved problem.using oracle user-defined types .net , visual studio

christian shay, thank resolving issue - auto generated code perhaps better choice implementing base classes handle of behavior, although possible.


Comments

Popular posts from this blog

How has firefox/gecko HTML+CSS rendering changed in version 38? -

javascript - Complex json ng-repeat -

jquery - Cloning of rows and columns from the old table into the new with colSpan and rowSpan -