How can I delete a single entry from a table - c#

I have a listbox with usernames, and a remove button I want the selected a user (with all entered data associated with that user) to be deleted when the remove button is clicked.
My code
SqlConnection con = new SqlConnection("Data Source=JAMES-PC\\SQLEXPRESS;Initial Catalog=staff;Integrated Security=True");
con.Open();
string sql = #"DELETE FROM staff1;";
SqlCommand cmd = new SqlCommand(sql, con);
cmd.ExecuteNonQuery();
con.Close();
this code deletes the whole table.
How can I just delete the selected user?

You need a WHERE clause to select the required record. You have to get the username of the selected user to be deleted and pass it to #UserName parameter.
var userName = (listBox.SelectedItem as DataRowView)["UserName"].ToString();
string sql = #"DELETE FROM staff1 WHERE Username = #UserName;";
SqlCommand cmd = new SqlCommand(sql, con);
cmd.Parameters.AddWithValue("#UserName",useName);
cmd.ExecuteNonQuery();
con.Close();
See this thread on how to use parameters in the SQL.

When you execute a delete query, in order to delete only 1 row from the table you need to add a WHERE clause.
Based on the comments the workflow should be something like: you click on a delete button, you send the name of the staff you want to delete to the command, which looks like:
string sql = #"DELETE FROM staff1 where Name=#Name;";
SqlCommand cmd = new SqlCommand(sql, con);
cmd.Parameters.AddWithValue("#Name","NameReceivedFromList");
cmd.ExecuteNonQuery();
con.Close();

When you are deleting you should remember to add a Where clause, it is actually very powerfull here is some examples that will get you started
The following query will delete only one element
DELETE FROM Table WHERE Table.PrimaryField = Value
The following query will delete all items that matches
DELETE FROM Table WHERE Table.Field = Value
You can also have a join in your delete statement for more complex delete queries
DELETE A FROM Table A
INNER JOIN TableB B ON A.Key = B.Key
WHERE B.PrimaryField = Value

Related

How to use FK SQL in a relation M:1

i need to understand how to work with FK SQL,i'm really desperate. I've a FK between two tables. From a third table i select what item i want to Execute(those item's are local urls). I select them, i run them, i need to save in the third table(tabStoricoDetail) a code referred to the items started. STOP if i manage how to do that i can then try to pickup the first date of the first event and the last date of the last item. I thought that the FK that i've made was ok but it's not. PLEASE HELP PLEASE
//btnStart it allows to lunch the selected items
private void btnSTART_Click(object sender, RoutedEventArgs e)
{
ApplyExecuteResults(ExecuteResults());//non toccare
sqliteCon.Open();
if (sqliteCon.State == System.Data.ConnectionState.Open)
{
SqlCommand cmd1 = new SqlCommand("INSERT INTO tabStoricoDetail(NomeItem,ResItemDet)values('Prova','RProva')", sqliteCon);
/*cmd1.Parameters.AddWithValue("#DATESD", this.DPStart.Text);
cmd1.Parameters.AddWithValue("#DATEED", this.DPEnd.Text);*/
cmd1.ExecuteNonQuery();
cmd1.Parameters.Clear();
SqlCommand cmd2 = new SqlCommand("UPDATE tabStoreExec SET FK_TSD_id =(tabStoricoDetail.id)", sqliteCon);
cmd2.ExecuteNonQuery();
cmd2.Parameters.Clear();
MessageBox.Show("Dato Aggiunto");
}
sqliteCon.Close();
}
When inserting a row into tabStoricoDetail you will need to save the generated ID into a variable. Note the OUTPUT clause of the INSERT statement:
SqlCommand cmd1 = new SqlCommand("INSERT INTO tabStoricoDetail(NomeItem,ResItemDet) OUTPUT inserted.Id VALUES ('Prova','RProva')", sqliteCon);
/*cmd1.Parameters.AddWithValue("#DATESD", this.DPStart.Text);
cmd1.Parameters.AddWithValue("#DATEED", this.DPEnd.Text);*/
int generatedId = Convert.ToInt32(cmd1.ExecuteScalar());
cmd1.Parameters.Clear();
Then you just use this generatedId when updating tabStoreExec, although you probably want some kind of WHERE on that UPDATE, because right now you'll just update all the existing rows.
SqlCommand cmd2 = new SqlCommand("UPDATE tabStoreExec SET FK_TSD_id = #tsdId", sqliteCon);
cmd2.Parameters.AddWithValue("#tsdId", generatedId);
cmd2.ExecuteNonQuery();

How do I add data from ListBox into SQL Server database in C# Windows forms?

I am working on a project where the user gets to generate a set of licenses keys and export it into a text file. The information is then displayed in a listbox as shown below. I am using C# and Windows Forms:
On top of this I would also like to save the details from the listbox into the local SQL Server database for record keeping purposes in my application. I have tried out various methods I found online to do this but all were unsuccessful.
One of the methods I've found is from this link:
https://www.youtube.com/watch?v=hUZGyA6UKGI&t=0s&index=26&list=PLZEMJ7iJtVdq9aMAiDfRlMoNrzGaWOfkZ
Here is the code I used from the video tutorial:
private void recordinserted(List<string>li)
{
StringBuilder stringbi = new StringBuilder(string.Empty);
foreach (string item in li)
{
const string qry = "Insert into [LicenseDB](Comapny Name, Software Name, LicenseKeys)values";
stringbi.AppendFormat("{0}('{i}');",qry,item);
}
SqlConnection con = new SqlConnection();
con.ConnectionString = (#"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\User\Documents\Database.mdf;Integrated Security=True;Connect Timeout=30");
con.Open();
SqlCommand cmd = new SqlCommand();
cmd.CommandText = stringbi.ToString();
cmd.Connection = con;
int a = cmd.ExecuteNonQuery();
if (a > 0)
{
MessageBox.Show("inserted");
}
}
// adding into local database (method placed in button click)
List<string> li = new List<string>();
foreach (ListViewItem item in lbGeneratedKeys.Items)
{
if (item.Selected)
{
li.Add(item.Text);
}
recordinserted(li);
}
I realized that the person was using C# with ASP.Net and makes use of ListITem property which Windows Form does not have.
The other method I used is the classic SqlConnection method:
//adding into local database
using (SqlConnection con = new SqlConnection(#"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\User\Documents\Database.mdf;Integrated Security=True;Connect Timeout=30"))
{
con.Open();
SqlCommand cmd = new SqlCommand("INSERT INTO LicenseDB (Company Name, Software Name, LicenseKeys,LicenseFileNo) VALUES (#cName, #sName, #lKeys, #lno)");
cmd.CommandType = CommandType.Text;
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
lbGeneratedKeys.Items.Add(dr[0].ToString());
lbGeneratedKeys.Items.Add(dr[1].ToString());
lbGeneratedKeys.Items.Add(dr[2].ToString());
lbGeneratedKeys.Items.Add(dr[3].ToString());
}
}
I used (dr[0].ToString()) to read each line from the listbox to be added into the database, where each number represents a row in the listbox. Eg. [0] represents the company name in the listbox. However when I try to execute the program there's an error saying that the SqlDataReader row is not initialized.
Also, since my program has the algorithm for users to generate more than one license keys, I also need help on how I can group these several rows of generated license keys to be added into one database column in the Database table. For instance in my UI above, I chose to generate 3 license keys and each license key takes up a row in the ListBox, I would like to group these three rows together to be placed under one database column variable (licenseKeys). I would like the algorithm to be able to read the generated keys dynamically as well as the user can generate as many license keys as needed.
I hope I had understood your problem:
First of all, I think is very important to define your data model. For example, in order to allow that a user can define a lot of keys, I would use another table where all the keys were stored, after that you need to define if a same key could be related to more than one row on the table 'LicenseDB' (in the table 'LicenseDB' you would have the columns Company Name, Software Name, LicenseFileNo). If so you'd have the relation (n:n) and then you would need to build another intermediate table that defines the relation between the table 'keys' and the table 'LicenseDB' . If it's not the case, then you simple define the relation between 'keys' and 'LicenseDB' (n:1) adding a column licenseDbID to the table 'keys' that relation many keys to one row in the table 'LicenseDB'
On the other hand, the problem with your code is that you are trying to insert data and not to read data, so you don't need a DataReader instead of that you just simply could implement something like this:
using (SqlConnection con = new SqlConnection('YOUR STRING CONNECTION'))
{
con.Open();
string comando = "INSERT INTO LicenseDB (companie, software) VALUES ('" + lbGeneratedKeys.Items[0].ToString() + "','" + lbGeneratedKeys.Items[1].ToString() + "')";
SqlCommand cmd = new SqlCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = comando;
cmd.Connection = con;
cmd.ExecuteNonQuery();
}
In this case, two values are inserted into the table LicenseDB the values for companie name and software name.
I hope I had helped you.
I referred back to my previous school project and managed to save my listbox data into the SQL database. I have two listboxes in total: 1 for allowing user to export as text file, and the second to specifically store generated license keys only. The second listbox is set to not visible in my program.
The codes I used:
private void exportKey_Click(object sender, EventArgs e)
{
//adding into local database
//excludes adding licensekeys
SqlConnection sqlCon = new SqlConnection(#"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\User\Documents\Database.mdf;Integrated Security=True;Connect Timeout=30");
sqlCon.Open();
SqlCommand sqlCmd = new SqlCommand("addLicensedata", sqlCon);
sqlCmd.CommandType = CommandType.StoredProcedure;
sqlCmd.Parameters.AddWithValue(#"companyName", companyTextbox.Text.Trim());
sqlCmd.Parameters.AddWithValue(#"softwareName", softwareTextbox.Text.Trim());
sqlCmd.Parameters.AddWithValue(#"prodID", prodidTextbox.Text.Trim());
sqlCmd.Parameters.AddWithValue(#"licenseType", cbLicensetype.Text.Trim());
sqlCmd.Parameters.AddWithValue(#"LicenseNo", licensekeyNum.Text.Trim()); //no of license keys
sqlCmd.ExecuteNonQuery();
//MessageBox.Show("Added to database");
sqlCon.Close();
if (cbLicensetype.SelectedItem.ToString() == "Trial")
{
sqlCmd.Parameters.AddWithValue(#"TrialDays", tbTrialdays.Text.Trim());
}
addtoFKtable();
private void addtoFKtable()
{
SqlConnection Con = new SqlConnection(#"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\User\Documents\Database.mdf;Integrated Security=True;Connect Timeout=30");
Con.Open();
SqlCommand Cmd = new SqlCommand("addLicensekeys", Con);
Cmd.CommandType = CommandType.StoredProcedure;
Cmd.Parameters.AddWithValue(#"LicenseNo", licensekeyNum.Text.Trim());
Cmd.Parameters.AddWithValue(#"LicenseKeys", lbHidden.Text.Trim());
Cmd.Parameters.AddWithValue(#"prodID", prodidTextbox.Text.Trim());
Cmd.Parameters.AddWithValue(#"companyName", companyTextbox.Text.Trim());
Cmd.ExecuteNonQuery();
//MessageBox.Show("Added license to database");
Con.Close();
}
I stored my SQL commands as a stored procedure within the database, and just called the command in my codes.

Datarow id string not matching with object id string even though they are identical strings after checking debug

I am trying to search through a list of ID strings in my database where an ID string is equal to the one of the object i am trying to create. The id being created is in a factory design pattern where a train type "express" is made with an ID of "1E45". After this ID is created, it increments the number section after the letter and then that can be used for the next train added.
When searching through the list with a foreach it returns the id from the database that is similar to the one trying to be created.
But when I try to match these two after using toString to change them both and match in an IF. The match returns false even though when I check the debug it is exactly the same?
It then just continues on to try and add a new object with that ID that already exists and crashes.
What am I doing wrong? it doesn't make sense after checking the values being matched and it saying false.
Here is the code I have set up:
//Create sql command variables to create new commands
SqlCommand insert = new SqlCommand();
SqlCommand checkID = new SqlCommand();
//Set the command type to text
insert.CommandType = CommandType.Text;
checkID.CommandType = CommandType.Text;
//Searches for an ID in the database that matches one that is trying to be created
checkID.CommandText = "SELECT id FROM Train WHERE id = #trainID";
//Parameters for checking ID in database
checkID.Parameters.AddWithValue("#trainID", train.TrainID);
//Set the connection for the command for the checkID sql connection
checkID.Connection = con;
//Start the connection
con.Open();
DataTable dt = new DataTable();
SqlDataAdapter adapter = new SqlDataAdapter(checkID);
adapter.Fill(dt);
dt.Load(checkID.ExecuteReader());
//Item last = Module.
foreach (DataRow i in dt.Rows)
{
if (i.ToString() == train.TrainID.ToString())
{
MessageBox.Show("This ID already exists! " + train.TrainID);
return;
}
}
//Close the connection
con.Close();
//Set the text for the command to insert data to the database connected to
insert.CommandText = "INSERT Train (id, departure, destination, type, intermediate, departure_time, departure_date, sleeperBerth, firstClass) " +
"VALUES ( #trainID , #departure, #destination, #type, #intermediate, #dep_time, #dep_date, #sleep, #first)";
//Parameters for adding values from the train object to the database
insert.Parameters.AddWithValue("#trainID", train.TrainID);
insert.Parameters.AddWithValue("#departure", train.Departure);
insert.Parameters.AddWithValue("#destination", train.Destination);
insert.Parameters.AddWithValue("#type", train.Type);
insert.Parameters.AddWithValue("#intermediate", intStops);
insert.Parameters.AddWithValue("#dep_time", train.DepartureTime);
insert.Parameters.AddWithValue("#dep_date", train.DepartureDay);
insert.Parameters.AddWithValue("#sleep", train.SleeperBerth);
insert.Parameters.AddWithValue("#first", train.FirstClass);
//Set the connection for the command for the insert sql connection
insert.Connection = con;
//Start the connection
con.Open();
//Execute the command specified
insert.ExecuteNonQuery();
//Close the connection
con.Close();
Sounds like you need to change your column id in the table train to an IDENTITY column, and let the database handle the ID assignment:
ALTER TABLE dbo.Train ALTER COLUMN id int IDENTITY(1,1); --data type guessed
Then, in your application, you don't need to generate a value for ID, nor do declare it in your INSERT statement (either in the list of columns to INSERT into or in your VALUES clause).

DeleteButton code for deleting the data from SQL Server database

I have a form name "AddNewUnitForm" through this I am saving data in a SQL Server database. Please advice code for "DeleteButton" deleting the data from database by selected data of datagridview
SaveButton code is as under for the reference
string connString = ConfigurationManager.ConnectionStrings["dbx"].ConnectionString;
using (SqlConnection conn = new SqlConnection(connString))
{
using (SqlCommand cmd = new SqlCommand("usp_UnitMasterInsertDetails", conn))
{
cmd.CommandType = CommandType.StoredProcedure;
//Parameter
cmd.Parameters.AddWithValue("UNITNAME", AddUnitTextBox.Text);
//Open Connection
conn.Open();
// ExecuteReader (Select Statement)
// ExecuteScalar (Select Statement)
// ExecuteNoQuery (Insert, Update or Delete)
cmd.ExecuteNonQuery();
MessageBox.Show("ADDED SUCCESSFULLY", "Succesful", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
create a stored procedure to delete records
use transactions to if there is a fall back, while deleting
your delete button code will be similar to the insert here you will be calling stored procedure for deleting, with key parameter to pass the stored procedure.
if you want to do soft delete make a column with flag IsDeleted and changes the flag when deleted

Get auto_increment id from table

I have this code:
string conStr = ConfigurationManager.ConnectionStrings["BackgammonGame"].ConnectionString;
SqlConnection con = new SqlConnection(conStr);
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
con.Open();
cmd.CommandText = ("INSERT INTO Game (playerA, playerB) OUTPUT INSERTED.gameID VALUES (#playerA, #playerB)");
cmd.Parameters.Add("#playerA", SqlDbType.NVarChar).Value = firstPlayer;
cmd.Parameters.Add("#playerB", SqlDbType.NVarChar).Value = secondPlayer;
cmd.ExecuteNonQuery();
int id = (int)cmd.ExecuteScalar();
con.Close();
When I insert into this table, I have an auto_increment int primary key column called gameID, and I declared in the sql statement that I want the gameID in output.
my problem is that when I write this line in the code: int id = (int)cmd.ExecuteScalar(); the inserted parameters apear twice in the table (2 rows with the same info.), but when I delete it it's ok.
I need this row so I can use this id in other table.
Change your command text with this and try
cmd.CommandText = ("INSERT INTO Game (playerA, playerB) VALUES (#playerA,#playerB);
SELECT SCOPE_IDENTITY()");
SCOPE IDENTITY returns the identity value of last inserted row. Hence that will returns the identity filed of the inserted row using the insert query
EDIT
You are executing the query two times
cmd.ExecuteNonQuery(); // Avoid this
int id = (int)cmd.ExecuteScalar();// This is enough
In both case your query gets executed and it cause insertion twice.
ExecuteNonQuery() will execute the insert query and will returns the number of rows affected.
Where as ExecuteScalar() will return the result of the select scope_identity() staement which is the identity column of the inserted row.
Here is your code
con.Open();
cmd.CommandText = ("INSERT INTO Game (playerA, playerB) VALUES (#playerA,#playerB);
SELECT SCOPE_IDENTITY()");
cmd.Parameters.Add("#playerA", SqlDbType.NVarChar).Value = firstPlayer;
cmd.Parameters.Add("#playerB", SqlDbType.NVarChar).Value = secondPlayer;
int id = Convert.ToInt32(cmd.ExecuteScalar());
con.Close();
Modify your command like this
INSERT INTO YourTable(val1, val2, val3 ...)
VALUES(#val1, #val2, #val3...)
SELECT SCOPE_IDENTITY()
But i personally prefer to write a stored procedure and return the primary key as an output parameter of that sp.

Categories

Resources