title: Why do I get "Invalid Parameter binding" when using Oracle stored procedure with Udt and C#
body: <p>I'm trying to call a simple stored procedure on Oracle DB which takes a Udt (User defined type) as it's input and produces a simple varchar2 output. </p>
  
  <p>However there is obviously something wrong in my code as I keep on getting following error:</p>
  
  <pre><code>Invalid parameter binding
     at Oracle.DataAccess.Client.OracleParameter.PreBind_OracleObject(OracleConnection conn)
     at Oracle.DataAccess.Client.OracleParameter.PreBind_Object(OracleConnection conn)
     at Oracle.DataAccess.Client.OracleParameter.PreBind(OracleConnection conn, IntPtr errCtx, Int32 arraySize)
     at Oracle.DataAccess.Client.OracleCommand.ExecuteReader(Boolean requery, Boolean fillRequest, CommandBehavior behavior)
     at Oracle.DataAccess.Client.OracleCommand.ExecuteReader()
     at Oracle.DataAccess.Client.OracleCommand.ExecuteScalar()
  </code></pre>
  
  <p>I have been reading through Oracles documentation<br/>
  <a href="https://docs.oracle.com/database/121/ODPNT/extenRest.htm#ODPNT453" rel="nofollow noreferrer">https://docs.oracle.com/database/121/ODPNT/extenRest.htm#ODPNT453</a>, <br/><a href="https://docs.oracle.com/cd/E14435_01/win.111/e10927/featUDTs.htm#CJAHJHGE" rel="nofollow noreferrer">https://docs.oracle.com/cd/E14435_01/win.111/e10927/featUDTs.htm#CJAHJHGE</a> and <br/> <a href="https://docs.oracle.com/cd/E14435_01/win.111/e10927/IOracleCustomTypeInterface.htm#BABHGCIG" rel="nofollow noreferrer">https://docs.oracle.com/cd/E14435_01/win.111/e10927/IOracleCustomTypeInterface.htm#BABHGCIG</a>
   and googling various sources:<br/> 
  <a href="https://www.codeproject.com/Articles/141728/Interaction-between-C-Application-and-Oracle-throu" rel="nofollow noreferrer">https://www.codeproject.com/Articles/141728/Interaction-between-C-Application-and-Oracle-throu</a><br/><a href="https://stackoverflow.com/questions/44126843/invalid-parameter-name-binding-oracle-udt">Invalid parameter name binding oracle UDT</a><br/><a href="https://stackoverflow.com/questions/41586513/c-sharp-call-oracle-stored-procedure-with-nested-udt">C# Call Oracle Stored Procedure with nested UDT</a><br/>
   for clues what could be wrong but no luck.</p>
  
  <p>My stored procedure has the the following declaration: </p>
  
  <pre><code>PROCEDURE Test2(TEST2_IN_o IN TEST2_IN, errortext_out OUT varchar2); 
  </code></pre>
  
  <p>and type:</p>
  
  <pre><code>create or replace TYPE TEST2_IN AS OBJECT (
      FIELD1 VARCHAR2 (50 Byte),      
      FIELD2 VARCHAR2 (50 Byte),     
      FIELD3 VARCHAR2 (20 Byte),   
      USER_ID VARCHAR2(20)           
  ) NOT FINAL
  </code></pre>
  
  <p>Here is my object mapping:</p>
  
  <pre><code>namespace OracleProcedureTest
  {
      [OracleCustomTypeMapping("TEST2_IN")]
      public class TEST2_IN : IOracleCustomType, INullable
      {
          public TEST2_IN(string Field1, string Field2, string Field3, string UserID)
          {
              FIELD1 = Field1;
              FIELD2 = Field2;
              FIELD3 = Field3;
              USER_ID = UserID;
          }
  
          [OracleObjectMapping("FIELD1")]
          public string FIELD1 { get; set; }
  
          [OracleObjectMapping("FIELD2")]
          public string FIELD2 { get; set; }
  
          [OracleObjectMapping("FIELD3")]
          public string FIELD3 { get; set; }
  
          [OracleObjectMapping("USER_ID")]
          public string USER_ID { get; set; }
  
          public bool IsNull { get; set; }
  
          public static TEST2_IN Null =&gt; new TEST2_IN { IsNull = true };
  
          public void FromCustomObject(OracleConnection con, IntPtr pUdt)
          {
              OracleUdt.SetValue(con, pUdt, "FIELD1", FIELD1);
              OracleUdt.SetValue(con, pUdt, "FIELD2", FIELD2);
              OracleUdt.SetValue(con, pUdt, "FIELD3", FIELD3);
              OracleUdt.SetValue(con, pUdt, "USER_ID", USER_ID);
          }
  
          public void ToCustomObject(OracleConnection con, IntPtr pUdt)
          {
              FIELD1 = ((string)(OracleUdt.GetValue(con, pUdt, "FIELD1")));
              FIELD2 = ((string)(OracleUdt.GetValue(con, pUdt, "FIELD2")));
              FIELD3 = ((string)(OracleUdt.GetValue(con, pUdt, "FIELD3")));
              USER_ID = ((string)(OracleUdt.GetValue(con, pUdt, "USER_ID")));
          }
      }
  }
  </code></pre>
  
  <p>And here is the code that makes the call:</p>
  
  <pre><code>public static void RunTestFunction2(OracleConnection connection)
          {
              OracleTransaction transaction = null;
              OracleCommand cmd = null;
  
              //Start transaction
              transaction = connection.BeginTransaction(IsolationLevel.ReadCommitted);
  
              //Create the command
              cmd = new OracleCommand();
              cmd.Connection = connection;
              cmd.CommandType = CommandType.StoredProcedure;
              cmd.CommandText = "MyPackage.Test2";
  
              //Create the input object
              TEST2_IN inputObject = new TEST2_IN("Hello", "world", "OracleDB ", "123456");
  
              //Create the input parameter
              OracleParameter parameter_in = cmd.CreateParameter();
              parameter_in.OracleDbType = OracleDbType.Object;
              parameter_in.Direction = ParameterDirection.Input;
              parameter_in.ParameterName = "TEST2_IN_o";
              parameter_in.UdtTypeName = "TEST2_IN";
              parameter_in.Value = inputObject;
              cmd.Parameters.Add(parameter_in);
  
              //Create output parameter
              OracleParameter parameter_out = cmd.Parameters.Add("errortext_out", OracleDbType.Varchar2, 200);
              parameter_out.Direction = ParameterDirection.Output;
  
              //Run command and print result.
              Oracle.DataAccess.Types.OracleString oString;
  
              cmd.ExecuteNonQuery();
              oString = (Oracle.DataAccess.Types.OracleString)parameter_out.Value;
  
              Console.WriteLine("Return message was '" + oString.Value + "'.");
          }
  </code></pre>
  
  <p>Any help is appreciated. <br/><br/>I am aware that Oracle tools for Visual Studio allows creation of these objects from the Server Explorer but I could not get this to work. I have developer tools installed but I can only see managed driver which does not allow creation Udt-classes. </p>