0

I've data in DataTable with 2 rows and 3 columns. I want to insert that data into Oracle table.

How can I insert? please give me with some example.

And also

How can I pass datatable to storedprocedure in ORACLE...

I pass datatable in below mensioned manner, but datatable type problem is comming. how can I solve this?

cmd.Parameters.Add("@Details",dtSupplier);   
(OR)  
cmd.Parameters.Add("Details", DbType.Single).Value = dtSupplier.ToString();
1
  • Can you provide the "type problem" you see? It will help people who want to assist you with the problem. Commented Dec 13, 2012 at 7:14

7 Answers 7

2

want to insert dataset or a datatable into ORACLE,

  1. create an ORACLE data adapter.
  2. create a command object for insertion,
  3. set the CommandType to StoredProcedure.
  4. Update command of the data adapter,
  5. pass the dataset or datatable as parameter.

like this:

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

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

OR

if above dont work than pass datatable as xml prameter than than process it

For details check : ADO.NET DataTable as XML parameter to an Oracle/SQL Server Database Stored Procedure

OR

Check this thread on Oracle site : Thread: Pass data table to Oracle stored procedure

Check existing answer : How to Pass datatable as input to procedure in C#?

Sign up to request clarification or add additional context in comments.

2 Comments

I have never passed a dataset or datatable in the procedure. Can you give some example of procedure which takes any of the above too and update.
@krshekhar - have look to this stackoverflow.com/questions/12025085/…
2

I'm very late for this answer, but I elaborated a bit to have some more readable (I hope) code, and to avoid all those .ToString() for the values so nulls and other less common values can be handled; here it is:

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";

Hope this can be still useful to somebody

Comments

0

The best idea would be follow the step mentioned below

  1. Create a transaction
  2. Begin the transaction
  3. Loop through you data table
  4. call your procedure
  5. If no error occurred commit transaction
  6. else roll back transaction

Comments

0

Regarding this part of your question:

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

What is the type of the "Details" parameter? Is it a Single? Then you would have to pick one (1) value from your DataTable and pass it to your parameter, something like dtSupplier.Rows[0]["col"].
If you use dtSupplier.ToString() you are just making a string of the entire DataTable (which i guess will always be the type name of DataTable).

Comments

0

First of all, you need to add Oracle.DataAccess.dll as reference in Visual Studio. In most cases, you can find this dll in the directory C:\ProgramData\Oracle11g\product\11.2.0\client_1\ODP.NET\bin\2.x\Oracle.DataAccess.dll

If just you need to insert the records from DataTable to Oracle table, then you can call the below function. Consider that your DataTable name is dt.

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

1. Without using Oracle Parameters(special character non-safe)

The definition of the function is given below. Here, we are just making the query dynamic for passing this as a sql statement to the InsertWithQuery function.

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 = "";
    }
}

The code for InsertWithQuery function is given below. Here, in the connection string you have to place you database details like Host,Username,Password etc.

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. With using Oracle Parameters(special character safe)
This can handle special characters like single quotes like scenarios in the column values.

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();
    }
}

And the InsertWithParams is given below

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;
}

Comments

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);
                }

Comments

0

I know it's been a big WHILE upon the matter, but the same need: "to insert data from a datatable to an Oracle table" has happened to me. I found this thread. I also tried the answers and came to the conclusion that executing a

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

in a loop, is bad. Reeaaally bad. The first thing that is bad is performance, the second is unnecessary complexity, the third is unnecessary Oracle Objects (stored proc). The time it takes to complete, lets say 200 rows, is almost 1 minute and that's me rounding it down. So in the hope that someone else will find this helpful here's my experience.

I got stubborn and searched some more, so I found out this, true it's from 2018. But I'm in 2021 myself...

So the base code is:

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();
}

This should match a raw oracle DDL performance:

create table table_name as select * from other_table_name

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.