C# Windows 窗体使用 OracleDataAdapter 从系统数据表向 Oracle 表插入行

Posted

技术标签:

【中文标题】C# Windows 窗体使用 OracleDataAdapter 从系统数据表向 Oracle 表插入行【英文标题】:C# Windows Form using OracleDataAdapter to insert rows to a Oracle Table from a System DataTable 【发布时间】:2017-04-12 22:25:10 【问题描述】:

我正在编写一个填充 DataTable 的 Windows 窗体,我希望它插入到 Oracle 表中。我在这里看到了一些使用 OracleDataAdapter 执行此操作的示例,因此我不必遍历所有记录。该代码没有任何错误,但是当我使用 Toad 检查表格时(我确实刷新了),我没有看到它。我用了下面的例子 Update and insert records into Oracle table using OracleDataAdapter from DataTable 以下是我的 DataTable 的制作方法:

    public DataTable dtMain = new DataTable();

    public void FillTable(DataTable dt)
    
        dtMain.Columns.Add("SERIAL", typeof(System.String));
        dtMain.Columns.Add("LOCATION", typeof(System.String));
        dtMain.Columns.Add("UPC", typeof(System.String));
        dtMain.Columns.Add("PRODUCT", typeof(System.String));
        dtMain.Columns.Add("CREATED_BY", typeof(System.String));
        dtMain.Columns.Add("CREATED_DATE", typeof(System.DateTime));
        dtMain.Columns.Add("SKU", typeof(System.String));
        dtMain.Columns.Add("MAN_DATE", typeof(System.DateTime));
        dtUpload.Columns[0].Unique = true;
        dtMain.Merge(dt);

    

这就是我尝试插入数据库的方式

    private void btnUpload_Click(object sender, EventArgs e)
     
DataTable dt = new DataTable();
string strSelect = "SELECT serial, upc, man_date, location, product, created_by, created_date, serial from schema.table where rownum < 2";
string strInsert = "INSERT INTO schema.table (serial, upc, man_date, location, product, created_by, created_date, serial) VALUES (:serial, :upc, :man_date, :location, :product, :created_by, :created_date, :serial)";
string conStr = ConfigurationManager.ConnectionStrings["connection"].ConnectionString;
OracleConnection connection = new OracleConnection(conStr);
connection.Open();
if (connection.State != ConnectionState.Open)

    return;

try

    OracleDataAdapter adapterS = new OracleDataAdapter();
    adapterS.SelectCommand = new OracleCommand(strSelect, connection);
    adapterS.Fill(dt);
    dt.Rows.Remove(dt.Rows[0]);
    dt.Merge(dtUpload);

catch (Exception ex)

    string x = ex.Message + ex.StackTrace;
    throw;

for (int i = 0; dt.Rows.Count > i; i++)


    OracleDataAdapter adapter = new OracleDataAdapter();
    adapter.InsertCommand = new OracleCommand(strInsert, connection);
    adapter.InsertCommand.BindByName = true;

    OracleParameter pSerial = new OracleParameter(":serial", OracleDbType.Varchar2);
    pSerial.SourceColumn = dt.Columns[0].ColumnName;
    pSerial.Value = dtUpload.Rows[i][0];

    OracleParameter pLocation = new OracleParameter(":location", OracleDbType.Varchar2);
    pLocation.SourceColumn = dt.Columns[1].ColumnName;
    pLocation.Value = dtUpload.Rows[i][1];

    OracleParameter pUPC = new OracleParameter(":upc", OracleDbType.Date);
    pUPC.SourceColumn = dt.Columns[2].ColumnName;
    pUPC.Value = dtUpload.Rows[i][2];

    OracleParameter pProduct = new OracleParameter(":product", OracleDbType.Varchar2);
    pProduct.SourceColumn = dt.Columns[3].ColumnName;
    pProduct.Value = dtUpload.Rows[i][3];

    OracleParameter pCreatedBy = new OracleParameter(":created_by", OracleDbType.Varchar2);
    pCreatedBy.SourceColumn = dt.Columns[4].ColumnName;
    pCreatedBy.Value = dtUpload.Rows[i][4];

    OracleParameter pCreatedDate = new OracleParameter(":created_date", OracleDbType.Varchar2);
    pCreatedDate.SourceColumn = dt.Columns[5].ColumnName;
    pCreatedDate.Value = dtUpload.Rows[i][5];

    OracleParameter pSKU = new OracleParameter(":SKU", OracleDbType.Date);
    pSKU.SourceColumn = dt.Columns[6].ColumnName;
    pSKU.Value = dtUpload.Rows[i][6];

    OracleParameter pManDate = new OracleParameter(":man_date", OracleDbType.Varchar2);
    pManDate.SourceColumn = dt.Columns[7].ColumnName;
    pManDate.Value = dtUpload.Rows[i][7];

    adapter.InsertCommand.Parameters.Add(pSerial);
    adapter.InsertCommand.Parameters.Add(pLocation);
    adapter.InsertCommand.Parameters.Add(pUPC);
    adapter.InsertCommand.Parameters.Add(pProduct);
    adapter.InsertCommand.Parameters.Add(pCreatedBy);
    adapter.InsertCommand.Parameters.Add(pCreatedDate);
    adapter.InsertCommand.Parameters.Add(pserial);
    adapter.InsertCommand.Parameters.Add(pManDate);

try

    adapter.Update(dt);

catch (Exception ex)

    string x = ex.Message + ex.StackTrace;
    throw;

connection.Close();
connection.Dispose();

如果有人可以给我一些很棒的建议,我已经在谷歌上搜索了 2 天,我就是想不通。我敢打赌这很简单

更新:

感谢您的回复,我花了一点时间才回到这个项目。当我发布此内容时,我没有意识到我忘记包含我的选择语句。

对于 OracleParameter 值,我认为使用 SourceColumn 会将该列用作值。

我确实更新了 DataTable,序列号是唯一的。它仍然没有插入数据。如果我包含 Parameter.value 我会逐行循环来执行此操作吗?上面我用当前代码更正/更新了它。

第二次更新:

好的,我尝试循环访问参数以添加 DataTable 中的值,没有错误但仍然没有插入到数据库中。我知道我的连接字符串是正确的,因为选择查询有效。上面的代码已针对我所做的更改进行了更新。如果某位 Oracle 专家能够阐明我的问题,那么虚拟的高五正等着他们。

【问题讨论】:

【参考方案1】:

我从未使用过OracleDataAdapter,但我看到了这些可能的问题:

我认为您不能立即使用OracleDataAdapter,首先您必须从 Oracle 中选择一个现有表,然后根据此结果您可以对其执行更新/插入/删除。你的strSelect 字符串在哪里?我没看到。

您创建了所有OracleParameter,但我没有看到您为其分配了任何值,它们都是空的。在您进行任何插入之前,我希望得到类似 pOptoroLP.Value = ...; 的信息。

你应该定义一个唯一的,resp。像dt.Columns["SERIAL"].Unique = true; 这样的主键列,以便生成Update()Delete()Insert()可能不需要,我不知道。

您是否按照Data Provider for .NET Developer's Guide中的示例进行操作

【讨论】:

【参考方案2】:

我终于找到了问题,DataTable中的行状态需要处于Added状态才能工作。如果其他人有这个问题,这里是我的新代码,你可以将它与我试图做的比较。谢谢 Wernfried Domscheit 的 Oracle 部分,但事实证明是我的 DataTable 是问题,尽管设置 Unique 列也可能是一个问题,我没有检查。 OracleCommandBuilder 为我处理了插入语句和参数。

    private void btnUpload_Click(object sender, EventArgs e)

    DataTable dt = new DataTable();
    string strSelect = "SELECT serial, upc, man_date, location, product, created_by, created_date, serial from schema.table where rownum < 2";
    string strInsert = "INSERT INTO schema.table (serial, upc, man_date, location, product, created_by, created_date, serial) VALUES (:serial, :upc, :man_date, :location, :product, :created_by, :created_date, :serial)";
    string conStr = ConfigurationManager.ConnectionStrings["connection"].ConnectionString;
    OracleConnection connection = new OracleConnection(conStr);
    connection.Open();
    if (connection.State != ConnectionState.Open)
    
        return;
    
    OracleDataAdapter adapter = new OracleDataAdapter(strSelect, conStr);
    OracleCommandBuilder builder = new OracleCommandBuilder(adapter);
    adapter.Fill(dt);
    dt.Columns["SERIAL"].Unique = true;
    dt.Merge(dtUpload);
    dt.Rows.Remove(dt.Rows[0]);
    foreach (DataRow row in dt.Rows)
    
        row.SetAdded();
    

    try
    
        adapter.Update(dt);
    
    catch (Exception ex)
    
        string x = ex.Message + ex.StackTrace;
        throw;
    
    finally
    
        connection.Close();
        connection.Dispose();
    

【讨论】:

以上是关于C# Windows 窗体使用 OracleDataAdapter 从系统数据表向 Oracle 表插入行的主要内容,如果未能解决你的问题,请参考以下文章

C# 使用VS创建Windows窗体应用程序

如何使用 c# 从 Windows 窗体向用户显示默认的 Windows 身份验证提示?

如何使用 C# 在 Windows 窗体中创建 F1 帮助

C#使用Windows窗体实现发邮件功能

C#使用Windows窗体实现发邮件功能

如何将我的 VBA 宏转换为 C# 以在 Windows 窗体应用程序中使用?