Synchronize Data from serverDB to Local DB - c#

I would like to get all the details of a single table from Remote server DB to my local DB, during page load event which should happen as a back end process can any one help me over this issue.
NOTE:
Server DB table Columns may slightly differ from local DB.
Each time when a new user is added in the server, it should update the local DB when the UserPage.aspx page is loaded.
Tools using: ASP.NET,SQL SERVER 2008.
Eg: Let the DB name be sample and the table name is customer
**Table Header in Server DB:** Cus_id,Cus_name,Cus_address,Cus_email,Cus_mob
**Table Headers in Local DB:** Cus_id,Cus_name,Cus_address,Cus_email,Cus_mob,Cus_password
Once the page gets loaded all the data in Customer table from serve DB should be synchronized to localDB

Asuming that the database login has access to both db's you can execute the following string as one command through your database connections.
--empty local table
truncate table [sample]..customer;
--fill local table
insert into [sample]..customer
(Cus_id,Cus_name,Cus_address,Cus_email,Cus_mob)
select Cus_id,Cus_name,Cus_address,Cus_email,Cus_mob from serverDb..Customer;
This will get you startet, but this is not good architecture. You might want to put a trigger on the table in the server database that will insert the new row in your local database everytime there is a new row in the serverDb.
edit
showing the whole process
protected void Page_Load(object sender, EventArgs e){
string sql = #"--empty local table
truncate table [sample]..customer;
--fill local table
insert into [sample]..customer
(Cus_id,Cus_name,Cus_address,Cus_email,Cus_mob)
select Cus_id,Cus_name,Cus_address,Cus_email,Cus_mob from serverDb..Customer;";
var conn = new SqlConnection("Server=localhost;Database=sample;User Id=myUserName;Password = myPassword");
var cmd = conn.CreateCommand();
cmd.CommandText = sql;
conn.Open();
cmd.ExecuteNonQuery();
}

I will advice you SCHEDULE a job to load record to localdb from the backend every 15mins interval. You can use management studios to achieve that.

Related

SQL Server CE two way sync with remote Access database

I'm working on a pretty special, legacy project where I need to build an app for PDA devices under Windows Mobile 6.5. The devices have a local database (SQL Server CE) which we are supposed to sync with a remote database (Microsoft Access) whenever they are docked and have network access.
So the local database using SQL Server CE works fine, but I can’t figure out a way to sync it to the Access database properly.
I read that ODBC and OLEDB are unsupported under Windows Mobile 6.5, most ressources I find are obsolete or have empty links, and the only way I found was to export the local database relevant tables in XML in the hope to build a VBA component for Access to import them properly. (and figure out backwards sync).
Update on the project and new questions
First of all, thanks to everyone who provided an useful answer, and to #josef who saved me a lot of time with the auto path on this thread.
So a remote SQL Server is a no go for security reasons (client is paranoid about security and won't provide me a server). So I'm tied to SQL Server CE on the PDA and Access on the computer.
As for the sync:
The exportation is fine: I'm using multiple dataAdapters and a WriteXML method to generate XML files transmitted by FTP when the device is plugged back in. Those files are then automatically imported into the Access database. (see code at the end).
My problem is on the importation: I can acquire data through XML readers from an Access-generated file. This data is then inserted in a dataset (In fact, I can even print the data on the PDA screen) but I can't figure out a way to do an "UPSERT" on the PDA's database. So I need a creative way to update/insert the data to the tables if they already contains data with the same id.
I tried two methods, with SQL errors (from what I understood it's SQL Server CE doesn't handle stored procedures or T-SQL). Example with a simple query that is supposed to update the "available" flag of some storage spots:
try
{
SqlCeDataAdapter dataAdapter = new SqlCeDataAdapter();
DataSet xmlDataSet = new DataSet();
xmlDataSet.ReadXml(localPath +#"\import.xml");
dataGrid1.DataSource = xmlDataSet.Tables[1];
_conn.Open();
int i = 0;
for (i = 0; i <= xmlDataSet.Tables[1].Rows.Count - 1; i++)
{
spot = xmlDataSet.Tables[1].Rows[i].ItemArray[0].ToString();
is_available = Convert.ToBoolean(xmlDataSet.Tables[1].Rows[i].ItemArray[1]);
SqlCeCommand importSpotCmd = new SqlCeCommand(#"
IF EXISTS (SELECT spot FROM spots WHERE spot=#spot)
BEGIN
UPDATE spots SET available=#available
END
ELSE
BEGIN
INSERT INTO spots(spot, available)
VALUES(#spot, #available)
END", _conn);
importSpotCmd.Parameters.Add("#spot", spot);
importSpotCmd.Parameters.Add("#available", is_available);
dataAdapter.InsertCommand = importSpotCmd;
dataAdapter.InsertCommand.ExecuteNonQuery();
}
_conn.Close();
}
catch (SqlCeException sql_ex)
{
MessageBox.Show("SQL database error: " + sql_ex.Message);
}
I also tried this query, same problem SQL server ce apparently don't handle ON DUPLICATE KEY (I think it's MySQL specific).
INSERT INTO spots (spot, available)
VALUES(#spot, #available)
ON DUPLICATE KEY UPDATE spots SET available=#available
The code of the export method, fixed so it works fine but still relevant for anybody who wants to know:
private void exportBtn_Click(object sender, EventArgs e)
{
const string sqlQuery = "SELECT * FROM storage";
const string sqlQuery2 = "SELECT * FROM spots";
string autoPath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase); //get the current execution directory
using (SqlCeConnection _conn = new SqlCeConnection(_connString))
{
try
{
SqlCeDataAdapter dataAdapter1 = new SqlCeDataAdapter(sqlQuery, _conn);
SqlCeDataAdapter dataAdapter2 = new SqlCeDataAdapter(sqlQuery2, _conn);
_conn.Open();
DataSet ds = new DataSet("SQLExport");
dataAdapter1.Fill(ds, "stock");
dataAdapter2.Fill(ds, "spots");
ds.WriteXml(autoPath + #"\export.xml");
}
catch (SqlCeException sql_ex)
{
MessageBox.Show("SQL database error: " + sql_ex.Message);
}
}
}
As Access is more or less a stand-alone DB solution I strongly recommend to go with a full flavored SQL Server plus IIS to setup a Merge Replication synchronisation between the SQL CE data and the SQL Server data.
This is described with full sample code and setup in the book "Programming the .Net Compact Framework" by Paul Yao and David Durant (chapter 8, Synchronizing Mobile Data).
For a working sync, all changes to defined tables and data on the server and the CE device must be tracked (done via GUIDs, unique numbers) with there timestamps and a conflict handling has to be defined.
If the data is never changed by other means on the server, you may simply track Device side changes only and then push them to the Access database. This could be done by another app that does Buld Updates like described here.
If you do not want to go the expensive way to SQL Server, there are cheaper solutions with free SQLite (available for CE and Compact Framework too) and a commercial Sync tool for SQLite to MSAccess like DBSync.
If you are experienced, you may create your own SQLite to MS ACCESS sync tool.

DROP command denied to user X for table 'Y'

We are getting ready for a big SQL migration.
Currently, I have the code written, and I am testing it out with data on my local machine.
Step 1 is to throw out the existing data in the table before I import the new stuff:
using (var txn = m_mySqlConnection.BeginTransaction()) {
using (var cmd = new MySqlCommand("TRUNCATE TABLE `blah_blah`;", m_mySqlConnection, txn)) {
cmd.ExecuteNonQuery();
}
// other code
}
But, the TRUNCATE command is throwing an exception whenever I try to execute it with the MySQL user account I am running the code with:
I tried going into MySQL Workbench to give this userid DROP permission, but all I could find was a way to add DROP under the View section.
I tried that, but it did not work.
How do I go about giving this user the ability to remove the data in these tables so that I can test my populate script?
TRUNCATE deletes the table. Try using DELETE FROM Table.

Copy a whole table from a SQL Server CE database to another

I'm developing a C# application and I want to copy a whole table from a SQL Server CE database to another programmatically. I know I can use this command in SQL Server, but I'm not sure how to use two database connections in one query in C#.
Select * into DestinationDB.dbo.tableName from SourceDB.dbo.SourceTable
Thanks in advance.
You wouldn't do it the same way as in SQL Server because there's no single server that manages both databases. Your app is the only thing that links the two databases so the the data has to go through your app. You're trying to do it the wrong way and that's why you can't find a solution: you're looking for the wrong thing.
There are examples of this out there. I know, because I've written more than one myself. You simply need to use a data adapter to populate a DataTable from the first database and then a data adapter to save the contents of that DataTable to the second database. If the data sources are the same type then you can even use just one data adapter because the SelectCommand and InsertCommand can have different connections.
using (var adapter = new SqlDataAdapter("SELECT statement here", "source connection string here"))
using (var destinationConnection = new SqlConnection("destination connection string here"))
using (var insertCommand = new SqlCommand("INSERT statement here", destinationConnection))
{
// Add parameters to insertCommand here.
adapter.InsertCommand = insertCommand;
// Leave the RowState of all DataRows as Added so they are ready to be inserted.
adapter.AcceptChangesDuringFill = false;
var table = new DataTable();
// Retrieve data from source and save to destination.
adapter.Fill(table);
adapter.Update(table);
}
That example uses SqlClient but it works the same for any provider, including SqlServerCe.

MS Access database not up to date? (VS Web Developer Studio)

I'm taking a class in C# web dev and I'm currently trying to display data from a .mdb (Microsoft Access) database. I have two pages that both want to show a table stored in the database in a grid view. One page's form uses function that connects the the db and then writes to the table to the grid. it connects with this call:
sqlConn = new OleDbConnection("PROVIDER=Microsoft.Jet.OLEDB.4.0;" +
"Data Source=" + Database);
sqlDA = new OleDbDataAdapter("select * from tblPersonnel where LastName = '"+strSearch+"'", sqlConn);
//Initialize a new activity
DS = new dsPersonnel();
//Add rows to the dataset from the data source
sqlDA.Fill(DS.tblPersonnel);
The database is called PayrollSystem_DB.mdb. In the other page I placed a SqlDataSource control on the page and connected it to PayrollSystem_DB.mdb. Then set this to the gridView. However when running, the the first page shows a long table with data I've entered since last week. and the 2nd page shows only data from the first day I tested it. Looking at the db in the vs explorer the tables are identical to teh second page.
So I'm wondering were all the other data is being stored that the first page is showing? Am I unknowingly using a database I can't see in the solution?
Just a guess, but have you tried clearing your browsers cache and then looking at the first page again? Try that. If the data is still showing I would compare the size of the MDB before and after an insert to see if the MDB grows. If not, try a search of all the files on your PC limiting it to only files modified recently, I think that will at least help you find where the data is being stored.

Connect web form to external Access database

I'm trying to figure out how to connect a website form to an external Microsoft Access database. The website and database are on different servers. The website is going through a hosting company and the database is located inside a company office network.
My goal is to have users fill out an online form and then that information will be sent and saved to the Access database.
Is there a tutorial on this or does anyone have any suggestions?
TODO: You'll need to change the path to the mdb (in the connection string), probably hook up to some button click event instead of form load, change the table name (tblYourData) and the field names (field1, field2, etc) in the sql string, and instead of using 'some text', use the .Text property of the textbox on the page.
protected void Form_Load()
{
string connstring = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\mydatabase.mdb;User Id=admin;Password=;";
string sql = "insert into tblYourData (field1, field2) values ('some text', 'some more text')";
CreateCommand(sql, connstring);
}
private static void CreateCommand(string queryString, string connectionString)
{
using (OleDbConnection connection = new OleDbConnection(
connectionString))
{
OleDbCommand command = new OleDbCommand(queryString, connection);
command.Connection.Open();
command.ExecuteNonQuery();
}
}
--Edit #1 --
This can only be done with the MDB is located on the same network (local hard drive, or network file share) as the IIS server.
Considering this isn't possible, you have a couple of options.
Option 1:
Save it to a local database (sql express, sql server, etc...)
Allow them to set up a linked server between the access database and your database.
Option 2:
Save it to a local database (sql express, sql server, etc...)
Allow them to export the data to a CSV or similar format.
Then they can import that data into their Access database.

Categories