C# 2010,ODP.net,调用存储过程传递数组

2023-11-26

我有一个需要 4 个输入的 PL/SQL 存储过程。这些输入之一是关联数组(Oracle 类型:PLS_INTEGER 索引的 VARCHAR2(1) 表)。

我想要一个 C# 程序,使用正确的输入(包括关联数组)调用此存储过程。

我将 ODP.net 11.2 与 Visual C# 2010 Express 和 Oracle 11gR2 结合使用。

我找不到任何关于如何从 C# 将数组传递到 pl/sql 过程的好示例。有人能给我举个例子吗?按照 Oracle 文档,我确实遇到错误,指出参数的数量或类型错误。

我的 C# 代码:

        OracleCommand cmd = new OracleCommand("begin sdg_test.sdg_test2(:1); end;", conn);

        OracleParameter Param1 = cmd.Parameters.Add("1", OracleDbType.Varchar2);

        Param1.Direction = ParameterDirection.Input;

        Param1.CollectionType = OracleCollectionType.PLSQLAssociativeArray;

        Param1.Value = new string[22] { "Y", "Y", "N", "Y", "N", "Y", "Y", "Y", "Y", "Y", "N", "Y", "N", "Y", "Y", "Y", "Y", "Y", "N", "Y", "N", "Y" };

        Param1.Size = 22;
        Param1.ArrayBindSize = new int[22] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };

        cmd.ExecuteNonQuery();

        conn.Close();
        conn.Dispose();

我的程序所做的只是记录一条消息。我只是想让这个概念发挥作用。


您可以从(更简单的方法)开始:

List<int> idList = yourObjectList;
List<int> nameList = yourObjectList;

using (OracleConnection oraconn = new OracleConnection())
{
    oraconn.ConnectionString = "Your_Connection_string";

    using (OracleCommand oracmd = new OracleCommand())
    {
        oracmd.Connection = oraconn;

        oracmd.CommandType = CommandType.StoredProcedure;
        oracmd.CommandText = "Your_Procedura_name";
        oraconn.Open();

        // To use ArrayBinding, you need to set ArrayBindCount   
        oracmd.BindByName = true;
        oracmd.ArrayBindCount = idList.Count;

        // Instead of single values, we pass arrays of values as parameters   
        oracmd.Parameters.Add("ids", OracleDbType.Int32, oyourObjectList.ToArray(), ParameterDirection.Input);
        oracmd.Parameters.Add("names", OracleDbType.Varchar2, oyourObjectList.ToArray(), ParameterDirection.Input);

        oracmd.ExecuteNonQuery();
        oraconn.Close();
    }
}

然后,在数据库中添加包/过程:

PROCEDURE Your_Procedure_name(
      name IN VARCHAR2,
      id IN NUMBER
      )    IS     
BEGIN

    INSERT INTO your_table VALUES( id, name);
END Your_Procedure_name;

另一种选择是:

using (OracleConnection oraconn = new OracleConnection())
{
    oraconn.ConnectionString = "Your_Connection_string";

    using (OracleCommand cmd = new OracleCommand())
    {

        cmd.Connection = oraconn;

        cmd.CommandType = CommandType.StoredProcedure;
        cmd.CommandText = "Your_Procedure_name";
        oraconn.Open();


        OracleParameter idParam = new OracleParameter("i_idList", OracleDbType.Int32, ParameterDirection.Input);
        idParam.CollectionType = OracleCollectionType.PLSQLAssociativeArray;
        idParam.Value = idList.ToArray();
        idParam.Size = idList.Count;

        OracleParameter nameParam = new OracleParameter("i_nameList", OracleDbType.Varchar2, ParameterDirection.Input);
        nameParam.CollectionType = OracleCollectionType.PLSQLAssociativeArray;
        nameParam.Value = nameList.ToArray();
        nameParam.Size = nameList.Count;

        // You need this param for output
        cmd.Parameters.Add("ret", OracleDbType.RefCursor).Direction = ParameterDirection.Output;
        cmd.Parameters.Add(idParam);
        cmd.Parameters.Add(nameParam);

        conn.Open();

        //If you need to read results ...
        using (OracleDataReader dr = cmd.ExecuteReader())
        {
            while (dr.Read())
            {
                ...
            }
        }
        conn.Close();
    }
}

但它更复杂,因为您需要为存储过程定义新类型,例如

TYPE integer_list IS TABLE OF Your_table.id_column%TYPE INDEX BY BINARY_INTEGER;
// same for names

创建一个模式级别类型,例如

create or replace TYPE T_ID_TABLE is table of number; 

然后在存储过程中使用它们,例如

PROCEDURE Your_Procedure_name(
      v_ret IN OUT SYS_REFCURSOR,
      i_idList integer_list,
      i_nameList string_list)
  IS  
  begin
    -- Store passed object id list to array
 idList T_ID_TABLE := T_ID_TABLE(); 
  ...
  begin

    -- Store passed object id list to array
    idList.Extend(i_idList.Count);
    FOR i in i_idList.first..i_idList.last loop
     idList(i) := i_idList(i);
    END LOOP;    

    ...
END Your_Procedure_name;
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C# 2010,ODP.net,调用存储过程传递数组 的相关文章

随机推荐

  • 如何在 virtualenv 中添加 PYTHONPATH 路径

    我正在尝试添加 PYTHONPATH 环境变量的路径 该路径仅在特定的 virtualenv 环境中可见 I tried SET PYTHONPATH 在 virtualenv 命令提示符下 但这会为整个环境设置变量 我该如何实现这一目标
  • 空 div 与具有 inline-block 属性的文本的 div

    想知道这种行为的原因 CSS div display inline block margin right 2px width 20px background color red 空div div style height 20px div
  • 远程事后核心转储分析,无需共享系统库的精确调试符号

    您通常如何解决这个问题 想象一下 一个线程在 Computer1 上的 libc 代码 系统共享库 内部崩溃 然后生成核心转储 但要分析此 coredump 的 Computer2 可能具有不同版本的 libc So 在远程计算机上拥有相同
  • Material Design:如何断开浮动标签以供选择?

    我需要创建没有浮动标签的选择字段 但我想要有占位符和默认值 我阅读文档https material angular io components form field overview floating label并尝试自己做
  • 如何将数据库上传到 Heroku

    我有一个共享的heroku应用程序 现在我不想使用相同的代码在heroku中创建一个测试应用程序 所以我创建了一个新的应用程序 好的 问题是要使该应用程序正常工作 它需要一个数据库 所以我正在尝试上传本地数据库 但不知道如何上传 谁能告诉我
  • 如何在 条目中获取红色星号

    如何在条目中添加红色星号 以便可以将其显示在文本末尾以指示其为必填字段 例如 输入您的姓名 星号将为红色 或者 就此而言 文本中的任何位置 您无法通过 xml 字符串资源来做到这一点 这只能通过代码来完成 为此 您需要使用Spannable
  • 将 mysql 跳过网络设置为关闭

    我正在尝试设置我的 Ubuntu 12 10 服务器以接受远程 mysql 连接 但是我在将跳过网络设置为关闭时遇到困难 注意我已经将绑定地址设置为面向互联网的 IP 而不是 127 0 0 1 当我查看 etc mysql my conf
  • jQuery.parseJSON 与 JSON.parse

    jQuery parseJSON and JSON parse是执行相同任务的两个函数 如果 jQuery 库已经加载 将使用jQuery parseJSON比使用更好JSON parse 在性能方面 如果是 为什么 如果不是 为什么不呢
  • 如何使用 Python 高效解析电子邮件而不触及附件

    我正在使用 Python imaplib Python 2 6 从 GMail 获取电子邮件 我用方法获取电子邮件的所有内容http docs python org library imaplib html imaplib IMAP4 fe
  • CSS 悬停与 JavaScript 鼠标悬停 [关闭]

    Closed 这个问题是基于意见的 目前不接受答案 有时我需要选择使用 CSS element hover 还是 JavaScript onmouseover 来控制页面上 html 元素的外观 考虑以下场景 其中 div 包装输入 div
  • SVG 图像在 IE9 中不会被裁剪

    以下代码 div style border solid 1px black height 100px width 100px div
  • Scala:合并地图

    如何合并地图 如下所示 Map1 Map 1 gt Class1 1 2 gt Class1 2 Map2 Map 2 gt Class2 1 3 gt Class2 2 合并后 Merged Map 1 gt List Class1 1
  • 空列表到可见性转换器

    我正在尝试为 WPF 做一个 空列表到可见性转换器 这是一个 IValueConverter 它接受一个对象 应该是一个列表 如果列表为空 或者传递的对象为 null 它应该返回 Visibility Collapsed 如果列表不为空 则
  • 迄今为止的 Swift ISO8601 格式

    我有以下字符串 20180207T124600Z 如何将其转换为 Date 对象 这是我当前的代码 但它返回nil let dateString 20180207T124600Z let dateFormatter ISO8601DateF
  • Spring Web 响应式客户端

    我正在尝试使用 Spring Reactive WebClient 将文件上传到 spring 控制器 控制器非常简单 如下所示 PostMapping value upload consumes MediaType MULTIPART F
  • Azure DevOps REST api - 使用变量运行管道

    我在 Azure Devops 上有一个管道 我尝试使用 REST api 以编程方式 无头运行 https learn microsoft com en us rest api azure devops pipelines runs ru
  • 从嵌入 iframe 代码获取 YouTube 视频 ID

    我想使用 preg match 或正则表达式从 YouTube 嵌入代码获取 YouTube 视频 ID 举个例子 我要拿身份证0gugBiEkLwU 谁能告诉我该怎么做 真的很适合你的帮助 将此模式与捕获组一起使用应该会为您提供所需的字符
  • 我的 onNewIntent 没有调用

    创建一个集成 Twitter 的应用程序 我使用这个教程 http blog blundell apps com sending a tweet package com blundell tut ttt import android app
  • 访问事件以从源自标签 onclick 属性的自定义函数调用 Preventdefault

    我有这样的链接 a href a click a href a click 我想做一个preventDefault inside myfunc 因为一个 单击链接时将添加到地址栏中 不做return false or href javasc
  • C# 2010,ODP.net,调用存储过程传递数组

    我有一个需要 4 个输入的 PL SQL 存储过程 这些输入之一是关联数组 Oracle 类型 PLS INTEGER 索引的 VARCHAR2 1 表 我想要一个 C 程序 使用正确的输入 包括关联数组 调用此存储过程 我将 ODP ne