我试图用OracleCommand对象填充DataSet对象,我刚刚开始使用Oracle,一生都在使用SQL Server。 在我的.NET控制台项目上,我添加了NuGet Oracle.ManagedDataAccess包,并将Sql对象更改为Oracle。像:SqlConnection到OracleConnection。 在SQL Server中,它工作正常,但是在Oracle中,它给了我这个错误,我真的不明白它的意思。
我将SqlConnection
更改为OracleConnection
和SqlCommand
至OracleCommand
也
command.Parameters.AddWithValue("@" + parameters[i], values[i] ?? DBNull.Value);
到
command.Parameters.Add(parameters[i], values[i] ?? DBNull.Value);
command.Parameters[i].Value = values[i];
因为AddWithValue
上不存在OracleCommand
这是从数据库获取数据的方法。
private void GetData(string storedProcedure, IReadOnlyList<string> parameters, IReadOnlyList<object> values)
{
using (var connection = new OracleConnection(_connectionString))
{
using (
var command = new OracleCommand(storedProcedure, connection)
{
CommandType = CommandType.StoredProcedure
})
{
if (parameters != null)
for (var i = 0; i < parameters.Count; i++)
{
command.Parameters.Add(parameters[i], values[i] ?? DBNull.Value);
}
var ds = new DataSet();
connection.Open();
new OracleDataAdapter(command).Fill(ds);
_data = ds.Tables;
connection.Close();
}
}
}
这些是im正在使用的参数。
var db = new Connector.Provider("AIA.GET_DATA",
new[]{
"Test1",
"Test2",
"Test3",
"Test4"},
new object[]{
1,
2,
3,
null});
这是存储过程。
PROCEDURE GET_DATA(
Test1 in NUMBER,
Test2 in NUMBER,
Test3 in NUMBER,
Test4 in NUMBER,
TestOut out SYS_REFCURSOR
);
在Provider的构造函数上,它获取连接字符串并使用方法GetData。
失败:
new OracleDataAdapter(command).Fill(ds);
Oracle.ManagedDataAccess.Client.OracleException:'ORA-03115:不支持的网络数据类型或表示形式'
同样,这在SQL Server上完美运行。
至少可以得到任何帮助,此错误消息是什么意思。
编辑:
谢谢卢克·伍德沃德,这非常有帮助。因此,OUT参数存在问题,但我发送的参数类型也存在问题。 这样可以解决问题。
无论如何,我最终还是采用了这种新方法。除null外,一切正常。
private void GetData(string storedProcedure, IReadOnlyList<string> parameters, IReadOnlyList<object> values, IReadOnlyList<string> cursors)
{
using (var connection = new OracleConnection(_connectionString))
{
using (
var command = new OracleCommand(storedProcedure, connection)
{
CommandType = CommandType.StoredProcedure
})
{
if (parameters != null)
for (var i = 0; i < parameters.Count; i++)
{
var parameter = new OracleParameter();
parameter.ParameterName = parameters[i];
if (values[i] is Enum)
parameter.Value = (int)values[i];
else
parameter.Value = values[i];
if (cursors != null && cursors.Contains(parameter.ParameterName))
{
parameter.Direction = ParameterDirection.Output;
parameter.OracleDbType = OracleDbType.RefCursor;
}
else
{
parameter.OracleDbType = GetOracleType(values[i]);
}
command.Parameters.Add(parameter);
}
var ds = new DataSet();
connection.Open();
new OracleDataAdapter(command).Fill(ds);
_data = ds.Tables;
connection.Close();
}
}
}
在Sql中,我可以使用DBNull.Value
,但是在Oracle中,我需要定义OracleDbType
,这很麻烦,因为此方法适用于任何对象,而无需关心类型,现在我仍然不使用知道如何修复它以使其可与Oracle中的任何对象一起使用。 但是可以认为这是题外话,这个问题可以标记为已回答。
答案 0 :(得分:1)
您需要为OracleParameter
参数OUT
添加一个TestOut
,但是您没有这样做。
在设置参数的其他行之后添加以下行:
var outParam = new OracleParameter("TestOut", OracleDbType.RefCursor, ParameterDirection.Output);
command.Parameters.Add(outParam);
然后,您将需要单独执行命令,而不是将命令传递给OracleDataAdapter
。通过添加行来完成
command.ExecuteNonQuery();
在两个添加outParam
的位置之后。
最后,通过替换行,将参考光标中的数据集填充到OUT
中
new OracleDataAdapter(command).Fill(ds);
使用
new OracleDataAdapter().Fill(ds, (OracleRefCursor)outParam.Value);
偶然地,我在运行您的代码时遇到了另一个错误。我收到错误PLS-00306: wrong number or types of arguments in call to 'GET_DATA'
。