将 Null/空字符串从 asp.net 传递到 Oracle 存储过程
我们有一个 ASP.NET Web 服务,可以调用数据库 (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;
这是从 Web 服务调用 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;
}
作为实验,我修改了 Web 服务以传递 null
而不是空字符串。当传入 null
时,我看到一条错误,指示“调用‘CREATEREPORT 时参数的数量或类型错误”。
我还尝试在参数为 null/空时传递 DBNull.Value,但这导致错误
“参数'p_column_id':没有为可变长度数据类型设置大小:字符串。” >
(当然,在这种情况下,p_column_id 是空参数)。
那么,如何成功地将空字符串作为参数传递给我的存储过程呢?我们肯定希望允许 p_column_id 参数为空。
We have an ASP.NET web service that invokes a stored procedure on our DB (Oracle 11g). The problem is that the call to the procedure blows up every time an empty string is passed as one of the parameters. We're seeing an ORA-01084 error, which indicates to me that call is failing before the procedure is actually run.
Here's the procedure, minus some logic that I believe is not relevant:
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;
Here's the invocation of CreateReport
from the web service:
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;
}
As an experiment, I modified the web service to pass null
rather than an empty strings. When null
is passed in, I see an error indicating "wrong number or types of arguments in call to 'CREATEREPORT."
I also tried passing DBNull.Value
whenever the params were null/empty, but that resulted in the error
Parameter 'p_column_id': No size set for variable length data type: String.
(Of course, p_column_id was the empty parameter in this case).
So, how can I successfully pass empty strings as parameters to my stored procedure? We definitely want to allow the p_column_id parameter to be empty.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您可以对任何可为空的参数执行以下操作。
这样,您就不再依赖 string ->由 oracle 适配器进行 null 转换。
编辑:如果这不能解决问题,则很可能是类型之间不匹配,请检查 NVarChar 与 VarChar
You can do the following for any nullable parameters.
That way, you're not relying on string -> null conversion by the oracle adapter.
Edit: If this doesn't fix the issue, it is most possibly a mismatch between types, check NVarChar vs VarChar