I could use some suggestions / ideas. I wrote a console application that queries all data from a table in MS Access (I know, but I inherited it) to a SQL table. It runs every morning as a scheduled task. The fields between the two tables are not identical. Currently I select all data from the MS Access table, loop through the dataset and insert each row into the SQL table. I also write a quick log file in the process. It works, but it's not fast. I would appreciate any ideas that you may have to improve the process. Thanks!
+4
A:
It's way faster than individual insert
statements.
You have to increment your own identity field value for the primary key. To do that, first grab the last identity field value where you left off:
select top 1 id_customer
from customers
order by id_customer desc
Then increment an int
variable as you loop through your DataSet
.
Or you can use GUID for primary key column instead.
Example code for using SqlBulkCopy:
public static void BulkLoadDataTable(DataTable table, string destinationTable)
{
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(_connectionString))
{
bulkCopy.BulkCopyTimeout = 1200;
bulkCopy.DestinationTableName = destinationTable;
bulkCopy.WriteToServer(table);
}
}
Strongly Typed DataTable:
using System;
using System.Data;
public class CustomersDataTable : DataTable
{
public CustomersDataTable() : base()
{
base.TableName = "Customers";
Columns.Add(new DataColumn("id_customer", typeof(int)));
Columns.Add(new DataColumn("first_name", typeof(string)));
Columns.Add(new DataColumn("last_name", typeof(string)));
Columns.Add(new DataColumn("active", typeof(bool)));
}
}
JohnB
2010-07-01 16:28:42
Creating your own primary key is only necessary in extreme cases when your inserts are in the millions of records. But I agree with John that SqlBulkCopy is the way to go.
Doug
2010-07-01 16:39:29
Looks like the BulkCopyClass is the way to go. But, what happens when the field attributes do not match? For example, a string field in access and a Boolean field in SQL.
gnome
2010-07-01 16:54:04
Well you can loop through your data and build a `DataTable` exactly the way you want it in SQL Server, i.e. 'bit' column for a 'bool'. SQL Server should be able to convert data points in an untyped `DataTable` to the proper type in your schema, but personally, I would create a **strongly typed DataTable** (see above). You could also write out a .CSV and bulk copy that. Doing all this work in a loop in your code will take relatively little time. The main point is 1000's of individual `insert` statements will waste **TONS** of time!
JohnB
2010-07-01 17:13:23
Thanks JohnB - your suggestion worked like a charm. After creating the strongly typed DataTable it took less than a second to perform the work (before it was like 30 seconds).
gnome
2010-07-01 20:45:27
+1
A:
Have you looked at SSIS packages? I would look into that first. If you don't have access to that, then look into the SqlBulkCopy class mentioned here already.
You could also look into using SELECT statement with an INSERT.
knight0323
2010-07-01 16:31:01
Yeah but it's still faster than individual inserts. It would be my last choice but I figured I'd present the option. SSIS would be the way to go in my opinion.
knight0323
2010-07-01 20:39:27
Why would a batch insert using INSERT with a SELECT statement be slow?
David-W-Fenton
2010-07-01 23:42:05