Mysql if exist update else insert - c#

I Sql server i use this command to insert value and if the id already exist update the vale
string commandLine = "IF NOT EXISTS(SELECT clientid FROM Rating WHERE clientid = " + clientId + " AND userid = " + userid + ") " +
"INSERT INTO Rating VALUES(#clientId,#userid,#rating) " +
"ELSE " +
"UPDATE Rating SET rating=#rating WHERE clientid = " + clientId + " AND userid = " + userid + ";";
And i now move to MySQL and this command won't work. there is any thing same in MySQL?

The INSERT ... ON DUPLICATE KEY UPDATE provides an easier syntax in MySQL and also gives you feedback as to what was happening via the affected-rows API call. Few people realise in my experience how handy it can come in your program logic to know that:
With ON DUPLICATE KEY UPDATE, the affected-rows value per row is 1 if
the row is inserted as a new row, 2 if an existing row is updated, and
0 if an existing row is set to its current values.

If you have unique constraint or primary key on clientid, userid you can use INSERT ... ON DUPLICATE KEY UPDATE Syntax
INSERT INTO Rating VALUES(#clientId,#userid,#rating)
ON DUPLICATE KEY
UPDATE Rating SET rating=#rating

Related

Violation of PRIMARY KEY constraint SQL Server

string query = "UPDATE Completed_orders SET service=N'" + comboBox1.SelectedValue + "',kolvo=N'" + kol.Text + "',note=N'" + not.Text + "' WHERE orders='" + form3.ordersgrid.CurrentRow.Cells[0].Value.ToString() + "' ";
SqlCommand cmd = new SqlCommand(query, dataBase.getConnection());
dataBase.openConnection();
cmd.ExecuteNonQuery();
dataBase.closeConnection();
form3.serviceklient();
MessageBox.Show("Изменена");
this.Hide();
You try to add an occurence in a table when a record with the same id (primary key) already exist.
If it's possible for your project, I suggest you tu use a numeric ID with the autoincrement option :
CREATE TABLE `table_name` ( id INT PRIMARY KEY NOT NULL AUTO_INCREMENT, [...] );
Auto-increment allows a unique number to be generated automatically when a new record is inserted into a table.
When you insert a new record in the table, you don't have to specify the id.

How can I insert data from a text field into a foreign key in the database

How can I insert data from a text field into a foreign key in the database. Basically, I have tables named Employee and Role, RoleId is a foreign key in Employee, but the role text field is a string.
I have this
String Query = "insert into EMPLOYEE (LastName,FirstName,Manager,RoleId,HireStatus) values('" + this.txtLName.Text + "','" + this.txtFName.Text + "','" + this.txtManager.Text + "','" + this.txtRoleId.Text + "','" + this.txtHireStatus.Text + "');";
Edited - I have this, but I cannot have select with the following string
string Query = "insert into EMPLOYEE(LastName,FirstName,RoleId,Manager,HireStatus) values('" + this.txtLName.Text + "','" + this.txtFName.Text + "','" + ( SELECT RoleId From Role WHERE Role.RoleId = this.txtRole.Text ) + "','" + this.txtManager.Text + "','" + this.cmbHireStatus.Text + "');";
I think you should do this:
String Query = "insert into EMPLOYEE (LastName,FirstName,Manager,RoleId,HireStatus) values('" + this.txtLName.Text + "','" + this.txtFName.Text + "','" + this.txtManager.Text + "','" + this.txtRoleId.Text + "','" + this.txtHireStatus.Text + "');";
If you are trying to add a new Employee assigned to an existing role, then a better design would be have a dropdown with all Roles populated instead of a textbox for user to enter.
The dropdown should get filled with all the Roles from Roles table. (map the SelectedValue attribute of the dropdown to - RoleId and SelectedText to RoleName).
When you submit the form, you will get the SelectedValue (RoleId) which you can directly send as part of the INSERT statement, i.e., dropDownRole.SelectedValue instead of txtRoleId.Text
Note: Your insert query seems to be a classic candidate for SQL Injection. I suggest you transform it to Parameterized query.
Update: Now that I came to know it is a Winforms application, adding more detailed snippets. Here is how you can do it in the Win Forms world (not as intuitive as web app world though :) ) and please bear with me, it has been years since I had written a winforms snippet.
Define your dropdown combo box like this -
cbxRole.DataSource = roles; // data from back end
cbxRole.Name = "Role";
cbxRole.DropDownStyle = ComboBoxStyle.DropDownList;
cbxRole.DisplayMember = "RoleName"; // should match the property name in your roles data table
cbxRole.ValueMember = "RoleId"; // should match the property name in your roles data table
cbxRole.SelectedItem = null;
cbxRole.SelectedText = "Select Role";
Observe the ValueMember and DisplayMember properties. DisplayMember tells what property in the roles data source to be used to display as the dropdown item text. ValueMember specifies the property to be used to identify each of the item behind the scenes.
When you submit the details, access the SelectedValue property to get the RoleId corresponding to the selected role name.
private void btnCreate_Click(object sender, EventArgs e)
{
var firstName = txtFirstName.Text;
var lastName = txtLastName.Text;
var roleId = (int)cbxRole.SelectedValue;
}
The SelectedValue property fetches the value of the column identified by the ValueMember property in the dropdown definition, which is the RoleId value. Now, you can send this 'roleId' variable's value to the insert query.
here is how it looks like when you submit -
here is quick sample UI -

How do I make my query more precise based on my condition to return a string to check duplicate record exist

I am creating string function which checks duplicate record before inserting or updating a record but I have a condition with it. Before giving conditions, I have a table called Products (name, description, type, isActive, InsertedDate, UpdatedDate). Isenabled is in bit datatype (0 or 1). And InsertedDate, UpdatedDate are auto generated.
In isActive column
0 means disable
1 means enable
Before inserting (or even updating), check whether name is unique but if name exist more than one then,
My conditions
Check whether product is isActive = 1 then while inserting data should display message "Product exist in the table."
Check whether product is isActive = 0 then while inserting data should display message "Product exist but it is disabled."
Else Insert/Update the data.
Below function only check whether record exist or not and return message accordingly.
Question: How can I have return proper message regardless I am checking above query for inserting or updating a record and it goes over my requirement. As Top 1 can help me to insert new record checking if name is unique and it will return empty but if I am updating row with its own keeping name as it is and changing other column which is description. And when I update that I am receiving message "Record exist in the table" which it should not give me and should updating without message. So how can I make this query check for both the method inserting and updating record.
Here is what I have tried:
private string GetName(string name, int id)
{
using (var connection = connection string)
using (var command = new SqlCommand())
{
command.Connection = connection;
command.CommandText =
#"DECLARE #Enabled INT; " +
#"SET #Enabled = " +
#"( " +
#"SELECT TOP 2 p.isActive " +
#"FROM dbo.[product] p WITH (nolock) " +
#"WHERE p.name = #name " +
#"); " +
#"SELECT Msg = CONVERT( VARCHAR(32), " +
#"CASE " +
#"WHEN #Enabled = 0 " +
#"THEN 'Record is disabled' " +
#"WHEN #Enabled = 2 " +
#"THEN 'Record exist in the table' " +
#"ELSE ''";
#"END);";
command.Parameters.AddWithValue("name", name);
command.CommandTimeout = 100;
connection.Open();
command.ExecuteNonQuery();
string message = (string)command.ExecuteScalar();
connection.Close();
return message;
}
}
return string.Empty;
}
Note My query might be wrong. If you do not understand my query then please go over to what I am doing before inserting or updating record and accordingly I am expecting to have a query. Also please don't worry about Insert or update query I have a different method which takes care of it. Also if you have any solution which can help me to solve my probkem ten I would really appreciate that.
Summery
First check duplicate record exist or not (Means check all names are unique).
If name exist more than 1 then check isActive is 0 or 1 and accordingly sends the message which I am showing in my query.
FYI: I know I can do it in Stored Procedure but this is like a requirement to do it with command parameter.
Also if you guys think tha this post does not have consistant, please let me know instead of downgrading or flagging it.

Duplicate key on mysql

I have a POS system that will be used to create receipts in two different locations. the problem i am having right now is that when both location enter a receipt at the same time, they would have the same receipt ID, and therefore, i made a pretty bad way to fix this problem.
while (!success)
{
try
{
MySqlCommand myCommand4 = new MySqlCommand("Insert into OrderRecords_table values('" + OrderID + "','" + customerCode + "','" + customer + "','" + TelComboBox.Text + "','" + LicenseComboBox.Text + "','" +
DriverComboBox.Text + "','" + AddressComboBox.Text + "','" + LocationTypeComboBox.Text + "','" + PickupComboBox.Text + "','" + CustomerTypeLabel.Text + "','" +
Convert.ToDecimal(TotalPriceLabel.Text) + "','" + status + "','" + note + "','" + sandReceiptNo + "','" + createtiming + "','" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "')", myConnection52);
myCommand4.ExecuteNonQuery();
if (retried == true)
{
MessageBox.Show("收據號碼已改為: " + OrderID);
}
success = true;
}
catch (MySqlException ex)
{
switch (ex.Number)
{
case 1062:
retried = true;
OrderID = OrderID.Substring(0, 1) + (Convert.ToInt32(OrderID.Substring(1, OrderID.Length - 1)) + 1).ToString("00000");
success = false;
break;
}
}
}
i have wrote this to catch the exception, and increase the receipt number when that duplicate key happens, and it worked fine when i first test it, however, it is won't catch the exception anymore, and it would just insert the record.
I don't know how it breaks the rules on mysql.
the situation right now is like the following:
if i have a record with receipt number: m00001 (orderID col)
and the other program is trying to insert a receipt number that is also m00001, it should catch that exception, but it insert both m00001 somehow. (orderID column is set as primary key).
i was doing some researches online to see if there is another way to fix this problem, and i found this
INSERT INTO table (a,b,c) VALUES (1,2,3)
ON DUPLICATE KEY UPDATE c=c+1;
however, this update the old record instead of the new one, is there another way that would update the one that i am trying to insert if it is found duplicated?
Thanks
Classic concurrency control problem. Modern relational databases handle this problem by having the database generate the ID. Internally, the database utilizes a mutex to ensure that only one thread is ever able to increment the counter at once. This is usually exposed in SQL via sequences or a special data type that wraps up the functionality. In MySQL, there is a special data type called SERIAL that will handle the IDs automatically using MySQL's internal sequence generator called AUTO_INCREMENT.
Otherwise, you will have to implement locking and concurrency control yourself. I do not recommend doing this, since MySQL can do it better and faster than you could, but it is possible.
Changing an existing column to begin using AUTO_INCREMENT is a trivial operation that can be quickly done against smaller data sets (less than a million rows or so). Let's say you have a table that looks like this:
mysql> SHOW CREATE TABLE t_receipts;
+------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| t_receipts | CREATE TABLE `t_receipts` (
`id` bigint(20) unsigned NOT NULL,
`amount` double(8,2) DEFAULT NULL,
`date_created` datetime DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)
Converting the table is as simple as:
ALTER TABLE t_receipts CHANGE id id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT;
Or, using the SERIAL shortcut:
ALTER TABLE t_receipts CHANGE id id SERIAL;
visual studio has a great tool called entity framework for .net, there is a guide to use it with MySQL. It will make everything a lot safer and easier, it would suggest you use this.
Using the entity Framework and Linq if there is a problem, like a duplicate key it will always throw an exception. Creating keys if you cannot use auto increment or a GUID is a bit easier because of the exceptions, you will always know when the key you tried to insert is wrong.
A table in your database will just be a class in C# with the entity model, you simply create a new object of this class fill in the field, add it to the collection (which corresponds to the records in your database) and save. on save it will check if it is original and the record will be created.
For as far as I know this will never allow for a duplicate key no matter how many connections and how simultaneous the records are added.
example code for adding with linq to your entity model:
MyDbEntities mydb = new MyDbEntities();
Order order = new Order();
order.OrderID = "m0000001";
try
{
mydb.Order.Add(order);
mydb.SaveChange();
}
catch (Exception exception)
{
if(excpetion == duplicate key) // pseudo code, don't know the error for duplicate keys
{
order.OrderID = m0000002;
}
}

how to write mysql create table query in c#

how to create table query in c# for mysql database..
MySqlConnection con = new MySqlConnection("Server=localhost;Database=demo_test;UID=root;Password= ");
MySqlCommand acmd = new MySqlCommand("CREATE TABLE first (" + a.Columns[0] + " int(20) NOT NULL auto_increment,'" + a.Columns[1].ToString() + "' varchar(100) NOT NULL default,PRIMARY KEY (" + a.Columns[0]+") 1", con);
con.Open();
acmd.ExecuteNonQuery();
it gives me an error
You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use
near ''name' varchar(100) NOT NULL default,PRIMARY KEY (id) 1' at line
1
Instead of fighting with SQL directly, you could use Mig# like this:
var schema = new DbSchema(ConnectionString, DbPlatform.MySql5);
schema.Alter(db => db.CreateTable("first")
.WithPrimaryKeyColumn(a.Colunns[0], DbType.Int32).AsIdentity()
...);
It's because you are wrapping the column names with single quote which converts the value into string and not an identifier anymore. Remove the single quotes and it will work.
string query = #"CREATE TABLE first (" + a.Columns[0] + " int(20) NOT NULL auto_increment, "
+ a.Columns[1].ToString() + " varchar(100) NOT NULL default,
PRIMARY KEY (" + a.Columns[0]+")"

Categories

Resources