zoukankan      html  css  js  c++  java
  • ORA24381: error(s) in array DML

    使用ODP.NET 批量插入时,将cmd.ArrayBindCount 设置为10万时出错,经搜索得知,原来 使用array DML operations一次最多插入65535条=2^16。但是据我实验一次最多插入65534条。

    本人使用的是Oracle 10.1.0.2。不知道之后的版本修复了没有!

    以下是插入6万条记录,各种方法花费的时间。

    ordinaryInsert
    1 static void ordinaryInsert(int[] ids, string[] names)
    2 {
    3 using (OracleConnection connection = new OracleConnection(connectString))
    4 {
    5 connection.Open();
    6 using (OracleCommand cmd = connection.CreateCommand())
    7 {
    8 string sqlInsert = "insert into person values(:pId,:name)";
    9 cmd.CommandText = sqlInsert;
    10 OracleParameter paraId =
    11 cmd.Parameters.Add("pId", OracleDbType.Int32);
    12 paraId.Direction = ParameterDirection.Input;
    13 OracleParameter paraName =
    14 cmd.Parameters.Add("name", OracleDbType.NVarchar2, 50);
    15 paraName.Direction = ParameterDirection.Input;
    16
    17 Stopwatch watch = new Stopwatch();
    18 watch.Start();
    19
    20 for (int i = 0; i < ids.Length; i++)
    21 {
    22 paraId.Value = ids[i];
    23 paraName.Value = names[i];
    24
    25 cmd.ExecuteNonQuery();
    26 }
    27
    28 watch.Stop();
    29 Console.WriteLine("ellapsed time {0} ms", watch.ElapsedMilliseconds);
    30 }
    31 }
    32 }

    ellapsed time 67309 ms

    batchInsert
    1 static void batchInsert(int[] ids, string[] names)
    2 {
    3 using (OracleConnection connection = new OracleConnection(connectString))
    4 {
    5 connection.Open();
    6 using (OracleCommand cmd = connection.CreateCommand())
    7 {
    8 string sqlInsert = "insert into person values(:pId,:name)";
    9 cmd.CommandText = sqlInsert;
    10 cmd.ArrayBindCount = ids.Length;
    11 OracleParameter paraId =
    12 cmd.Parameters.Add("pId", OracleDbType.Int32);
    13 paraId.Direction = ParameterDirection.Input;
    14 OracleParameter paraName =
    15 cmd.Parameters.Add("name", OracleDbType.NVarchar2, 50);
    16 paraName.Direction = ParameterDirection.Input;
    17 paraId.Value = ids;
    18 paraName.Value = names;
    19
    20 Stopwatch watch = new Stopwatch();
    21 watch.Start();
    22 cmd.ExecuteNonQuery();
    23 watch.Stop();
    24 Console.WriteLine("ellapsed time {0} ms", watch.ElapsedMilliseconds);
    25 }
    26 }
    27 }

    ellapsed time 923 ms

    batchInsertViaProcedure
    1 static void batchInsertViaProcedure(int[] ids, string[] names)
    2 {
    3 using (OracleConnection connection = new OracleConnection(connectString))
    4 {
    5 connection.Open();
    6 using (OracleCommand cmd = connection.CreateCommand())
    7 {
    8 cmd.CommandText = "insertPerson";
    9 cmd.CommandType = CommandType.StoredProcedure;
    10 cmd.ArrayBindCount = ids.Length;
    11 OracleParameter paraId =
    12 cmd.Parameters.Add("p_pId", OracleDbType.Int32);
    13 paraId.Direction = ParameterDirection.Input;
    14 OracleParameter paraName =
    15 cmd.Parameters.Add("p_name", OracleDbType.NVarchar2, 50);
    16 paraName.Direction = ParameterDirection.Input;
    17
    18 paraId.Value = ids;
    19 paraName.Value = names;
    20
    21 Stopwatch watch = new Stopwatch();
    22 watch.Start();
    23 cmd.ExecuteNonQuery();
    24 watch.Stop();
    25 Console.WriteLine("ellapsed time {0} ms", watch.ElapsedMilliseconds);
    26 }
    27 }
    28 }

    ellapsed time 5116 ms

    batchInsert和batchInsertViaProcedure花费时间少于ordinaryInsert是毋庸置疑的,但是batchInsertViaProcedure却比batchInsert花费更长的时间有点不能理解。难道预编译存储在数据库中的存储过程比在程序库缓冲区Oracle SQL sharing中的语句执行的更慢?难道Oracle中没有缓存procedure的可执行代码,导致每次调用都要加载,还是函数调用开销?不知道,留着疑问慢慢摸索O(∩_∩)O~

    最后谢谢http://www.cnblogs.com/isline/archive/2010/08/31/1813722.html,文章不错!

  • 相关阅读:
    HDFS进阶
    sql 自连接 优化
    爬虫初探-笔趣阁小说下载
    Uos 系统访问局域网下的windows 系统文件
    统信Uos 操作系统--ThinkPad x280 机 安装后无法调节亮度
    Hadoop源码分析-hdfs(2)-NameNode类探索
    Hadoop源码分析-hdfs(1)-启动脚本分析
    设计模式学习笔记(4)-接口和抽象类
    设计模式学习笔记(3)-面向对象与面向过程
    设计模式学习笔记(2)-面向对象基本概念和四大特性
  • 原文地址:https://www.cnblogs.com/freewater/p/2063364.html
Copyright © 2011-2022 走看看