Передача пустой / пустой строки в хранимую процедуру Oracle из asp.net - PullRequest
1 голос
/ 02 марта 2010

У нас есть веб-служба ASP.NET, которая вызывает хранимую процедуру в нашей БД (Oracle 11g). Проблема заключается в том, что вызов процедуры взрывается каждый раз, когда в качестве одного из параметров передается пустая строка. Мы видим ошибку ORA-01084 , которая указывает мне, что вызов не выполняется до фактического запуска процедуры.

Вот процедура, за исключением некоторой логики, которая, я считаю, не имеет значения:

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;

Вот вызов CreateReport из веб-службы:

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;
}

В качестве эксперимента я изменил веб-сервис так, чтобы он передавал null, а не пустые строки. Когда передается null, я вижу ошибку, указывающую «неправильное число или типы аргументов при вызове« CREATEREPORT ».

Я также пытался передать DBNull.Value всякий раз, когда параметры были нулевыми / пустыми, но это приводило к ошибке

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

(Конечно, p_column_id был пустым параметром в этом случае).

Итак, как мне успешно передать пустые строки в качестве параметров моей хранимой процедуры? Мы определенно хотим, чтобы параметр p_column_id был пустым.

1 Ответ

3 голосов
/ 02 марта 2010

Вы можете сделать следующее для любых обнуляемых параметров.

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;

Таким образом, вы не полагаетесь на строку -> нулевое преобразование с помощью адаптера оракула. ​​

Изменить: Если это не решает проблему, скорее всего, это несоответствие между типами, проверьте NVarChar против VarChar

...