As @PeterLeow has pointed out, this would be a lot easier if you had a datetime column. As things have been described I can see no way of identifying the data that has been loaded after 10pm the previous day.
So the solution I'm offering here is focussing on the
request_number
in a similar way to the code snippet you posted.
Here is the full code
using System;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Windows.Forms;
namespace Sandbox
{
public partial class Sandbox : Form
{
readonly string connectionString = ConfigurationManager.ConnectionStrings["ConnectToDB"].ConnectionString;
private const string Qrychild = "SELECT request_number,pincode,city FROM testtable WHERE request_number > @no;";
private int rnberLast;
private const string LastNumber = "lastNumber";
private DataTable dchild;
public Sandbox()
{
InitializeComponent();
}
private void Sandbox_Load(object sender, EventArgs e)
{
rnberLast = GetDataSinceLastId(LastIdFromConfig());
WriteSetting(LastNumber, rnberLast.ToString());
timerCheckDB.Interval = (2*60*60*1000);
timerCheckDB.Enabled = true;
}
private int LastIdFromConfig()
{
try
{
var s = ReadSetting(LastNumber);
if (!int.TryParse(s, out rnberLast))
rnberLast = 0;
}
catch (Exception)
{
rnberLast = 0;
}
return rnberLast;
}
static string ReadSetting(string key)
{
var configFile = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
var settings = configFile.AppSettings.Settings;
return settings[key] != null ? settings[key].Value : "";
}
static void WriteSetting(string key, string value)
{
var configFile = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
var settings = configFile.AppSettings.Settings;
if (settings[key] == null)
settings.Add(key, value);
else
settings[key].Value = value;
configFile.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection(configFile.AppSettings.SectionInformation.Name);
}
private int GetDataSinceLastId(int lastId)
{
using (var cnn = new SqlConnection(connectionString))
{
using (var adapChild = new SqlDataAdapter(Qrychild, cnn))
{
dchild = new DataTable();
adapChild.SelectCommand.Parameters.AddWithValue("@no", lastId);
adapChild.Fill(dchild);
return dchild.Rows.Count > 0 ? int.Parse(dchild.AsEnumerable().Max(r => r["request_number"]).ToString()) : lastId;
}
}
}
private void timerCheckDB_Tick(object sender, EventArgs e)
{
rnberLast = GetDataSinceLastId(rnberLast);
WriteSetting(LastNumber, rnberLast.ToString());
}
}
}
Explanation:
The method
GetDataSinceLastId
takes the number of the
lastId
saved and retrieves all data rows where the
request_number
is greater than that number. Note the differences between your code and mine: I've used a parameterised query and I'm using
int.Parse
instead of
Convert.ToInt
The method
LastIdFromConfig
reads the application configuration file to get the last
request_number
that was read from the database on the previous run. As soon as the new data (if any) has been loaded, then the
WriteSetting
method updates the config file with the new last id (request_number)
An initial data load happens as soon as the form is loaded and the timer is initialise and enabled. The
timerCheckDB_Tick
subsequently attempts to reload the data at the given interval.
The key to getting this to work is persisting the last request_number - here is my App.Config file
<configuration>
<startup>
<supportedruntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<connectionstrings>
<add name="ConnectToDB">
connectionString="Data Source=MyDataSource;Initial Catalog=Sandbox14;Integrated Security=True"
providerName="System.Data.SqlClient" />
</add></connectionstrings>
<appsettings>
<add key="lastNumber" value="5" />
</appsettings>
</configuration>
(Note the config file is overwritten in the bin\debug folder everytime you run in debug mode. To prevent this go to the Project, Properties, Debug tab and untick the "Enable the Visual Studio hosting process" checkbox)
In this case I've used the App.config to persist the data. A better option is to have this as a User Setting
Using Application Settings and User Settings[
^]
User Settings Applied[
^]
Windows Forms User Settings in C#[
^]
This does not fit your requirement as stated
Quote:
in fact when user opens the winform app on morning at 9 Am, i fetch from table A, data between day before night(10 pm) and current day 9Am. i save the last ID
This version will always retrieve data loaded after the previous id. To be able to handle time in this way you will need a
DateTime
column on your table and you will probably want to persist the DateTimeLastRun in the settings.
[EDIT]
My apologies - I forgot to mention that you will need to change SqlConnection and SqlDataAdapter to
MySqlConnection
and
MySqlDataAdapter
in the code above