Pregunta

Tenemos un servicio web ASP.NET que invoca un procedimiento almacenado en nuestra (Oracle 11g) DB. El problema es que la llamada al procedimiento explota cada vez que una cadena vacía se pasa como uno de los parámetros. Estamos viendo un ORA-01084 error , lo que me indica que la llamada está fallando antes el procedimiento se ejecuta realmente.

Este es el procedimiento, menos cierta lógica que creo que no es relevante:

PROCEDURE CreateReport
( 
  from_dt IN NVARCHAR2,
  to_dt IN NVARCHAR2,
  p_table_id   IN NVARCHAR2,
  p_column_id  IN NVARCHAR2,
  device_name IN NVARCHAR2,
  ret_cursor OUT t_cursor
)
AS
  v_cursor t_cursor;
  dateStr NVARCHAR2(200);
  sqlStmt VARCHAR2(10000);
  extraColumns NVARCHAR2(10000);
BEGIN

    /* SNIP Cut logic that builds the query statement based on inputs */

    OPEN v_cursor FOR sqlStmt;
    ret_cursor := v_cursor;

END CreateReport;

Aquí está la invocación de CreateReport del servicio web:

public DataSet CreateReport(string fromDt, string toDate, string tableNames, 
                            string columnNames, string deviceName)
{
    DataSet dataSet;

    string fmDateStr = String.IsNullOrEmpty(fromDt) ? String.Empty : fromDt.Trim();
    string toDateStr = String.IsNullOrEmpty(toDate) ? String.Empty : toDate.Trim();

    OracleCommand oleDBCmd = new OracleCommand();

    oleDBCmd.CommandType = CommandType.StoredProcedure;
    oleDBCmd.CommandText = "Web_Pkg.CreateReport";

    oleDBCmd.Parameters.Add(new OracleParameter("from_dt", OracleType.NVarChar));
    oleDBCmd.Parameters["from_dt"].Value = fmDateStr;
    oleDBCmd.Parameters["from_dt"].Direction = ParameterDirection.Input;

    oleDBCmd.Parameters.Add(new OracleParameter("to_dt", OracleType.NVarChar));
    oleDBCmd.Parameters["to_dt"].Value = toDateStr;
    oleDBCmd.Parameters["to_dt"].Direction = ParameterDirection.Input;

    oleDBCmd.Parameters.Add(new OracleParameter("p_table_id", OracleType.NVarChar));
    oleDBCmd.Parameters["p_table_id"].Value = tableNames;
    oleDBCmd.Parameters["p_table_id"].Direction = ParameterDirection.Input;

    oleDBCmd.Parameters.Add(new OracleParameter("p_column_id", OracleType.LongVarChar));
    oleDBCmd.Parameters["p_column_id"].Value = columnNames;
    oleDBCmd.Parameters["p_column_id"].Direction = ParameterDirection.Input;

    oleDBCmd.Parameters.Add(new OracleParameter("device_name", OracleType.LongVarChar));
    oleDBCmd.Parameters["device_name"].Value = deviceName;
    oleDBCmd.Parameters["device_name"].Direction = ParameterDirection.Input;


    oleDBCmd.Parameters.Add(new OracleParameter("ret_cursor", OracleType.Cursor));
    oleDBCmd.Parameters["ret_cursor"].Direction = ParameterDirection.Output;

    try
    {
        // Throws exception if any of the paramters are String.Emtpy
        dataSet = DB.SQLSelect(oleDBCmd, connStr);
    }
    catch (Exception exp)
    {
        return null;
    }
    finally
    {
        if (oleDBCmd != null)
        {
            oleDBCmd.Dispose();
        }
    }

    return dataSet;
}

A modo de experimento, que modificó el servicio web para pasar null en lugar de una cadenas vacías. Cuando se pasa en null, veo un error que indica "número equivocado o tipos de argumentos en la llamada a 'createReport."

I también intentado pasar DBNull.Value siempre que los params eran nulas / vacío, pero que resultó en el error

Parameter 'p_column_id': No size set for variable length data type: String.

(Por supuesto, p_column_id fue el parámetro vacío en este caso).

Así que, ¿cómo puedo pasar con éxito las cadenas vacías como parámetros al procedimiento almacenado? Definitivamente, queremos permitir que el parámetro p_column_id a estar vacío.

¿Fue útil?

Solución

Se puede hacer lo siguiente para los parámetros con valores nulos.

oleDBCmd.Parameters.Add(new OracleParameter("to_dt", OracleType.NVarChar));
if(string.IsNullOrEmpty(toDateStr)) {
    oleDBCmd.Parameters["to_dt"].Value = DBNull.Value;
} else {
    oleDBCmd.Parameters["to_dt"].Value = toDateStr;
}
oleDBCmd.Parameters["to_dt"].Direction = ParameterDirection.Input;

De esta manera, usted no está confiando en cadena -.> Conversión nula por el adaptador de Oracle

Editar: Si esto no soluciona el problema, es más, posiblemente, una falta de correspondencia entre los tipos, comprobar Nvarchar vs VarChar

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top