【问题标题】:DategridView insert into another oracle Table C#DatagridView插入另一个oracle表C#
【发布时间】:2016-01-05 06:07:01
【问题描述】:

我有一个 46 列的 Datagridview,由 Date、Int 和 String 类型组成。我想将值插入另一个 oracle 表。

private void loopGrid()
    {
        foreach (DataGridViewRow datarow in this.dataGridView1.Rows)
        {
            writeRecord(datarow);
        }
    }

    private void writeRecord(DataGridViewRow datarow)
    {

        string sqlqry = "insert into Table  (Date,Number) values(:Date,:Number)";

        OracleCommand cmd = new OracleCommand(sqlqry, conn);
        cmd.Parameters.Add(new OracleParameter(":Date", datarow["DATE"]))
        cmd.Parameters.Add(new OracleParameter(":Number", datarow["Number"]));
        cmd.CommandText = sqlqry;
        cmd.ExecuteNonQuery();
    }

我不太明白我在传递参数时做错了什么。我对 C# 很陌生,将数据类型和值传递给另一个 oracle 表的正确方法是什么?

【问题讨论】:

    标签: c# oracle datagridview


    【解决方案1】:

    根据您使用的 Oracle 驱动程序,.Add 方法可能会出现重载,该方法接受该值作为第二个参数,或者可能存在显式执行此操作的 .AddWithValue 方法。我认为对于 ODP.net,您就像 .Add 一样正确。

    无论哪种方式,这些都会从值的数据类型派生数据类型。

    关于您的参数,您需要在调用参数时省略冒号: 字符。我知道在 SQL Server、Sybase、SQLite 和其他人中包含它们(在这些情况下为 @),但在 Oracle 中,您在参数声明期间将它们排除在外。有趣的是,我认为 PostgreSQL 接受任何一种方法。

    因此,我认为这会起作用:

    private void writeRecord(DataGridViewRow datarow)
    {
    
        string sqlqry = "insert into Table (Date,Number) values(:Date,:Number)";
    
        OracleCommand cmd = new OracleCommand(sqlqry, conn);
        cmd.Parameters.Add(new OracleParameter("Date", datarow["DATE"]))
        cmd.Parameters.Add(new OracleParameter("Number", datarow["Number"]));
        // cmd.CommandText = sqlqry;  -- not necessary, handled in constructor
        cmd.ExecuteNonQuery();
    }
    

    如果没有,可以尝试使用类型或值进行显式转换:

    呸:

    cmd.Parameters.Add(new OracleParameter("Date", Convert.ToDateTime(datarow["DATE"])))
    cmd.Parameters.Add(new OracleParameter("Number", Convert.ToDecimal(datarow["Number"])));
    

    更好:

    cmd.Parameters.Add(new OracleParameter("DATE", OracleDbType.Date,
        datarow["DATE"], ParameterDirection.Input);
    cmd.Parameters.Add(new OracleParameter("Number", OracleDbType.Decimal,
        datarow["Number"], ParameterDirection.Input));
    

    如果情况变得更糟,防弹(虽然冗长)的方法是:

    cmd.Parameters.Add(new OracleParameter("DATE", OracleDbType.Date));
    cmd.Parameters.Add(new OracleParameter("Number", OracleDbType.Decimal));
    cmd.Parameters[0].Value = datarow["DATE"];
    cmd.Parameters[1].Value = datarow["Number"];
    

    作为脚注,如果您要插入多行,则最后一种方式实际上是首选,因为您创建一次参数并修改值并多次执行插入:

    cmd.Parameters.Add(new OracleParameter("DATE", OracleDbType.Date));
    cmd.Parameters.Add(new OracleParameter("Number", OracleDbType.Decimal));
    
    foreach (DataRow datarow in datarows)
    {
        cmd.Parameters[0].Value = datarow["DATE"];
        cmd.Parameters[1].Value = datarow["Number"];
    
        cmd.ExecuteNonQuery();
    }
    

    -- 编辑--

    根据您的反馈和我改进的校对技巧,这是我的建议。我在其中添加了一笔交易以取得良好的效果:

    string sqlqry = "insert into Table  (Date,Number) values(:Date,:Number)";
    
    OracleTransaction trans = conn.BeginTransaction(IsolationLevel.ReadCommitted);
    OracleCommand cmd = new OracleCommand(sqlqry, conn, trans);
    cmd.Parameters.Add(new OracleParameter("DATE", OracleDbType.Date));
    cmd.Parameters.Add(new OracleParameter("Number", OracleDbType.Decimal));
    
    foreach (DataGridViewRow datarow in this.dataGridView1.Rows)
    {
        cmd.Parameters[0].Value = datarow.Cells["DATE"].Value;
        cmd.Parameters[1].Value = datarow.Cells["Number"].Value;
    
        cmd.ExecuteNonQuery();
    }
    
    trans.Commit();
    

    为了它的价值,你还需要一些异常处理。

    【讨论】:

    • 无法将 [] 索引应用于“System.Windows.Forms.DataGridViewRow”类型的表达式。 datarow["Number"] 下的红线。不识别,怎么办?
    • 哦,根据您的问题陈述,我假设 datarow 是 DataRow (System.Data.DataRow) - 我没有意识到它是一个网格行。我认为这就是您通常从网格行获取值的方式:datarow.Cells["Number"].Value。如果可行,请告诉我,我可以更新答案。
    • 是的,在我得到你的答案之前我就知道了,哈哈。我遇到的另一个问题是无限循环。我认为它会在读取数据网格的最后一行后停止,但它一直在无限运行。你知道为什么吗?非常感谢您的帮助!
    • 我在你的代码 sn-p 中看不到任何会导致这种情况的东西......我唯一的想法是你有一个事件正在触发 loopGrid(),它可能会基于某些东西触发它发生在loopGrid 内部。您可以发布更多代码吗?另外,很抱歉——您的示例中有正确的数据类型。我没注意。
    【解决方案2】:

    您可能想使用:

        cmd.Parameters.Add(new OracleParameter(DbType.Date, datarow["DATE"]))
        cmd.Parameters.Add(new OracleParameter(DbType.Double, datarow["Number"]));
    

    请看https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlparameter.dbtype(v=vs.110).aspx

    【讨论】:

      猜你喜欢
      • 2018-04-03
      • 1970-01-01
      • 2016-06-11
      • 1970-01-01
      • 2013-12-14
      • 2011-10-08
      • 2012-12-01
      • 2023-03-09
      相关资源
      最近更新 更多