Shamil Salakhetdinov
shamil at smsconsulting.spb.ru
Sat Apr 26 17:12:40 CDT 2008
Hi John, Try to use SqlDataReader and custom classes as in the sample code below (sorry C# is used - real pleasure to use C# is also coming from the fact that you can copy and paste code and do not care about line warps because even "screwed by e-mail" code should be compiled well).... ...using ADO.NET datasets and bulk update will anyway result in a series of updates on SQL server side therefore custom on-the-fly built sql updates or calls to update SPs should work as quick as ADO.NET DataSets' batch update... ...etc... ...as you can see my sample did update 25000 records in ~10 seconds - and this only for starters - if that approach will work reasonably well for you then the next step could be to introduce multi-threading etc... ...note also how MS SQL 2005's paging feature is used to get record's batches... using System; using System.Collections.Generic; using System.Data.SqlClient; namespace ORS_TDD_Console { public class DataItem { public int ID; public string Name; public DataItem(int id, string name) { ID = id; Name = name; } public string ParsedName { get { return Name; // just for testing purposes // return real parsed name here } } } public class DataProcessor { private const string COUNT_SQL = "select count(*) from zsysUserSessionTrace"; private const string PAGED_SELECT_SQL = "SELECT * from " + "(" + " select " + " Cast(ROW_NUMBER() over (ORDER BY [UserSessionTraceId]) as int) as RowNum, " + " UserSessionTraceId, " + " HostAddress, " + " UserBrowser " + " from zsysUserSessionTrace " + ") s " + "where s.RowNum between {0} and {1}"; private const string UPDATE_SQL = "update zsysUserSessionTrace set UserBrowser = '{0}' where UserSessionTraceId = {1}"; private const int DEFAULT_BATCH_SIZE = 1000; private int _totalCount = -1; public int TotalCount { get { return _totalCount; } } private int _currentBatchStartRowNum = 0; private int _batchSize = 0; private string _connectionString; public DataProcessor(string connectionString) { initialize(connectionString, DEFAULT_BATCH_SIZE); } public DataProcessor(string connectionString, int batchSize) { initialize(connectionString, batchSize); } private void initialize(string connectionString, int batchSize) { _batchSize = batchSize; _currentBatchStartRowNum = 1; _connectionString = connectionString; using (System.Data.SqlClient.SqlConnection cnn = new System.Data.SqlClient.SqlConnection(connectionString)) { cnn.Open(); System.Data.SqlClient.SqlCommand cmd = cnn.CreateCommand(); cmd.CommandText = COUNT_SQL; cmd.CommandType = System.Data.CommandType.Text; _totalCount = (int)cmd.ExecuteScalar(); } } public bool HasData { get { return (TotalCount > 0 && _currentBatchStartRowNum < TotalCount); } } public List<DataItem> GetData() { using (System.Data.SqlClient.SqlConnection cnn = new System.Data.SqlClient.SqlConnection(_connectionString)) { cnn.Open(); System.Data.SqlClient.SqlCommand cmd = cnn.CreateCommand(); string sql = string.Format(PAGED_SELECT_SQL, _currentBatchStartRowNum, _currentBatchStartRowNum + _batchSize); cmd.CommandText = sql; cmd.CommandType = System.Data.CommandType.Text; _currentBatchStartRowNum += _batchSize + 1; System.Data.SqlClient.SqlDataReader rdr = cmd.ExecuteReader( System.Data.CommandBehavior.SequentialAccess); List<DataItem> list = new List<DataItem>(); while (rdr.Read()) { list.Add (new DataItem((int)rdr[1], (string)rdr[3])); } return list; } } public int Update(DataItem item) { using (System.Data.SqlClient.SqlConnection cnn = new System.Data.SqlClient.SqlConnection(_connectionString)) { cnn.Open(); System.Data.SqlClient.SqlCommand cmd = cnn.CreateCommand(); string sql = string.Format(UPDATE_SQL, item.ParsedName, item.ID ); cmd.CommandText = sql; cmd.CommandType = System.Data.CommandType.Text; return cmd.ExecuteNonQuery(); } } } public class A_MainEntry { //27.04.2008 1:53:30 //Count(*) = 25045 //Counter = 25045 //27.04.2008 1:53:40 public static void Main() { int count = 0; try { //+ customize - set your connection string here string connectionString = AppConfigManager.DefaultConnectionString; //- Console.WriteLine(DateTime.Now); DataProcessor p = new DataProcessor(connectionString); while (p.HasData) { List <DataItem> list = p.GetData(); foreach (DataItem item in list) { p.Update(item); count++; } } Console.WriteLine("Count(*) = {0}", p.TotalCount); Console.WriteLine("Counter = {0}", count); Console.WriteLine(DateTime.Now); } catch (Exception ex) { Console.WriteLine(ex.Message); } } } } -----Original Message----- From: dba-vb-bounces at databaseadvisors.com [mailto:dba-vb-bounces at databaseadvisors.com] On Behalf Of jwcolby Sent: Saturday, April 26, 2008 11:26 PM To: VBA Subject: [dba-VB] ADO.Net I have been setting up an application to read a block of records, perhaps 10K or something. <<< the rest trimmed to get message through accessd >>>