我們有一個ASP.NET Web服務調用我們的數據庫(Oracle 11g)上的存儲過程。問題在於,每當空字符串作爲參數之一傳遞時,該過程的調用就會爆炸。我們看到一個ORA-01084錯誤,這表明在程序實際運行之前調用失敗。從空白處傳遞NULL /空字符串到Oracle存儲過程
這裏的過程中,減去一些邏輯,我認爲是不相關的:
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
從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;
}
作爲一個實驗,我修改了網站服務通過null
而不是空字符串。當傳入null
時,我看到一個錯誤,指出「調用CREATEREPORT時參數的錯誤數量或類型」。
我也試過路過DBNull.Value
每當PARAMS是空/空的,但是這導致錯誤
Parameter 'p_column_id': No size set for variable length data type: String.
(當然,p_column_id在這種情況下,空參數)。
那麼,我怎樣才能成功地將空字符串作爲參數傳遞給我的存儲過程?我們肯定希望允許p_column_id參數爲空。
這確實是一個類型不匹配。 device_name和p_column_id參數在Web服務中使用的類型不正確。它們是OracleType.LongVarChar,但它們應該是OracleType.NVarChar。謝謝! – Odrade 2010-03-02 15:07:47