sql >> Base de Datos >  >> RDS >> Oracle

¿Parámetros de Oracle con declaración IN?

Puede usar una colección de números de Oracle como parámetro (variable de enlace) cuando usa ODP.NET como proveedor de datos. Esto funciona con el servidor Oracle 9, 10 u 11 y la versión ODP.net>=11.1.0.6.20.

Una solución similar es posible cuando utiliza el proveedor de datos .NET de Devart para Oracle.

Seleccionemos los contratos con contractnum's 3 y 4.

Tenemos que usar un tipo de Oracle para transferir una matriz de números de contrato a nuestra consulta.

MDSYS.SDO_ELEM_INFO_ARRAY se usa porque si usamos este tipo de Oracle ya predefinido, no tenemos que definir nuestro propio tipo de Oracle. Puede completar MDSYS.SDO_ELEM_INFO_ARRAY con un máximo de 1048576 números.

using Oracle.DataAccess.Client;
using Oracle.DataAccess.Types;

[OracleCustomTypeMappingAttribute("MDSYS.SDO_ELEM_INFO_ARRAY")]
public class NumberArrayFactory : IOracleArrayTypeFactory
{
  public Array CreateArray(int numElems)
  {
    return new Decimal[numElems];
  }

  public Array CreateStatusArray(int numElems)
  {
    return null;
  }
}

private void Test()
{
  OracleConnectionStringBuilder b = new OracleConnectionStringBuilder();
  b.UserID = "sna";
  b.Password = "sna";
  b.DataSource = "ora11";
  using (OracleConnection conn = new OracleConnection(b.ToString()))
  {
    conn.Open();
    using (OracleCommand comm = conn.CreateCommand())
    {
      comm.CommandText =
      @" select  /*+ cardinality(tab 10) */ c.*  " +
      @" from contract c, table(:1) tab " +
      @" where c.contractnum = tab.column_value";

      OracleParameter p = new OracleParameter();
      p.OracleDbType = OracleDbType.Array;
      p.Direction = ParameterDirection.Input;
      p.UdtTypeName = "MDSYS.SDO_ELEM_INFO_ARRAY";
      //select contract 3 and 4
      p.Value = new Decimal[] { 3, 4 };
      comm.Parameters.Add(p);

      int numContracts = 0;
      using (OracleDataReader reader = comm.ExecuteReader())
      {
        while (reader.Read())
        {
           numContracts++;
        }
      }
      conn.Close();
    }
  }
}

El índice en contract.contractnum no se usa cuando se omite la sugerencia /*+ cardinalidad (pestaña 10) */. Supuse que contractnum es la clave principal, por lo que esta columna se indexará.

Consulte también aquí:http://forums.oracle.com/forums/thread.jspa?messageID=3869879#3869879