تمرير سلسلة فارغة/فارغة إلى إجراء Oracle المخزنة من ASP.NET
-
23-09-2019 - |
سؤال
لدينا خدمة ويب ASP.NET التي تستدعي إجراءً مخزنًا على DB (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 أن تكون فارغة.
المحلول
يمكنك القيام بما يلي لأي معلمات قابلة للبطولة.
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.
تحرير: إذا لم يصل هذا المشكلة ، فمن المحتمل أن يكون عدم تطابق بين الأنواع ، تحقق من Nvarchar vs varchar