【问题标题】:Can't pass an array to oracle procedure无法将数组传递给 oracle 过程
【发布时间】:2016-10-27 21:19:47
【问题描述】:

我已经创建了一个程序来测试这个问题,它在 oracle 开发人员中可以正常工作。有一个名为“dizi”的类型(数组和varchar2)。并且程序有输入参数。我正在尝试将一个数组作为 c# 中的参数传递给这个过程。我已经搜索了很多,但我无法解决问题。错误是:“并非所有可验证”

public void InsertQuestion(List<string> area_list)
    {
        quest_areas = area_list.ToArray();
        command = new OracleCommand();
        command.Connection = connect;           
        connect.Open();

        var arry = command.Parameters.Add("area_array",OracleDbType.Varchar2);
        arry.Direction = ParameterDirection.Input;
        arry.Size = quest_areas.Length;                      
        arry.CollectionType = OracleCollectionType.PLSQLAssociativeArray;
        arry.Value = quest_areas;            

        command.BindByName = true;
        command.CommandText ="TESTPROCEDURE(:area_array)";
        command.CommandType = CommandType.StoredProcedure;
        command.ExecuteNonQuery();
        connect.Close();
    }

这是我的程序(它只是为了测试,但我会使用类似的东西)

CREATE OR REPLACE PROCEDURE TESTPROCEDURE (t_in IN dizi)
IS
BEGIN
 FOR i IN 1..t_in.count LOOP
 dbms_output.put_line(t_in(i));
    END LOOP;
    END;

【问题讨论】:

  • 试试command.CommandType = CommandType.Text; command.CommandText ="BEGIN TESTPROCEDURE(:area_array); END;";
  • 我认为当你使用CommandType = CommandType.StoredProcedure;时你不能使用BindByName = true;
  • 请在答案下查看我的评论

标签: c# arrays oracle stored-procedures


【解决方案1】:

我的代码可以成功地将数组传递到 oracle 存储过程。采取与您的方法略有不同的方法。不完全确定有多少是相关的,但如果它有助于我的代码:

  • 使用正确的名称参数名称(在您的情况下为 t_in)
  • 不用设置参数的大小
  • 创建一个长度正确的对象数组并将内容复制到其中(即在您的情况下来自 quest_areas)
  • 然后将此对象数组设置为命令参数的值
  • 在调用 proc 时不使用绑定变量,而只是使用 proc 名称本身作为 CommandText。

也就是说,我怀疑您的问题可能与您在调用过程时使用绑定变量有关。如果您只是将“TESTPROCEDURE”设置为 CommandText,会发生什么?

或者另辟蹊径,将其更改为适当的匿名 PLSQL 块 'begin TESTPROCEDURE(:area_array);结尾;'并将 CommandType 更改为 CommandType.Text(正如 Wernfried 在我打字时建议的那样......)

更新

public void InsertQuestion(List<string> area_list)
    {
        var input_array = area_list.Select(s => (object)s).ToArray();
        command = new OracleCommand();
        command.Connection = connect;           
        connect.Open();

        var arry = command.Parameters.Add("area_array",OracleDbType.Varchar2);
        arry.Direction = ParameterDirection.Input;
        arry.CollectionType = OracleCollectionType.PLSQLAssociativeArray;
        arry.Value = input_array;            

        command.CommandText ="TESTPROCEDURE";
        command.CommandType = CommandType.StoredProcedure;
        command.ExecuteNonQuery();
        connect.Close();
    }

【讨论】:

  • 在您提出建议之前,我尝试使用 begin-end;并尝试仅使用 TESTPROCEDURE。但我已将参数名称更改为 t_in 和 "BEGIN TESTPROCEDURE(:t_in); END;"所以它不起作用,但我的错误已经改变:调用“TESTPROCEDURE”的参数类型错误数量
  • 在这种情况下,请尝试我的更新答案 - 我建议的更完整版本以匹配我成功采取的方法。
  • 不幸的是它仍然不起作用(调用“TESTPROCEDURE”时参数的数量或类型错误):(我认为我们已经使用了所有项目符号,也许我应该改变我的所有结构
  • 还有一件事要尝试:更改参数名称以匹配过程中的参数名称:var arry = command.Parameters.Add("t_in",OracleDbType.Varchar2);
  • 我在发表评论之前尝试过 :) 我想我放弃了,我会改变我的方式。感谢您的时间和精力
猜你喜欢
  • 2011-07-09
  • 2014-12-08
  • 2017-03-09
  • 2012-02-10
  • 1970-01-01
  • 1970-01-01
  • 2011-03-03
  • 1970-01-01
相关资源
最近更新 更多