0

DataTable有 2 行 3 列的数据。我想将该数据插入Oracle表中。

我该如何插入?请给我一些例子。

并且

如何将数据表传递给ORACLE中的存储过程...

我以以下方式传递数据表,但数据表类型问题即将到来。我该如何解决这个问题?

cmd.Parameters.Add("@Details",dtSupplier);   
(OR)  
cmd.Parameters.Add("Details", DbType.Single).Value = dtSupplier.ToString();
4

7 回答 7

2

想要将数据集或数据表插入 ORACLE,

  1. 创建一个 ORACLE 数据适配器。
  2. 创建一个用于插入的命令对象,
  3. 将 CommandType 设置为 StoredProcedure。
  4. 数据适配器的更新命令,
  5. 将数据集或数据表作为参数传递。

像这样:

OracleDataAdapter da = new OracleDataAdapter();
OracleCommand cmdOra = new OracleCommand(StoredProcedureName, Connection);
cmdOra.CommandType = CommandType.StoredProcedure;

da.InsertCommand = cmdOra;
da.Update(dsDataSet);

或者

如果以上不起作用,则将数据表作为 xml 参数传递而不是处理它

有关详细信息,请查看:ADO.NET DataTable as XML parameter to an Oracle/SQL Server Database Stored Procedure

或者

在 Oracle 站点上查看此线程:线程:将数据表传递给 Oracle 存储过程

检查现有答案:如何将数据表作为输入传递给 C# 中的过程?

于 2012-12-13T06:59:48.757 回答
1

这个答案我很晚了,但我详细说明了一些更易读(我希望)的代码,并避免所有这些.ToString()值,以便null可以处理 s 和其他不太常见的值;这里是:

public void Copy(String tableName, DataTable dataTable)
{
    var insert = $"insert into {tableName} ({GetColumnNames(dataTable)}) values ({GetParamPlaceholders(dataTable)})";
    using (var connection = /*a method to get a new open connection*/)
    {       
        for (var row = 0; row < dataTable.Rows.Count; row++)
        {
            InsertRow(dataTable, insert, connection, row);
        }
    }
}

private static void InsertRow(DataTable dataTable, String insert, OracleConnection connection, Int32 row)
{
    using (var command = new OracleCommand(insert, connection))
    {
        AssembleParameters(dataTable, command, row);
        command.ExecuteNonQuery();
    }
}

private static void AssembleParameters(DataTable dataTable, OracleCommand command, Int32 row)
{
    for (var col = 0; col < dataTable.Columns.Count; col++)
    {
        command.Parameters.Add(ParameterFor(dataTable, row, col));
    }
}

private static OracleParameter ParameterFor(DataTable dataTable, Int32 row, Int32 col)
{
    return new OracleParameter(GetParamName(dataTable.Columns[col]), dataTable.Rows[row].ItemArray.GetValue(col));
}

private static String GetColumnNames(DataTable data) => (from DataColumn column in data.Columns select column.ColumnName).StringJoin(", ");

private static String GetParamPlaceholders(DataTable data) => (from DataColumn column in data.Columns select GetParamName(column)).StringJoin(", ");

private static String GetParamName(DataColumn column) => $":{column.ColumnName}_param";

希望这对某人仍然有用

于 2017-09-18T14:09:48.050 回答
0

最好的办法是按照下面提到的步骤

  1. 创建交易
  2. 开始交易
  3. 循环遍历您的数据表
  4. 打电话给你的程序
  5. 如果没有发生错误提交事务
  6. 否则回滚事务
于 2012-12-13T06:55:31.487 回答
0

关于你问题的这一部分:

cmd.Parameters.Add("@Details",dtSupplier);
(OR)
cmd.Parameters.Add("详细信息", DbType.Single).Value = dtSupplier.ToString();

“详细信息”参数的类型是什么?是单曲吗?然后,您必须从 DataTable 中选择一 (1) 个值并将其传递给您的参数,例如 dtSupplier.Rows[0]["col"]。
如果您使用 dtSupplier.ToString() 您只是在制作整个 DataTable 的字符串(我猜这将始终是 DataTable 的类型名称)。

于 2012-12-13T06:58:34.880 回答
0

我知道这件事很重要,但同样的需要:“将数据从数据表插入到 Oracle 表”发生在我身上。我找到了这个线程。我也尝试了答案并得出结论,执行

...
cmd.ExecuteNonQuery();
...

在一个循环中,是坏的。真的很糟糕。不好的第一件事是性能,第二是不必要的复杂性,第三是不必要的 Oracle 对象(存储过程)。完成(比如说 200 行)所需的时间几乎是 1 分钟,这就是我将其四舍五入。因此,希望其他人会发现这很有帮助,这是我的经验。

我很固执,又搜索了一些,所以我发现了这个,真的是从 2018 年开始的。但我自己也在 2021 年......

所以基本代码是:

using Oracle.ManagedDataAccess.Client; // you don't need other dll, just install this from nuget gallery
using System.Data;
public static void Datatable2Oracle(string tableName, DataTable dataTable)
{
    string connString = "connection string";
    OracleBulkCopy copy= new(connString, OracleBulkCopyOptions.UseInternalTransaction /*I don't know what this option does*/);
    copy.DestinationTableName = tableName; 
    copy.WriteToServer(dataTable);
    copy.Dispose();
}

这应该与原始 oracle DDL 性能相匹配:

create table table_name as select * from other_table_name
于 2021-07-12T14:18:28.263 回答
0

首先,您需要Oracle.DataAccess.dll在 Visual Studio 中添加为引用。大多数情况下,你可以在目录中找到这个dllC:\ProgramData\Oracle11g\product\11.2.0\client_1\ODP.NET\bin\2.x\Oracle.DataAccess.dll

如果只是需要将数据表中的记录插入到 Oracle 表中,则可以调用以下函数。考虑您的 DataTable 名称是dt.

string error = "";
int noOfInserts = DataTableToTable(dt,out error);

1.不使用Oracle参数(特殊字符不安全)

下面给出函数的定义。在这里,我们只是使查询动态化,以便将其作为 sql 语句传递给InsertWithQuery函数。

public int DataTableToTable(DataTable dt,out string error)
{
    error = "";
    for (int i = 0; i < dt.Rows.Count; i++)
    {
        finalSql = "INSERT INTO TABLENAME SELECT ";
        for (int j = 0; j < dt.Columns.Count; j++)
        {
            colValue += "'" + dt.Rows[i][j].ToString() + "',"; 
        }
        colValue = colValue.Remove(colValue.Length - 1, 1);
        finalSql += colValue + " FROM DUAL";
        InsertWithQuery(finalSql, out error);
        if (error != "")
           return error;
        inserts++;
        colValue = "";
    }
}

函数代码InsertWithQuery如下。在这里,您必须在连接字符串中放置数据库详细信息,例如主机、用户名、密码等。

public int InsertWithQuery(string query, out string error)
{
     error = "";
     int rowsInserted = 0;        
     if (error == "")
     {
          OracleConnection con = new OracleConnection("Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=)(PORT=)))(CONNECT_DATA=(SERVER=DEDICATED)(SID=)));User Id=;Password="); 
          OracleTransaction trans = con.BeginTransaction();              
          try
          {
              error = "";
              OracleCommand cmd = new OracleCommand();
              cmd.Transaction = trans;
              cmd.Connection = con;
              cmd.CommandText = query;
              rowsInserted = cmd.ExecuteNonQuery();
              trans.Commit();
              con.Dispose();
              return rowsInserted;
          }
          catch (Exception ex)
          {
              trans.Rollback();
              error = ex.Message;
              rowsInserted = 0;
          }
          finally
          {
              con.Dispose();
          }
     }
     return rowsInserted;
}

2.使用Oracle参数(特殊字符安全)
这可以处理列值中的单引号等特殊字符。

public int DataTableToTable(DataTable dt,out string error)
{
    error = "";
    string finalSql = "";
    List<string> colValue = new List<string>();
    List<string> cols = new List<string>() {"COLUMN1","COLUMN2","COLUMN3"};
    for (int i = 0; i < dt.Rows.Count; i++)
    {
         finalSql = "INSERT INTO TABLENAME(COLUMN1,COLUMN2,COLUMN3) VALUES(:COLUMN1,:COLUMN2,:COLUMN3) ";                    
         for (int j = 0; j < dt.Columns.Count; j++)
         {
             colValue.Add(dt.Rows[i][j].ToString());
         }                     
         objDAL.InsertWithParams(finalSql,colValue,cols, out error);
         if (error != "")
             return error;
         inserts++;
         colValue.Clear();
    }
}

下面InsertWithParams给出

public string InsertWithParams(string sql, List<string> colValue, List<string> cols, out string error)
{
     error = "";
     try
     {
         OracleConnection con = new OracleConnection("Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=)(PORT=)))(CONNECT_DATA=(SERVER=DEDICATED)(SID=)));User Id=;Password="); 
         OracleCommand command = new OracleCommand(sql, con);
         for (int i = 0; i < colValue.Count; i++)
         {
              command.Parameters.Add(new OracleParameter(cols[i], colValue[i]));
         }
         command.ExecuteNonQuery();
         command.Connection.Close();
    }
    catch (Exception ex)
    {
         error = ex.Message;
    }
    return null;
}
于 2017-03-28T19:03:32.607 回答
0
              try  {

                    //Suppose you have DataTable dt
                    string connectionString = @"Provider=Microsoft.ACE.OLEDB.12.0;" +
                                              @"Data Source='Give path of your access database file here';Persist Security Info=False";

                    OleDbConnection dbConn = new OleDbConnection(connectionString);
                    dbConn.Open();
                    using (dbConn)
                    {
                        int j = 0;
                        for (int i = 0; i < 2; i++)
                        {
                            OleDbCommand cmd = new OleDbCommand(
                            "INSERT INTO Participant_Profile ([column1], [column2] , [column3] ) VALUES (@c1 , @c2 , @c3 )", dbConn);
                            cmd.Parameters.AddWithValue("@c1", dt.rows[i][j].ToString());
                            cmd.Parameters.AddWithValue("@c2", dt.rows[i][j].ToString());
                            cmd.Parameters.AddWithValue("@c3", dt.rows[i][j].ToString());
                            cmd.ExecuteNonQuery();
                            j++;
                        }



                    }
                }
                catch (OleDbException exception)
                {
                    Console.WriteLine("SQL Error occured: " + exception);
                }
于 2017-03-28T19:48:26.563 回答