I have a project (with c# and SQLServer), that it should run on multiple clients and each client should communicate with a central SQL Server. All of the clients and the server are on the same local network.
Everything is ok, but... in some cases, when a insert query runs on a client, multiple duplicate records insert into sql server. This problem occurs rarely.
Below is the query. The query runs when a form is filled and a button click event trigers.
public static int insertSick(string firstname,string lastname,string mobile,string address)
{
using (SqlConnection connection = new SqlConnection(getConnectionString()))
{
string sql = "insert into TSick (Firstname,Lastname,MobileNumber,Address) values
(#fname,#lname,#mobile,#address)";
connection.Open();
SqlTransaction tran = connection.BeginTransaction();
SqlCommand command = new SqlCommand(sql, connection, tran);
command.Parameters.AddWithValue("fname", firstname);
command.Parameters.AddWithValue("lname", lastname);
command.Parameters.AddWithValue("mobile", mobile);
command.Parameters.AddWithValue("address", address);
int nRecord = command.ExecuteNonQuery();
tran.Commit();
return nRecord;
}
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
// check the text fields and validate them
insertSick(firstname,lastname,mobile,address);
}
The table is as below:
TSick :
- ID --> this column is an incremental identity
- Firstname
- Lastname
- Mobilenumber
- Address
Can someone tell me why in some cases instead of a single record multiple records inserted? How to solve? Do you think that it is a network related problem?
Thanks
It's almost certainly that the user clicks the button twice. You should disable the button as the first thing in your click event handler, and then enable it again at the appropriate time; what constitutes the "appropriate time" is up to you to decide.
Before from the insertion of data in table you can do validation of data whether data is duplicate or not.
First check which column is unique in your table, on the basis of unique column you can check the data otherwise make a composite key(if there is no unique column) in the table and verify the data before from insertion. If a data is duplicate through a message to user.
Related
I am trying to create a MyAccount page for a website I am making using ASP.NET and Bootstrap with html and C# running in the background for our objects. We are using SQL Server to run our databases and I am having a LOT of troubles getting my updates to go through. I am using a test user profile I had my partner hard insert into the system as I have not programmed the account creation system yet, only the login.
The issue is that when I run my update code the SQL Server database does not update with the passed information. I receive no exceptions and I know my connection string works as I use it to log in and drag contents of my database into text boxes on the main screen. Because of this I have no idea why it is not updating and I feel very lost.
I have removed bits of the connection string itself as this server is not my own and I don't want my professor's personal connection and login credentials being on the internet.
My debug label running a query tells me each time I attempt to change the state variable on the item that 1 row was effected.
The user profile I am trying to update has the following information stored in it.
Username: MarshallE
Email: Test1234
Password: Test1234!
First Name: Marshall
Last Name: Emmer
Properties Rented: Prime Place
Universities Attended Oklahoma State University
State: N/A (My partner just added this and didn't update the profile)
Here is my code I used to try and update the thing:
protected void btnRegAcctUpdate_Click(object sender, EventArgs e)
{
// This unit's job is to update the database of the specified user with the info in the text boxes
// Make sure the password fields are the same
if (txtAcctPass1.Text == txtAcctPass2.Text)
{
lblAcctDebug.Text = "";
SqlConnection MyConnection = new SqlConnection();
MyConnection.ConnectionString = "Server= (N/A ;Database=F19_groupRoss;User Id=groupRoss;Password = (N/A);";
string MyUpdateStatement;
MyUpdateStatement = "UPDATE dbo.UserID SET Email = #Email, Password = #Password, FirstName = #FirstName, LastName = #LastName, Universities = #University, Town = #Town, State = #State" + " WHERE UserID = #UserID";
SqlCommand MySqlCmd = new SqlCommand(MyUpdateStatement, MyConnection);
// These are the values we will be overriding the database with
MySqlCmd.Parameters.AddWithValue("#UserID", (string)Session["UserID"]);
MySqlCmd.Parameters.AddWithValue("#FirstName", txtAcctFirstName.Text);
MySqlCmd.Parameters.AddWithValue("#LastName", txtAcctLastName.Text);
MySqlCmd.Parameters.AddWithValue("#Email", txtAcctEmail.Text);
MySqlCmd.Parameters.AddWithValue("#Password", txtAcctPass1.Text);
MySqlCmd.Parameters.AddWithValue("#State", txtAcctState.Text);
MySqlCmd.Parameters.AddWithValue("#Town", txtAcctTown.Text);
MySqlCmd.Parameters.AddWithValue("#University", txtAcctUniversity.Text);
// Open the connection
MyConnection.Open();
int rows = MySqlCmd.ExecuteNonQuery();
lblDebug2.Text = "Rows affected: " + rows;
MyConnection.Close();
}
else
{
lblAcctDebug.Text = "Error: Please ensure the text in the new password and password confirmation boxes are identical";
}
}
If anyone can tell me what I am doing wrong I would REALLY appreciate it!
Try adding your parameters like this:
MysqlCmd.Parameters.Add(New Parameter(#FirstName, txtAcctFirstName.text));
Here is my code, it works when the database has the table "UserInformation"
public bool Save()
{
using (SqlConnection connection = new SqlConnection(ConnectionString)
{
connection.Open();
using (SqlTransaction transaction = connection.BeginTransaction())
{
try
{
using (var adapter = new UserInformationTableAdapter())
{
adapter.Connection = connection;
adapter.Transaction = transaction;
var table = new HelloDataSet.UserInformationDataTable();
HelloDataSet.UserInformationRow row = table.NewUserInformationRow();
row.UserName = userName;
row.Password = password;
row.Brithday = brithday;
table.Rows.Add(row);
adapter.Update(table);
transaction.Commit();
return true;
}
}
catch (Exception e)
{
transaction.Rollback();
return false;
}
finally
{
connection.Close();
}
}
}
However, when there is no table in the database, it will not create the "UserInformation" table in the database, it will jump to "catch" exception in line "adapter.Update(table);"
So my question is how can I create a new table in database if there is no "UserInformation" table in it. In addition, if the database already has the table "UserInformation" can I add a new column "Position" in that table?
Finally, I got the answer and want to share it out. First, I have to say that I put my question in a wrong way. What I really want is I have an application, and this application is connected with a database. However, I am allowed user to switch database. So, when the user switch to a new database I would like the application copy the entire database structure (not including the data) from the old one to the new one. Also, if I make some change (could be add a new column for one or more table, or add another new table) for the database in my application code, I would like every other database know the updates and make the same change by running my new application code.
So, here is my solution. I write a framework called "SchemaManager." It will create an additional table in each database, this table contains the version of the database. So, every time when I run my application the "SchemaManager" will check my hard code database version number with the database version number, if my hard code database version number is greater than the database version number, the "SchemaManager" will check the change and do the update for me.
I know my solution is not the best, but this is what I did. If anyone have anyother solution, please share with me and other people.
I want to insert values in "Navn" row and "Varenr" row in the DB table, when I'm clicking on a button. I have following code:
private void button2_Click(object sender, EventArgs e)
{
using (SqlConnection cn = new SqlConnection(#"Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\Produkt.mdf;Integrated Security=True"))
{
try
{
SqlCommand cm = new SqlCommand();
cm.Connection = cn;
string col1 = textBox2.Text;
string col2 = textBox3.Text;
//generate sql statement
cm.CommandText = "INSERT INTO ProduktTable (Navn,Varenr) VALUES (#col1,#col2)";
//add some SqlParameters
SqlParameter sp_add_col1 = new SqlParameter();
sp_add_col1.ParameterName = "#col1";
//data type in sqlserver
sp_add_col1.SqlDbType = SqlDbType.NVarChar;
//if your data type is not number,this property must set
//sp_add_col1.Size = 20;
sp_add_col1.Value = textBox2.Text;
//add parameter into collections
cm.Parameters.Add(sp_add_col1);
//in your insert into statement, there are how many parameter, you must write the number of parameter
SqlParameter sp_add_col2 = new SqlParameter();
sp_add_col2.ParameterName = "#col2";
//data type in sqlserver
sp_add_col2.SqlDbType = SqlDbType.NVarChar;
//if your data type is not number,this property must set
//sp_add_col2.Size = 20;
sp_add_col2.Value = textBox2.Text;
//add parameter into collections
cm.Parameters.Add(sp_add_col2);
//open the DB to execute sql
cn.Open();
cm.ExecuteNonQuery();
cn.Close();
}
catch (Exception ex)
{
MessageBox.Show("Error\n" + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
But unfortunately, my data table is still empty:
I have set a breakpoint on the ExecuteNonQuery function, and it is triggered, when pressing on the button:
My table definition:
Your connection string is causing this:
Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\Produkt.mdf;Integrated Security=True"
|DataDirectory| Your database that is being updated in this method is in your App Data Directory while the one you are trying to retrieve data from is in your project folder...
|DataDirectory| is a substitution string that indicates the path to the database. DataDirectory also makes it easy to share a project and also to deploy an application. For my PC my App Data Directory is:
C:\Users\MyUserName\AppData\...
If you browse to this location and then go to following folders
...\Local\Apps\2.0\Data
You will be able to find your particular application directory probably stored with your assembly name, or some hash when you go there you will find it the database there is being updated just fine. This connection string is best for deployment.
You can also try this:
If you notice that Server Explorer is detecting all the databases on my PC and you can notice that there are couple of MINDMUSCLE.MDF files but all are at different paths, this is because there is one file in DEBUG directory, one in my PROJECT directory, one in my APP DATA directory. The ones starting with the numbers are stored in my APP DATA directories... If you select your respective database file and then run the SELECT query against it, you will get your data.
I made a tutorial some time ago. May be it will help you:
Check the value that ExecuteNonQuery is returning. It should return an int with the number of records affected by the SQL statement.
If it comes back with a value other than 0, then you know a record is being inserted somewhere. Before you close the connection, run a SQL query against the table to select all of the records and see if they come back through the code.
SELECT * FROM ProduktTable
If you get some records, then you may want to double check the database you're looking at through the IDE and the one your inserting records into through the code. It could be possible that you've got two different databases and you're querying one while inserting into another one.
Those are the steps that I would go through to help narrow down the issue and sounds like something I've probably done before. I hope it helps!
I want to refresh the data automatically when change to the database is made.
I used this documentation:
And made the code on page load as:
protected void Page_Load(object sender, EventArgs e)
{
conString = "Data Source=MITEJ5-PC\\MITEJTECHONOLY;Initial Catalog=SSISTestDatabase;Integrated Security=SSPI;";
SqlDependency.Start(conString);
using (SqlConnection connection =
new SqlConnection(conString))
{
using (SqlCommand command =
new SqlCommand(GetSQL(), connection))
{
SqlCacheDependency dependency =
new SqlCacheDependency(command);
// Refresh the cache after the number of minutes
// listed below if a change does not occur.
// This value could be stored in a configuration file.
int numberOfMinutes = 1;
DateTime expires =
DateTime.Now.AddMinutes(numberOfMinutes);
Response.Cache.SetExpires(expires);
Response.Cache.SetCacheability(HttpCacheability.Public);
Response.Cache.SetValidUntilExpires(true);
Response.AddCacheDependency(dependency);
connection.Open();
gv.DataSource = command.ExecuteReader();
gv.DataBind();
}
}
}
private string GetSQL()
{
return "select Name,Age,Address from tlbStudent;";
}
But when I run this , and made changes in SQL table data, it is not reflecting it on grid automatically.
Where can I be wrong in above code???
Please help me.
First you need to understand how SqlDependency works. Read The Mysterious Notification for a short introduction. Once you learn that the real feature at work is Query Notifications, you can learn about the restrictions in place for queries using notifications, see Creating a Query for Notification. Once such restriction is:
The projected columns in the SELECT statement must be explicitly stated, and table names must be qualified with two-part names. Notice that this means that all tables referenced in the statement must be in the same database.
For future problems read Troubleshooting Query Notifications.
The problem in
private string GetSQL()
{
return "select Name,Age,Address from tlbStudent;";
}
the table name should be 2 parts ""
private string GetSQL()
{
return "select Name,Age,Address from dbo.tlbStudent;";
}
according to the documentation
The projected columns in the SELECT statement must be explicitly stated, and table names must be qualified with two-part names. Notice that this means that all tables referenced in the statement must be in the same database.
I'm trying to add records to a MS Access table 2007 using a C# application. My table consists of 3 fields: ID, Name and phone.
For example I tried to add a record for some one with these data: ID=1, Name=Boulis, and phone=1212422. The query didn't return any errors but I didn't find this data in my table.
But the most surprising matter is that when I tried to add the same previous data I got an error saying:
"The changes you requested to the table were not successful because they would create duplicate values in the index, primary key, or relationship. Change the data in the field or fields that contain duplicate data, remove the index, or redefine the index to permit duplicate entries and try again."
private void button1_Click(object sender, EventArgs e)
{
OleDbConnection con = new OleDbConnection();
string ConnStr = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=D:\boulis.accdb;;Persist Security Info=False ";
con.ConnectionString = ConnStr;
con .Open();
MessageBox.Show("The connection is available now");
OleDbCommand cmd = new OleDbCommand();
cmd.CommandText = "INSERT INTO info(ID, Name, phone) Values(#StudIDTxt, #StudNameTxt, #StudCNCITxt)";
cmd.Parameters.AddWithValue("#StudIDTxt",1);
cmd.Parameters.AddWithValue("#StudNameTxt", "boulis");
cmd.Parameters.AddWithValue("#StudCNCITxt", 1212422);
cmd.Connection = con;
cmd.ExecuteNonQuery();
MessageBox.Show("table is already updated");
}
The error message you receive on the second attempt clearly indicates that the first attempt was successful. If you already had the table open in Access before performing the INSERT in C# then you won't be able to see the new record until you either
close and re-open the table in Access, or
refresh the Datasheet View (or Form, or whatever). That can be accomplished by clicking the "Refresh All" button in the "Records" section of the "Home" tab (in Access 2010, anyway).