Domanda

Sto utilizzando un prodotto che fornisce un'API di database basata sulle funzioni Oracle e sono in grado di chiamare le funzioni tramite ODP.NET in generale. Tuttavia, non riesco a capire come chiamare una funzione che include un cursore di riferimento come parametro out-parametro. Tutti i campioni che ho trovato finora chiamano una procedura con il parametro out-parametro o una funzione con il cursore REF come valore di ritorno. Ho provato a definire in modo simile i parametri, ma continua a ottenere l'errore che viene fornito il numero e il tipo di parametri errato.

Ecco l'intestazione della funzione (ovviamente offuscata):

FUNCTION GetXYZ(
   uniqueId       IN   somepackage.Number_Type,
   resultItems    OUT  somepackage.Ref_Type)
   RETURN somepackage.Error_Type;

Queste sono le definizioni di tipo in "qualche package":

SUBTYPE Number_Type IS NUMBER(13);
TYPE Ref_Type IS REF CURSOR;
SUBTYPE Error_Type IS NUMBER;

E questo è il codice che ho provato:

string sql = "otherpackage.GetXYZ";
var getXYZCmd = OracleCommand oracleConnection.CreateCommand(sql);
getXYZCmd.CommandType = CommandType.StoredProcedure;

getXYZCmd.Parameters.Add("uniqueId", OracleDbType.Int32).Value = uniqueExplosionId;
getXYZCmd.Parameters.Add("resultItems", OracleDbType.RefCursor).Direction = ParameterDirection.Output;
getXYZCmd.Parameters.Add("return_value", OracleDbType.Int32).Direction = ParameterDirection.ReturnValue;

Ho provato i seguenti modi diversi per chiamare la funzione (ovviamente solo una alla volta):

var result = getXYZCmd.ExecuteNonQuery();
var reader = getXYZCmd.ExecuteReader();
var scalarResult = getXYZCmd.ExecuteScalar();

Ma ognuno di essi fallisce con il messaggio di errore:

Oracle.DataAccess.Client.OracleException: ORA-06550: line 1, column 15:
PLS-00306: wrong number or types of arguments in call to 'GETXYZ'
ORA-06550: line 1, column 15:
PLS-00306: wrong number or types of arguments in call to 'GETXYZ'
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored.

Quindi è generalmente possibile chiamare una funzione con un cursore REF come parametro out-parametro da C# con ODP.NET? Posso chiamare una funzione con la stessa struttura con un parametro Varchar2-Out invece del cursore REF senza problemi ...

A proposito, sto usando ODP.NET versione 2.112.2.0 da C#.NET 3.5 in Visual Studio 2008.

Grazie in anticipo per il vostro aiuto!

È stato utile?

Soluzione

Sicuramente puoi. Ci sono alcuni gotcha di cui diffidare, ma ecco un caso di prova

create or replace function testodpRefCursor(
                  uniqueId    IN NUMBER 
                 ,resultItems OUT NOCOPY SYS_REFCURSOR) RETURN NUMBER
                 IS

 BEGIN
      OPEN resultItems for select level from dual  connect by level < uniqueId ;
      return 1;
 END testodpRefCursor;
  1. Ho scoperto che le funzioni piace avere il returnValue come IL PRIMO parametro nella raccolta
  2. BindByName è per impostazione predefinita false, quindi è default legarsi per posizione

Altrimenti è abbastanza semplice:

  OracleCommand cmd = new OracleCommand("TESTODPREFCURSOR", con);
  cmd.CommandType   = CommandType.StoredProcedure;
  cmd.BindByName = true;
  // Bind 


  OracleParameter oparam = cmd.Parameters.Add("ReturnValue", OracleDbType.Int64);
  oparam.Direction = ParameterDirection.ReturnValue ;       

  OracleParameter oparam0 = cmd.Parameters.Add("uniqueId", OracleDbType.Int64);
  oparam0.Value = 5 ;
  oparam0.Direction = ParameterDirection.Input;

  OracleParameter oparam1 = cmd.Parameters.Add("resultItems", OracleDbType.RefCursor);
  oparam1.Direction = ParameterDirection.Output;




  // Execute command
  OracleDataReader reader;
  try
  {
    reader = cmd.ExecuteReader();

    while(reader.Read() ){
        Console.WriteLine("level: {0}", reader.GetDecimal(0));  
    }

  } ...

Ora per altri campioni vai alla tua oracle home directory e guarda @ i campioni di cursore ref in odp.net

Ad esempio: %Oracle Client Home % odp.net samples 4 refcursor

hth

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top