principlecsharpMinor
Compare Oracle Table with SQL Server Table and Update/Insert
Viewed 0 times
updateinsertwithsqlandcompareserveroracletable
Problem
Below is the current code which is used to update/insert records from Oracle view to SQL Server table using Dapper. There is not a field to check last record updated date in the oracle view so I have added a method to get hashcode by using property values. Since Oracle table has more than 15k records and each record has more more than 60 columns, this approach take more than 5 minutes. Any ideas/suggestions to improve below code?
```
using System;
using System.Configuration;
using System.Data.OracleClient;
using System.Data.SqlClient;
using System.Linq;
using System.Reflection;
using Dapper;
namespace SyncSQLSvrWithHRDB
{
internal class Program
{
public static PropertyInfo[] PropertyNames = typeof(Employee).GetProperties();
private static void Main(string[] args)
{
var OracleConStr = ConfigurationManager.ConnectionStrings["OracleCon"].ConnectionString;
var SqlSvrConStr = ConfigurationManager.ConnectionStrings["SqlSvrCon"].ConnectionString;
using (OracleConnection OraCon = new OracleConnection(OracleConStr))
{
var res = OraCon.Query(Constants.SelectSql).ToList();
res = res.GroupBy(x => x.EmpNumber.ToUpper()).Select(x => x.LastOrDefault()).ToList();
using (SqlConnection Sqlcon = new SqlConnection(SqlSvrConStr))
{
Sqlcon.Open();
for (int i = 0; i (Constants.SelectEmpSql, new { EmpNumber= res[i].EmpNumber}).FirstOrDefault();
if (item == null) // new record found
{
Sqlcon.Execute(Constants.InsertSql, res[i]);
}
else if (GetHashcode(res[i]) != GetHashcode(item)) // record updated
{
Sqlcon.Execute(Constants.UpdateSql, res[i]);
}
}
}
}
}
```
using System;
using System.Configuration;
using System.Data.OracleClient;
using System.Data.SqlClient;
using System.Linq;
using System.Reflection;
using Dapper;
namespace SyncSQLSvrWithHRDB
{
internal class Program
{
public static PropertyInfo[] PropertyNames = typeof(Employee).GetProperties();
private static void Main(string[] args)
{
var OracleConStr = ConfigurationManager.ConnectionStrings["OracleCon"].ConnectionString;
var SqlSvrConStr = ConfigurationManager.ConnectionStrings["SqlSvrCon"].ConnectionString;
using (OracleConnection OraCon = new OracleConnection(OracleConStr))
{
var res = OraCon.Query(Constants.SelectSql).ToList();
res = res.GroupBy(x => x.EmpNumber.ToUpper()).Select(x => x.LastOrDefault()).ToList();
using (SqlConnection Sqlcon = new SqlConnection(SqlSvrConStr))
{
Sqlcon.Open();
for (int i = 0; i (Constants.SelectEmpSql, new { EmpNumber= res[i].EmpNumber}).FirstOrDefault();
if (item == null) // new record found
{
Sqlcon.Execute(Constants.InsertSql, res[i]);
}
else if (GetHashcode(res[i]) != GetHashcode(item)) // record updated
{
Sqlcon.Execute(Constants.UpdateSql, res[i]);
}
}
}
}
}
Solution
One thing I would say is that you don't need to create those connection string variables, you are only using them once in this program and you have them nicely hidden where they should be, so you can just call them when you use them, which in this case is once.
so instead of this
Do this instead
You have already named them nicely so you know exactly what they are, meaning there is no reason to create variables for these, they are only used once.
and instead of a for loop here:
you could use a foreach loop
This is a little bit cleaner and is more straight to the point about what you are doing. I would probably change some variable names around, but I will let you have that fun.
so instead of this
var OracleConStr = ConfigurationManager.ConnectionStrings["OracleCon"].ConnectionString;
var SqlSvrConStr = ConfigurationManager.ConnectionStrings["SqlSvrCon"].ConnectionString;
using (OracleConnection OraCon = new OracleConnection(OracleConStr))
{
var res = OraCon.Query(Constants.SelectSql).ToList();
res = res.GroupBy(x => x.EmpNumber.ToUpper()).Select(x => x.LastOrDefault()).ToList();
using (SqlConnection Sqlcon = new SqlConnection(SqlSvrConStr))
{Do this instead
using (OracleConnection OraCon = new OracleConnection(ConfigurationManager.ConnectionStrings["OracleCon"].ConnectionString))
{
var res = OraCon.Query(Constants.SelectSql).ToList();
res = res.GroupBy(x => x.EmpNumber.ToUpper()).Select(x => x.LastOrDefault()).ToList();
using (SqlConnection Sqlcon = new SqlConnection(ConfigurationManager.ConnectionStrings["SqlSvrCon"].ConnectionString))
{You have already named them nicely so you know exactly what they are, meaning there is no reason to create variables for these, they are only used once.
and instead of a for loop here:
using (SqlConnection Sqlcon = new SqlConnection(SqlSvrConStr))
{
Sqlcon.Open();
for (int i = 0; i (Constants.SelectEmpSql, new { EmpNumber= res[i].EmpNumber}).FirstOrDefault();
if (item == null) // new record found
{
Sqlcon.Execute(Constants.InsertSql, res[i]);
}
else if (GetHashcode(res[i]) != GetHashcode(item)) // record updated
{
Sqlcon.Execute(Constants.UpdateSql, res[i]);
}
}
}you could use a foreach loop
using (SqlConnection Sqlcon = new SqlConnection(SqlSvrConStr))
{
Sqlcon.Open();
foreach (var record in res)
{
var item = Sqlcon.Query(Constants.SelectEmpSql, new { EmpNumber= record.EmpNumber}).FirstOrDefault();
if (item == null) // new record found
{
Sqlcon.Execute(Constants.InsertSql, record);
}
else if (GetHashcode(record) != GetHashcode(item)) // record updated
{
Sqlcon.Execute(Constants.UpdateSql, record);
}
}
}This is a little bit cleaner and is more straight to the point about what you are doing. I would probably change some variable names around, but I will let you have that fun.
Code Snippets
var OracleConStr = ConfigurationManager.ConnectionStrings["OracleCon"].ConnectionString;
var SqlSvrConStr = ConfigurationManager.ConnectionStrings["SqlSvrCon"].ConnectionString;
using (OracleConnection OraCon = new OracleConnection(OracleConStr))
{
var res = OraCon.Query<Employee>(Constants.SelectSql).ToList();
res = res.GroupBy(x => x.EmpNumber.ToUpper()).Select(x => x.LastOrDefault()).ToList();
using (SqlConnection Sqlcon = new SqlConnection(SqlSvrConStr))
{using (OracleConnection OraCon = new OracleConnection(ConfigurationManager.ConnectionStrings["OracleCon"].ConnectionString))
{
var res = OraCon.Query<Employee>(Constants.SelectSql).ToList();
res = res.GroupBy(x => x.EmpNumber.ToUpper()).Select(x => x.LastOrDefault()).ToList();
using (SqlConnection Sqlcon = new SqlConnection(ConfigurationManager.ConnectionStrings["SqlSvrCon"].ConnectionString))
{using (SqlConnection Sqlcon = new SqlConnection(SqlSvrConStr))
{
Sqlcon.Open();
for (int i = 0; i < res.Count; i++)
{
var item = Sqlcon.Query<Employee>(Constants.SelectEmpSql, new { EmpNumber= res[i].EmpNumber}).FirstOrDefault();
if (item == null) // new record found
{
Sqlcon.Execute(Constants.InsertSql, res[i]);
}
else if (GetHashcode(res[i]) != GetHashcode(item)) // record updated
{
Sqlcon.Execute(Constants.UpdateSql, res[i]);
}
}
}using (SqlConnection Sqlcon = new SqlConnection(SqlSvrConStr))
{
Sqlcon.Open();
foreach (var record in res)
{
var item = Sqlcon.Query<Employee>(Constants.SelectEmpSql, new { EmpNumber= record.EmpNumber}).FirstOrDefault();
if (item == null) // new record found
{
Sqlcon.Execute(Constants.InsertSql, record);
}
else if (GetHashcode(record) != GetHashcode(item)) // record updated
{
Sqlcon.Execute(Constants.UpdateSql, record);
}
}
}Context
StackExchange Code Review Q#31673, answer score: 7
Revisions (0)
No revisions yet.