Inserting different data simultaneously from different clients - c#

I created a windows forms application in C #, and a database MS SQL server 2008 Express, and I use LINQ-to-SQL query to insert and edit data.
The database is housed on a server with Windows Server 2008 R2 (standard edition). Right now I have the application running on five different computers, and users are authenticated through active directory.
One complaint reported to me was that sometimes when different data is entered and submitted, the same data do not appear in the listing that contains the application. I use try catch block to send the errors but errors do not appear in the application; but the data simply disappear.
The id of the table records is an integer auto-increment. As I have to tell them the registration number that was entered I use the following piece of code:
try{
ConectionDataContext db = new ConectionDataContext();
Table_Registers tr = new Table_Registers();
tr.Name=textbox1.text;
tr.sector=textbox2.text;
db.Table_Registers.InsertOnSubmit(tr);
db.SubmitChanges();
int numberRegister=tr.NumberRegister;
MessageBox.Show(tr.ToString());
}
catch{Exception e}
I wonder if I'm doing something wrong or if you know of any article on the web that speaks how to insert data from different clients in MSSQL Server databases, please let me know.
Thanks.

That's what a database server DOES: "insert data simultaneously from different clients".
One thing you can do is to consider "transactions":
http://www.sqlteam.com/article/introduction-to-transactions
Another thing you can (and should!) do is to insure as much work as possible is done on the server, by using "stored procedures":
http://www.sql-server-performance.com/2003/stored-procedures-basics/
You should also check the SQL Server error logs, especially for potential deadlocks. You can see these in your SSMS GUI, or in the "logs" directory under your SQL Server installation.
But the FIRST thing you need to do is to determine exactly what's going on. Since you've only got MSSQL Express (which is not a good choice for production use!), perhaps the easiest approach is to create a "log" table: insert an entry in your "log" every time you insert a row in the real table, and see if stuff is "missing" (i.e. you have more entires in the log table than the data table).

Related

C# / Sql Server 2008 INSERT int value grows automatically to 1000000

I had a strange problem recently that only occured one time in Sql Server 2008.
I work in a .net web application (C#) and use SqlCommand to access my Database and execute queries. My process is the following:
I have a view that get me the maximum number existing in a specific table:
SELECT MAX(number) as MaxNumber
FROM MyTable
I get this MaxNumber in a variable and, with this variable, I execute an insert in MyTable with the MaxNumber + 1. Like that, I always have the maximum number logged in MyTable
It worked well since that one time, a week ago, when, suddenly, I saw a MaxNumber that passed from 134200 to 1000000 !
I investigate my code and there is no way it could be the reason of that behavior. I also inspected the logs of the Web Server, no logs of bad Insert throwned.
I looked also into the logs of Sql Server I've found no logs of error...
What is suspicious is that the number passed from a "common" number (134200) to a "specific" number (1000000). Why 1000000 ? Why not 984216 or 1000256 ?
Is there someone that experienced the same problem ?
Thanks for your help.
EDIT - 2014-12-23:
I analyzed further the problem and it seems that it occurred when I restored a backup in my PreProd environment.
I explain: I have PreProd server where I have an Sql Server Instance (PreProd) and I have a Prod server where I also have an Sql Server Instance (Prod), which is backed up every day, on this same server.
When I want to test with effective datas, I restore the Prod backups on my PreProd databases:
RESTORE DATABASE PreProd
FROM DISK = '\\Prod\Backup\SQL\Prod.bak'
WITH MOVE 'Prod' TO 'E:\Bases\Data\PreProd.mdf',
MOVE 'Prod_log' TO 'E:\Bases\Data\PreProd.ldf',
REPLACE
The problem occurred the same day I restored my backup. The "1000000 row" appeared at the same moment of my restore, on my Prod database. Is there any possibility that it's linked ? Was the Prod server overwhelmed with the restore command executed from my PreProd server, and it, eventually, crashed an Insert request that occurred at the same moment ?
Thanks for your advices
The only thing that I can think is that maybe you are getting the maxValue with ExecuteScalar method without casting the result to a proper datatype
var max= cmd.ExecuteScalar();
and then
max= max+1;
Otherwise I saw that with your version of sqlServer you may receive incorrect values when using SCOPE_IDENTITY() and ##IDENTITY
refer here for the bug fix, you should update to SQL Server 2008 R2 Service Pack 1

C# creating a database programmatically with SMO

I am trying to create a database, but once created, I cannot connect to it.
The server is Microsoft SQL Server 2008 and using .Net 4.5. We're creating the database with SMO, but we're usually using Dapper to connect and query the database.
This is the code I have so far, which works :
System.Data.SqlClient.SqlConnection con = new System.Data.SqlClient.SqlConnection(connectionString);
Microsoft.SqlServer.Management.Smo.Server srv = new Microsoft.SqlServer.Management.Smo.Server(new Microsoft.SqlServer.Management.Common.ServerConnection(con));
var database = new Microsoft.SqlServer.Management.Smo.Database(srv, dbName);
database.Create(false);
database.Roles["db_datareader"].AddMember(???);
database.Roles["db_datawriter"].AddMember(???);
database.Roles["db_backupoperator"].AddMember(???);
srv.Refresh();
Noce the ??? ? I have tried
System.Environment.UserDomainName + "\\" + System.Environment.UserName
and
System.Environment.UserName
but it fails (update) with the error Add member failed for DatabaseRole 'db_datareader'. with both values.
The problem is that when I create the database, I cannot coonect to it for some reason (using Dapper), from the same program. (update) I get the error message : Cannot open database \"<database_name>\" requested by the login. The login failed.\r\nLogin failed for user '<domain>\\<username>' (where <database_name> is the database name, <domain> my logon domain, and <username> my Windows logon).
Am I missing something? Am I doing th right thing? I've tried searching the web, but it seems no one creates database this way. The methods are there, it should work, no?
** Update **
If I comment the database.Roles["..."].AddMember(...) lines, and I add a break point at srv.Refresh(), resuming the program from there solves everything.
Why a break point solves everything? I can't just break the program in production... nor break the program when creating the database everytime.
It sounds like the Dapper connection issue is a problem with SQL Server doing some of the SMO operations asynchronously. In all likelihood, the new Database is not ready for other users/connections immediately, but requires some small time for SQL Server to prepare it. In "human-time" (in SSMS, or a Breakpoint) this isn't noticeable, but "program-time" it too fast, so you probably need to give it a pause.
This may also be the problem with the Role's AddMember, but there a a number of things that could be wrong here, and we do not have enough information to tell. (specifically, does AddMember work later on? and are the strings being passed correct or not?)
This is happening because you've created the user, but no login for that user. Though I don't know the exact syntax, you're going to have to create a Login. You'll want to set its LoginType to LoginType.WindowsUser. Further, you'll likely need to set the WindowsLoginAccessType to WindowsLoginAccessType.Grant and you'll need to set the Credential by building one, probably a NetworkCredential with the user name you want.
To put a visual on this, the Login is under the Security node for the Server in Management Studio whereas the User is under the Security node for the Database. Both need to exist for access to the SQL Server.

Poor man's SQL pipeline service for SQL express 2008 R2

I have a basic/simple need to create a pipeline transfer process from one SQL express 2008 database to another server (equally SQL 2008 express).
Basically:
I have one table on SERVER A which has data coming in, and a default field called 'downloaded' which is again, by default set to 'N'
I have the same table schema on SERVER B
On a timed basis (say every 10 mins), I need to get all records from SERVER A where the 'downloaded' field is set to 'N', and copy that whole record to SERVER B
As each record from SERVER A is read/successfully copied to SERVER B, I set the 'downloaded' flag to 'Y' (with a timestamp field too).
From old memories, I used DTS (now SSIS I guess) to do something similar.. but of course SQL express doesn't have the loveliness!!
Question:
Is it just a case of a SQL datareader to get data from SERVER A and manually either INSERT a SQL statement to SERVER B (or a proc of course)?? any other slick ways?
Thanks for all comments...
oh don't use flags! They are not good for indexing.
Add two columns to both source and target tables:
dt_created
dt_modified.
Add an index on each one.
From your target database, select the source database/table for dt_created > max(target table.dt_created). Those are your new records.
Do the same for dt_modified, and those will be your modified records. See! Poor man's replication.
Well, how about MySQL with replication? Cheap and slick :-)
But I afrait it's too late to change DB...

updating changes from one database to another database in the same server

I have a copy of client database say 'DBCopy' which already contains modified data. The copy of the client database (DBCopy) is attached to the SQL Server where the Central Database (DBCentral) exists. Then I want to update whatever
changes already present in DBCopy to DBCentral. Both DBCopy and DBCentral have same schema. How can i do it programatically using C#.NET maybe with a button click. Can you give me an example code as how to do it?. I am using SQL Server 2005 Standard Edition and VS 2008 SP1.
In the actual scenario there are about 7 client database all with same schema as the central database. I am bringing copy of each client database and attach it to Central Server where the central database resides and try to update changes present in each copy of the client database to central database one by one programatically using C# .NET . The clients and the central server are physically seperate machines present in different places. They are not interconnected.
I need to only update and insert new data. I am not bothered about deletion of data.
Thanks and regards
Pavan
Go check out Sync Framework. Otherwise, go create some SSIS packages and run them.
What you are describing sounds an awful lot like Database Mirroring.
If this is a one-time or infrequent sync, then I'd use a third-party tool such as Red-Gate's SQL Data Compare. If this is meant as an ongoing sync, then I'd recommend replication or the Synchronization Framework.
i think this is wht u want:-----
USE DB1
UPDATE DB1.dbo.MyTable
SET
Field1 = d2.Field1,
Field2 = d2.Field2,
Field3 = d2.Field3
FROM DB2.dbo.MyTable d2
WHERE d2.MyKey = MyTable.MyKey

Local database, I need some examples

I'm making an app that will be installed and run on multiple computers, my target is to make an empty local database file that is installed with the app and when user uses the app his database to be filled with the data from the app .
can you provide me with the following examples :
what do I need to do so my app can connect to its local database
how to execute a query with variables from the app for example how would you add to the database the following thing
String abc = "ABC";
String BBB = "Something longer than abc";
and etc
Edit ::
I am using a "local database" created from " add > new item > Local database" so how would i connect to that ? Sorry for the dumb question .. i have never used databases in .net
Depending on the needs you could also consider Sql CE. I'm sure that if you specified the database you're thinking of using, or your requirements if you're usure you would get proper and real examples of connection strings etc.
Edit: Here's code for SqlCe / Sql Compact
public void ConnectListAndSaveSQLCompactExample()
{
// Create a connection to the file datafile.sdf in the program folder
string dbfile = new System.IO.FileInfo(System.Reflection.Assembly.GetExecutingAssembly().Location).DirectoryName + "\\datafile.sdf";
SqlCeConnection connection = new SqlCeConnection("datasource=" + dbfile);
// Read all rows from the table test_table into a dataset (note, the adapter automatically opens the connection)
SqlCeDataAdapter adapter = new SqlCeDataAdapter("select * from test_table", connection);
DataSet data = new DataSet();
adapter.Fill(data);
// Add a row to the test_table (assume that table consists of a text column)
data.Tables[0].Rows.Add(new object[] { "New row added by code" });
// Save data back to the databasefile
adapter.Update(data);
// Close
connection.Close();
}
Remember to add a reference to System.Data.SqlServerCe
I'm not seeing anybody suggesting SQL Compact; it's similar to SQLite in that it doesn't require installation and tailors to the low-end database. It grew out of SQL Mobile and as such has a small footprint and limited feature-set, but if you're familiar with Microsoft's SQL offerings it should have some familiarity.
SQL Express is another option, but be aware that it requires a standalone installation and is a bit beefier than you might need for an applciation's local cache. That said it's also quite a bit more powerful than SQL Compact or SQLite.
Seems like you're:
-Making a C# app that will be installed and run on multiple
computers
-That needs a local database (I'm assuming an RDBMS)
-You need to generate a blank database at installation
-You then need to be able to connect to the database and populate it when
the app runs.
In general, it seems that you need to read up on using a small database engine for applications. I'd start by checking out SQLite, especially if you need multi-OS capability (eg., your C# program will run on Microsoft's .NET Framework and Novell's Mono). There are C# wrappers for accessing the SQLite database.
I believe this question is about the "Local Database" item template in Visual Studio:
What are you considering as a database? From what little you've provided in your question, I'd suggest SQLite.
You can get sample code from their site Sqlite.NET
Not sure I fully understand what you're asking but Sqlite is a good option for lightweight, locally deployed database persistence. Have a look here:
http://www.sqlite.org/
and here for an ADO.NET provider..
http://sqlite.phxsoftware.com/
For 1)
The easiest way to provide this functionality is through SQL Server Express User Instances. SQL Server Express is free, so your user does not have to pay additional license for SQL Server, and the User Instance is file-based, which suits your requirement.
For 2)
This is a big topic. You may want to go through some of the tutorials from Microsoft to get the feeling of how to connect to DB, etc.

Categories

Resources