3

我有一个dataTable包含一些记录的断开连接。

我正在使用以下函数来获取dataTable.

static System.Data.DataTable ReadSetUpTable(string queryStr,SqlConnection sc)
{
    try
    {
        var command = new SqlCommand()
                          {Connection = sc, CommandText = queryStr};
        var dataAdapter = new SqlDataAdapter() {SelectCommand = command};
        var dataTable = new System.Data.DataTable();
        dataAdapter.Fill(dataTable);
        return dataTable;
    }
    catch (Exception)
    {
        throw;
    }
} 

到目前为止没有任何问题。

我想知道的是是否可以dataTable使用不同的连接字符串轻松地将其填充到另一个模式中。

为了这篇文章,假设有一个包含两列的表

Create Table Student(StudentId NUMBER(6), StudentName varchar2(50));

我希望用dataTable上面代码中的内容填写此表。

我可以使用命令对象和插入语句来做到这一点。例如这段代码:

static int LoadDataTable(OracleConnection oc, System.Data.DataTable dataTable)
{
    try
    {
        var command = 
            new OracleCommand
            {
                CommandText = "INSERT INTO STUDENT (STUDENTID, STUDENTNAME) VALUES(:studentid, :studentname)",
                CommandType = CommandType.TableDirect,
                Connection = oc
            };
        var op1 = 
            new OracleParameter
            {
                ParameterName = "StudentId",
                Size = 6,
                OracleDbType = OracleDbType.Int32,
            Direction = System.Data.ParameterDirection.Input
            };
        command.Parameters.Add(op1);
        var op2 = 
        new OracleParameter
            {
                ParameterName = "studentName",
                OracleDbType = OracleDbType.Varchar2,
                Size = 50,
                Direction = System.Data.ParameterDirection.Input
            };
        command.Parameters.Add(op2);                                   
       /*
        foreach (var row in dataTable.Rows)
        {
            op1.Value = int.Parse(row[0].ToString());
            op2.Value = row[1].ToString();
            command.ExecuteNonQuery();
        }*/
            foreach (System.Data.DataRow row in dataTable.Rows)
            {
                row.SetAdded();
            }    

            var dataAdapter = new OracleDataAdapter() {InsertCommand = command};
            dataAdapter.Update(dataTable); //This updates the table, but all column values are NULL.

    }
    catch(Exception)
    {
        throw;
    }
} 

有没有更快更简单的方法让我不必遍历记录?

4

1 回答 1

2

在您的第一个代码块中,您正在设置SelectCommand. 还有一个InsertCommand, UpdateCommand, 和DeleteCommand

这些命令也存在于OracleDataAdapter对象上...由于DataTable是端点中立的,因此您需要做的就是创建一个OracleCommand来执行插入,将其设置为OracleDataAdapter's InsertCommand,然后调用oracleDataAdapter.Update(dataTable)

当我检查它们时,将用更多细节来修改它。


设置的一个很好的例子InsertCommandhere。请注意,当您向命令添加参数时,您传递给的最后一个值.Add( ... )是您要映射到的列的名称。

因为您将数据检索到 中DataTable,而不是更改它,所以您需要RowState在调用之前将每行的 'Added'更改为oracleDataAdapter.Update(). 你需要做这样的事情:

foreach (DataRow row in dataTable.Rows) {
    row.SetAdded();
}

如果您需要更多代码示例,请告诉我...从您发布的代码中,我认为您已经大致了解了我要去的地方。


编辑

创建 OracleParameters 时,需要将源列设置为 DataTable 中列的名称。默认情况下,这是 select 语句返回的名称,因此:

var op1 = new OracleParameter {
                                ParameterName = "StudentId",
                                Size = 6,
                                OracleDbType = OracleDbType.Int32,
                                Direction = System.Data.ParameterDirection.Input
                                SourceColumn = "StudentId" // If that's what it's called in the DataTable
                              };
command.Parameters.Add(op1);

AcceptChanges()方法在 上,DataTable属性HasErrors也是(它也存在于DataRows, 和DataSets, 上)。

AcceptChanges()只告诉 DataTable 您已经处理了对数据库的更新......当您调用时,更改将提交给数据库oracleDataAdapter.Update()。您调用的原因AcceptChanges()是重置行状态...否则下次更新 DataTable 时,您将尝试添加已添加的行。

AcceptChangesDuringUpdate上的属性OracleDataAdapter将作为更新数据库的一部分自动调用AcceptChanges()...我通常不这样做,因为我习惯于HasErrors在调用之前测试属性并处理这些属性AcceptChanges()...但是我正在AcceptChanges()阅读现在在更新时默认调用。我不熟悉如何处理错误行的详细信息,是否接受更改。

于 2011-04-26T20:02:53.510 回答