2010-03-01 84 views
1

我們有一個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參數爲空。

回答

3

您可以對任何可爲空的參數執行以下操作。

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; 

這樣,你不依賴於oracle適配器的字符串 - > null轉換。

編輯:如果不解決這個問題,這是最有可能的類型之間的不匹配,檢查的NVarChar VS的VarChar

+0

這確實是一個類型不匹配。 device_name和p_column_id參數在Web服務中使用的類型不正確。它們是OracleType.LongVarChar,但它們應該是OracleType.NVarChar。謝謝! – Odrade 2010-03-02 15:07:47

相關問題