I have a problem with importing items from an MS Access .mdb database file into SQL Server. I wrote a C# application in practice database that extrapolates the data in a .mdb database and places them in a table in a SQL Server database.
My problem is that the .mdb database contains about 300,000 articles which are to be inserted with all of the controls inside the SQL Server database. The .mdb file is selected by the user.
How can I speed up the import of the articles?
This is my C# code:
dbConn = new OleDbConnection(#"Provider = Microsoft.Jet.OLEDB.4.0; Data Source=" + dialog.FileName + "; Persist Security Info = False; Jet OLEDB:Database Password = " + textBoxPwdComet.Text + "; Mode = Share Deny None");
// SqlConnection conn2 = db.apriconnessione();
try
{
string query = "SELECT CODMARCA,CODART,DESCR,UM,PRZNETTO,PRZCASA,DATAAGG FROM ARTICOLI";
string querycontalinee = "SELECT count(*) from ARTICOLI";
OleDbCommand command = new OleDbCommand(query, dbConn);
OleDbCommand commandcontalinee = new OleDbCommand(querycontalinee, dbConn);
dbConn.Open();
int linee = (int)commandcontalinee.ExecuteScalar();
OleDbDataReader reader = command.ExecuteReader();
Articolo a;
labelstatoaggiornamento.Show();
progressBarstatoaggiornamento.Show();
progressBarstatoaggiornamento.Style = ProgressBarStyle.Continuous;
progressBarstatoaggiornamento.Minimum = 0;
progressBarstatoaggiornamento.Maximum = linee;
progressBarstatoaggiornamento.Step = 1;
SqlConnection conn = db.apriconnessione();
while (reader.Read())
{
String CodMarca = "" + reader.GetValue(0).ToString();
String CodArt = "" + reader.GetValue(1).ToString().Replace("'", ""); ;
String Fornitore = "COMET";
String Descrizione = "" + reader.GetValue(2).ToString();
String UM = "" + reader.GetValue(3).ToString();
String PrezzoNetto = "" + reader.GetValue(4).ToString();
String PrezzoCasa = "" + reader.GetValue(5).ToString();
DateTime DataAggiornamento = DateTime.Now;
decimal Prezzo = Decimal.Parse(PrezzoNetto, System.Globalization.NumberStyles.Any);
decimal PrezzoListino = Decimal.Parse(PrezzoCasa, System.Globalization.NumberStyles.Any);
a = new Articolo(CodArt, CodMarca);
a.db = db;
if (a.ControlloDisponibilitàCOMET() == true)
{
string queryAggiornamento = "Update Articolo Set Descrizione='" + Descrizione + "', UM='" + UM + "', Prezzo='" + Prezzo + "',PrezzoListino='" + PrezzoListino + "',DataAggiornamento='" + DataAggiornamento + "',Stato='Aggiornamentoincorso' Where CodMarca = '" + CodMarca + "' AND CodArt = '" + CodArt + "' AND Importato = 'COMET' and Fornitore='COMET' ";
SqlCommand commaggiorna = new SqlCommand(queryAggiornamento, conn);
try
{
commaggiorna.ExecuteNonQuery();
}
catch (Exception ex)
{
Console.WriteLine(" " + ex);
}
}
else
{
string query2 = "INSERT INTO Articolo (CodMarca, CodArt, Fornitore, Importato, Descrizione, UM, Prezzo, PrezzoListino, Stato) VALUES (#CodMarca, #CodArt, #Fornitore, #Importato, #Descrizione, #UM, #Prezzo, #PrezzoListino, #Stato)";
SqlCommand myCommand = new SqlCommand(query2, conn);
myCommand.Parameters.AddWithValue("#CodMarca", CodMarca);
myCommand.Parameters.AddWithValue("#CodArt", CodArt);
myCommand.Parameters.AddWithValue("#Fornitore", Fornitore);
myCommand.Parameters.AddWithValue("#Importato", Fornitore);
myCommand.Parameters.AddWithValue("#Descrizione", Descrizione);
myCommand.Parameters.AddWithValue("#UM", UM);
decimal PrezzoNetto2 = Decimal.Parse(PrezzoNetto, System.Globalization.NumberStyles.Any);
myCommand.Parameters.AddWithValue("#Prezzo", PrezzoNetto2);
decimal PrezzoCasa2 = Decimal.Parse(PrezzoCasa, System.Globalization.NumberStyles.Any);
myCommand.Parameters.AddWithValue("#PrezzoListino", PrezzoCasa2);
DateTime dt = Convert.ToDateTime(DataAggiornamento);
myCommand.Parameters.AddWithValue("#Stato", "Aggiornamentoincorso");
myCommand.ExecuteNonQuery();
}
progressBarstatoaggiornamento.PerformStep();
int percent = (int)(((double)progressBarstatoaggiornamento.Value / (double)progressBarstatoaggiornamento.Maximum) * 100);
progressBarstatoaggiornamento.CreateGraphics().DrawString(percent.ToString() + "%", new Font("Arial", (float)8.25, FontStyle.Regular), Brushes.Black, new PointF(progressBarstatoaggiornamento.Width / 2 - 10, progressBarstatoaggiornamento.Height / 2 - 7));
}
string queryNonDisponibili = "Update Articolo Set Stato='Nondisponibile' where Stato!='Aggiornamentoincorso' AND Fornitore='COMET' AND Importato='COMET'";
string queryNonDisponibili2 = "Update Articolo Set Stato='Disponibile' where Stato='Aggiornamentoincorso' AND Fornitore='COMET' AND Importato='COMET'";
SqlCommand comm = new SqlCommand(queryNonDisponibili, conn);
SqlCommand comm2 = new SqlCommand(queryNonDisponibili2, conn);
comm.ExecuteNonQuery();
comm2.ExecuteNonQuery();
Console.WriteLine("\n Passaggio Completato");
conn.Close();
db.chiudiconnessione();
dbConn.Close();
}
catch (Exception ex)
{
MessageBox.Show("La password è errata oppure " + ex);
}
Consider using SqlBulkCopy. Since you are running sql queries I would suggest you'd work server side as much as possible. Create a temp table in Sql Server, add all records to a datatable or array of datarows and use SqlBulkCopy to import. I think that is the fastest way to move all records to Sql Server.
From there you can synchronize the two tables in Sql Server with only a few queries.
I would use SqlBulkCopy ...
dbConn = new OleDbConnection(#"Provider = Microsoft.Jet.OLEDB.4.0; Data Source=" + dialog.FileName + "; Persist Security Info = False; Jet OLEDB:Database Password = " + textBoxPwdComet.Text + "; Mode = Share Deny None");
SqlConnection conn2 = db.apriconnessione();
string query = "SELECT CODMARCA,CODART,DESCR,UM,PRZNETTO,PRZCASA,DATAAGG FROM ARTICOLI";
OleDbDataAdapter da = new OleDbDataAdapter(query,dbConn);
DataTable dt = new DataTable();
da.Fill(dt);
conn2.Open();
SqlBulkCopy bulk = new SqlBulkCopy(conn2);
bulk.DestinationTableName = "ARTICOLI";
bulk.WriteToServer(dt);
conn2.close();
Related
so I have this program which when I press a button inserts a record into an excel spreadsheet with, the columns, being , customer, product, weight, dateTime. Now I want to be able to update a record if the same customer, and product occurs, but I also want to add the previous weight field with the new field, and update the time.
The problem is i'm not sure how to modify my update statement to do this.
// Load data from database, and Update database if filed already exists
DataSet ds = new DataSet();
string insertquery = "SELECT * FROM [Sheet1$] where [Customer] = '" + lblcustomername + " ' ";
OleDbConnection myConnection = new OleDbConnection(OutputDatabaseConnectionString); //define new connection object
OleDbDataAdapter mydataadapter = new OleDbDataAdapter(insertquery, myConnection); //define data adaptor and select column data from spreadsheet
mydataadapter.Fill(ds);
int i = ds.Tables[0].Rows.Count;
// If item exists in database, update it
if (i > 0)
{
try
{
System.Data.OleDb.OleDbConnection myConnection2; //create new connection object
System.Data.OleDb.OleDbCommand myCommand = new System.Data.OleDb.OleDbCommand();
String sql = null;
myConnection2 = new System.Data.OleDb.OleDbConnection(OutputDatabaseConnectionString); //define connection string
myConnection2.Open();
myCommand.Connection = myConnection2;
sql = "UPDATE [Sheet1$] SET [Net Weight(Kg)]= '" + textBox1.Text + "' WHERE [Customer] = '" + lblcustomername + "'";
myCommand.CommandText = sql;
myCommand.ExecuteNonQuery();
myConnection2.Close();
myConnection2.Close(); //close connection
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
// if it doesn't exist update database
try
{
System.Data.OleDb.OleDbConnection myConnection1; //create new connection object
System.Data.OleDb.OleDbCommand myCommand = new System.Data.OleDb.OleDbCommand();
String sql = null;
myConnection1 = new System.Data.OleDb.OleDbConnection(OutputDatabaseConnectionString); //define connection string
myConnection1.Open();
myCommand.Connection = myConnection1;
sql = sql = "INSERT INTO [Sheet1$] ([Customer],[Product],[Net Weight(Kg)], [DateTime]) VALUES('" + lblcustomername.Text + "','" + lblproductname.Text + "','" + textBox1.Text + "','" + (DateTime.Now).ToString() + "')";
myCommand.CommandText = sql;
myCommand.ExecuteNonQuery();
myConnection1.Close();
myConnection1.Close(); //close connection
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
I've been working on this function to take a user selected csv file and parse it into an access database. After much trial and error and reading here, the thing will compile and run without crashing but no values are being inserted into the table. This I where I am at currently.
private void openFileDialog1_FileOk(object sender, CancelEventArgs e)
{
productFileName = productOpenDialog.SafeFileName;
productFilePath = Path.GetDirectoryName(productOpenDialog.FileName);
string connectionString = String.Format("Provider = Microsoft.ACE.OLEDB.12.0; Data Source ={0}"+"\\VendorDB.accdb;Persist Security Info = False;", Environment.CurrentDirectory);
string selectSQL = String.Format(#"SELECT * FROM [" + productFileName + "]");
using (OleDbConnection connection = new OleDbConnection(String.Format(#"Provider = Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=Text;", productFilePath)))
{
using (OleDbCommand command = new OleDbCommand(selectSQL, connection))
{
using (OleDbDataAdapter adapter = new OleDbDataAdapter(command))
{
DataTable dataTable = new DataTable();
adapter.Fill(dataTable);
//create connection to Access DB
OleDbConnection DBconn = new OleDbConnection(connectionString);
OleDbCommand cmd = new OleDbCommand();
//set cmd settings
cmd.Connection = DBconn;
//cmd.CommandType = CommandType.Text;
//open DB connection
DBconn.Open();
//read each row in the Datatable and insert that record into the DB
for (int i = 0; i < dataTable.Rows.Count; i++)
{
cmd.CommandText = "INSERT INTO Product_List (ProductID, ProductName, Description, InventoryItem, Price, CaseSize, SalespersonID)" +
" VALUES ('" + dataTable.Rows[i].ItemArray.GetValue(0) + "','" + dataTable.Rows[i].ItemArray.GetValue(1) + "','" + dataTable.Rows[i].ItemArray.GetValue(2) +
"','" + dataTable.Rows[i].ItemArray.GetValue(3) + "','" + dataTable.Rows[i].ItemArray.GetValue(4) + "','" + dataTable.Rows[i].ItemArray.GetValue(5) +
"','" + dataTable.Rows[i].ItemArray.GetValue(6) + "')";
cmd.ExecuteNonQuery();
}
//close DB.connection
DBconn.Close();
}
}
}
}
I am aware that datatypes in fields might be an issue, so I removed a DateTime and changed price to a short number, so all data is strings and numbers. Despite successfully loading the DataTable from the csv file, no values are inserted into access.
This question already has answers here:
ExecuteNonQuery: Connection property has not been initialized.
(7 answers)
Closed 7 years ago.
I tried to get my sql query read, but it does not really work. It is all working until it comes to the query part and then on the line:
rst = query.ExecuteReader();
It gets an error:
Connection property has not been initialized.
Does anyone know how to handle this?
Chart chart = new Chart();
StringBuilder xmlStr = new StringBuilder();
StringBuilder strCategories = new StringBuilder();
StringBuilder strProcesses = new StringBuilder();
StringBuilder strTasks = new StringBuilder();
xmlStr.Append("<chart logoURL='../../Images/Piktogramme/" + chart.Image + "' caption='" + chart.Caption + "' theme='flat'" + " dateformat='dd/mm/yyyy' showTaskLabels='1'>"); // attributes will go here
// Category for each month
for (int i = -12; i < 6; i++)
{
DateTime today = DateTime.Now;
today = today.AddMonths(i);
strCategories.Append("<category start='1/" + today.Month + "/" + today.Year + "' end='" + DateTime.DaysInMonth(today.Year, today.Month) + "/" + today.Month + "/" + today.Year + "' name='" + today.ToString("MMM") + "' />");
}
// Get the connection string
string connStr = ConfigurationManager.ConnectionStrings["CRM_SQL"].ConnectionString;
using (SqlConnection conn = new SqlConnection(connStr))
{
// Establish the connection with the database
conn.Open();
// Construct and execute SQL query which would return the total amount of sales for each year
SqlCommand query = new SqlCommand();
// Begin iterating through the result set
SqlDataReader rst;
query.CommandText = "SELECT * from table";
rst = query.ExecuteReader();
while (rst.Read())
{
// Construct the chart data in XML format
strProcesses.AppendFormat("<process name='{1}' id='{0}' />", rst[0], rst[1]);
strTasks.AppendFormat("<task name='{0}' processid='{1}' start='{2}' end='{3}' />", rst[4], rst[0], rst[2], rst[3]);
}
DateTime today = DateTime.Now;
xmlStr.Append("<trendlines><line start='" + DateTime.DaysInMonth(today.Year, today.Month) + "/" + today.Month + "/" + today.Year + "' displayvalue='Heute'/></trendlines>");
// End the XML string
xmlStr.Append("<categories>" + strCategories.ToString() + "</categories> <processes>" + strProcesses.ToString() + "</processes> <tasks width='10'>" + strTasks.ToString() + "</tasks> </chart>");
// Close the result set Reader object and the Connection object
rst.Close();
conn.Close();
}
return xmlStr.ToString();
}
Your SqlCommand object has no link to your SqlConnection.
Replace the line:
SqlCommand query = new SqlCommand();
By:
SqlCommand query = conn.CreateCommand();
PS: Like SqlConnection, SqlCommand and SqlDataReader are also disposable, so you can/should also use using.
And the line conn.Close(); is useless because using will take care of it.
One way to do this;
var query = new SqlCommand("SELECT * from table", conn);
another way is assigning the connection string
query.connection = conn;
Add following
query.Connection=conn;
after
SqlCommand query = new SqlCommand();
try this :
using (SqlConnection conn = new SqlConnection(connStr))
{
// Establish the connection with the database
conn.Open();
using (SqlCommand query = new SqlCommand("SELECT * from table", conn))
{
query.CommandType = CommandType.Text;
using (var rst = query.ExecuteReader())
{
while (rst.Read())
{
strProcesses.AppendFormat("<process name='{1}' id='{0}' />", rst[0], rst[1]);
strTasks.AppendFormat("<task name='{0}' processid='{1}' start='{2}' end='{3}' />", rst[4], rst[0], rst[2], rst[3]);
}
}
}
DateTime today = DateTime.Now;
xmlStr.Append("<trendlines><line start='" + DateTime.DaysInMonth(today.Year, today.Month) + "/" + today.Month + "/" + today.Year + "' displayvalue='Heute'/></trendlines>");
// End the XML string
xmlStr.Append("<categories>" + strCategories.ToString() + "</categories> <processes>" + strProcesses.ToString() + "</processes> <tasks width='10'>" + strTasks.ToString() + "</tasks> </chart>");
conn.Close();
}
I am very new to sqlite and c# and trying exporting a csv file to sqlite database using dataset.
but I get this error.
SQL logic error or missing database
no such column: P17JAW
code:
string strFileName = "I:/exploretest.csv";
OleDbConnection conn = new OleDbConnection("Provider=Microsoft.Jet.OleDb.4.0; Data Source = " + System.IO.Path.GetDirectoryName(strFileName) + "; Extended Properties = \"Text;HDR=YES;FMT=Delimited\"");
conn.Open();
OleDbDataAdapter adapter = new OleDbDataAdapter("SELECT * FROM " + System.IO.Path.GetFileName(strFileName), conn);
DataSet ds = new DataSet("Temp");
adapter.Fill(ds);
DataTable tb = ds.Tables[0];
SQLiteConnection m_dbConnection;
m_dbConnection = new SQLiteConnection("Data Source= C:/Users/WebMobility.db; Version=3;");
m_dbConnection.Open();
var dt = ds.Tables[0];
foreach (DataRow dr in dt.Rows)
{
var Id = dr["Id"].ToString();
var VRM = dr["VehicleRegistration"].ToString();
var Points = Convert.ToInt32(dr["TicketScore"].ToString());
string sql = "insert into NaughtyList (Id,VRM,Points) values ( '" + Id + "'," + VRM + "," + Points + ")";
SQLiteCommand command = new SQLiteCommand(sql, m_dbConnection);
command.ExecuteNonQuery();
}
m_dbConnection.Close();
}
CSV FILE CONTAINS
Id,VehicleRegistration,TicketScore
21,P17JAW,1
22,K1WOM,1
23,m4npr,4
25,G7EPS,4
Your problem is with the single quotes missing for VRM your query should be like:
string sql = #"insert into NaughtyList (Id,VRM,Points) values
( '" + Id + "','" + VRM + "'," + Points + ")";
//^^ ^^
From the values it appears that ID is of integer type, you can remove single quotes around ID.
You should parameterized your query that will save your from these errors. I am not sure if parameters are supported by SQLiteCommand if they are you can do something like:
string sql = #"insert into NaughtyList (Id,VRM,Points) values
(#Id,#VRM,#Points)";
and then
command.Parameters.AddWithValue("#id", Id);
command.Parameters.AddWithValue("#VRM", VRM);
command.Parameters.AddWithValue("#Points", Points);
So I have a table with the following columns:
ID, name, adress, etc..
I have been doing some research but I cannot come across the right keywords to find out to do what I want. I would like to be able to take the name value (Which would be say... "John Doe" which is in the database already for sure..) and retrieve the ID of it (from the int MySQL value ID).
I have come across the following code but I cannot seem to figure out how to extend its limits to match my needs.
connection2.Open();
cmd.ExecuteNonQuery();
try
{
MySqlDataReader myReader = cmd.ExecuteReader();
while (myReader.Read())
{
Console.WriteLine(myReader.GetString(myReader.GetOrdinal("id")));
}
myReader.Close();
}
finally
{
connection2.Close();
}
This is also what I have come up with to the best of my abilities.
MySqlConnection connection2 = new MySqlConnection("Server=" + server + ";" + "Port=" + port + ";" + "Database=" + database + ";" + "Uid=" + uid + ";" + "Password=" + password + ";");
string query = #"SELECT id FROM caregiverdatabse WHERE name Like '%" + caregiverNameDisp.Text + "%'";
MySqlCommand cmd = new MySqlCommand(query, connection2);
You should replace the hard coded parameters with sql parameters, but here is a general idea of what you'll need to do here. Using your present sql query.
MySqlConnection sqlConn = new MySqlConnection();
MySqlCommand sqlCmd = new MySqlCommand();
string sSql = "SELECT id FROM caregiverdatabse WHERE name Like '%" + caregiverNameDisp.Text + "%'";
sqlConn.ConnectionString = "Server=" + server + ";" + "Port=" + port + ";" + "Database=" + database + ";" + "Uid=" + uid + ";" + "Password=" + password + ";";
sqlCmd.CommandText = sSql;
sqlCmd.CommandType = CommandType.Text;
sqlConn.Open();
sqlCmd.Connection = sqlConn;
MySqlDataReader reader = sqlCmd.ExecuteReader();
List<string> results = new List<string>();
while (reader.Read())
{
results.Add((reader["id"].ToString());
}
reader.Close();
sqlConn.Close();
Keep in mind you can add the reader results to a string, to a list like above, whatever you want to do with it.
this how id en name pawe
clsMySQL.sql_con.Open();
string id = ID;
sql = "SELECT *FROM test";
cmd = new MySqlCommand(sql, clsMySQL.sql_con);
sql_cmd = new MySqlCommand(sql, clsMySQL.sql_con);
MySqlDataReader dr = cmd.ExecuteReader();
if (dr.Read())
{
id = dr["id"].ToString();
user = dr["user_name"].ToString();
pass = dr["password"].ToString();
if (name.Text == user && passw.Text == pass)
{
string depart = id;
Hide();
MessageBox.Show("it works");
// Then show the main form
cracker form = new cracker(name.Text);
form.sid = depart;
form.Show();
MessageBox.Show(ID);
}
}
else
{
MessageBox.Show("Invalid Login please check username and password");
}
clsMySQL.sql_con.Close();
}