尝试填充数据集时出现“ ORA-03115:不支持的网络数据类型或表示形式”

时间:2019-03-28 18:56:42

标签: c# oracle

我试图用OracleCommand对象填充DataSet对象,我刚刚开始使用Oracle,一生都在使用SQL Server。 在我的.NET控制台项目上,我添加了NuGet Oracle.ManagedDataAccess包,并将Sql对象更改为Oracle。像:SqlConnection到OracleConnection。 在SQL Server中,它工作正常,但是在Oracle中,它给了我这个错误,我真的不明白它的意思。

我将SqlConnection更改为OracleConnectionSqlCommandOracleCommand

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中的任何对象一起使用。 但是可以认为这是题外话,这个问题可以标记为已回答。

1 个答案:

答案 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'