2010-11-24 60 views
5

Je tente d'appeler une procédure qui prend un type de données personnalisé table of numbers comme l'un des paramètres.Liaison non valide pour Oracle UDT dans le paramètre de procédure

Voici la définition du type:

create type num_list as table of number; 

Et la définition de la procédure:

create or replace procedure my_procedure 
    (listofnumbers num_list, 
        v_value char) 
is 
begin 

    update my_table 
    set my_column = v_value 
    where my_row_id in (select column_value 
         from table(listofnumbers)); 

end; 

En utilisant ODP.NET et C#, je déclarais comme suit:

var row_ids = new int[] { 1, 2 }; 

using (var oracleConn = new Oracle.DataAccess.Client.OracleConnection(myConnectionString)) 
{ 
    oracleConn.Open(); 
    var cmd = new Oracle.DataAccess.Client.OracleCommand("my_procedure", oracleConn); 
    cmd.CommandType = CommandType.StoredProcedure; 

    var param1 = new Oracle.DataAccess.Client.OracleParameter("listofnumbers", Oracle.DataAccess.Client.OracleDbType.Array, ParameterDirection.Input); 
    param1.CollectionType = Oracle.DataAccess.Client.OracleCollectionType.PLSQLAssociativeArray; 
    param1.UdtTypeName = "num_list"; 
    param1.Value = row_ids; 
    cmd.Parameters.Add(param1); 

    var param2 = new Oracle.DataAccess.Client.OracleParameter("v_value ", Oracle.DataAccess.Client.OracleDbType.Char, ParameterDirection.Input); 
    param2.Value = "Y"; 
    cmd.Parameters.Add(param2); 

    cmd.ExecuteNonQuery(); 
} 

L'exception étant les états: jetés

Paramètre non valide Nom du paramètre de liaison : listofnumbers

Quelles sont les propriétés suis-je manque dans la définition du paramètre?

+0

Salut, comment avez-vous fini par résoudre cela? La réponse ci-dessous n'a pas fonctionné pour moi. – Jason

+0

Essayez la solution proposée dans le lien que j'ai posté dans ma réponse éditée. –

+0

PS la réponse ci-dessous fonctionne pour moi - vous ne devez pas définir le UdtTypeName mais utiliser plutôt le CollectionType. –

Répondre

2

EDIT: 14 mai

Comme ma réponse a unaccepted, voici un lien qui pourrait être utile:

http://developergeeks.com/article/35/working-with-user-defined-type-oracle-udt-and-custom-type-using-odp-net-11g


Malheureusement je ne peux pas jouer avec cela comme J'ai x64 ODP.NET qui ne supporte pas UDT.

Cependant, comme votre UDT est une collection, avez-vous essayé de définir la propriété Size sur param1?

param1.Size = row_ids.Length; 

Maintenant, ce n'est pas un UDT, mais voici un extrait de code que je lie à un type défini dans une spécification de package comme:

TYPE t_stringlist IS TABLE OF VARCHAR2(4000); 

      string[] values = new string[] { "AAA", "BBB" }; 

      OracleParameter parameter = new OracleParameter(); 
      parameter.Name = "my_param"; 
      parameter.CollectionType = OracleCollectionType.PLSQLAssociativeArray; 
      parameter.OracleDbType = OracleDbType.Varchar2; 
      parameter.ArrayBindSize = new int[values.Length]; 
      parameter.ArrayBindStatus = new OracleParameterStatus[values.Length]; 
      parameter.Size = values.Length; 

      for (int i = 0; i < values.Length; ++i) 
      { 
       parameter.ArrayBindSize[i] = 4000; 
       parameter.ArrayBindStatus[i] = OracleParameterStatus.Success; 
      } 

      parameter.Value = values; 

Je ne sais pas quelles sont les valeurs vous pouvez définir ArrayBindSize sur.

En outre, vous pouvez envisager la création d'une usine de type pour votre UDT:

http://download.oracle.com/docs/html/E15167_01/featUDTs.htm

De toute façon, j'espère que vous trouverez quelque chose qui aide.