How can add new row without insert with ado.net - c#

stokService = new StokService();
var stok = stokService.stokList("Select * from xstSabit where stokKodu= '" + txtStokKodu.Text + "' ");
dgvSepet.DataSource = stok;
this stok selected and viewed in Datagridview there is no problem. I want to add one more stok to Datagridview with existing stok but in this code it is only return one stok. How can ı add new rows without insert ?

As far as I know this is impossible. The alternative would be to upgrade an existing row if inserting new raw is not so mandatory.

Related

Scanning my table c# mysql

So i'm making a library system, and i encounter a problem in my Borrowing and Returning of books.
When i borrow a book then return it changing the status to return, then borrowing that same book again success, then when i'm returning it my trapping for return books message show.
sql = "SELECT * FROM tbltransactionbooks WHERE fBarCodeNo LIKE '" + txtBARCODE_R.Text.Trim() + "%'";
cfgotcall.engageQuery(sql);
if (cfgotcall.tbl.Rows[0]["fStatus"].ToString().Equals("Borrowed"))
{
txtTITLE_R.Text = cfgotcall.tbl.Rows[0]["fBookTitle"].ToString();
txtAUTHOR_R.Text = cfgotcall.tbl.Rows[0]["fAuthor"].ToString();
txtYEAR_R.Text = cfgotcall.tbl.Rows[0]["fBookYr"].ToString();
txtACCNO_R.Text = cfgotcall.tbl.Rows[0]["fAccNo"].ToString();
txtCALLNO_R.Text = cfgotcall.tbl.Rows[0]["fCallNo"].ToString();
txtBARCODE_BR.Text = cfgotcall.tbl.Rows[0]["fBarcodeNo"].ToString();
txtSEARCH.Text = cfgotcall.tbl.Rows[0]["fStudent"].ToString();
txtReturnDate.Text = cfgotcall.tbl.Rows[0]["fBorrowDate"].ToString();
txtIDNO.Text = cfgotcall.tbl.Rows[0]["fIDStudent"].ToString();
txtLEVEL.Text = cfgotcall.tbl.Rows[0]["fLevel"].ToString();
}
else
{
MessageBox.Show("Book already returned.");
}
What i debug in my own code in the pic is it doesn't scan the whole rows in the tbltransactionbooks it only reads the first row of my table.
33 123 NAME IT 2/20/2017 2/20/2017 [HISTORY OF] COMPUTERS: THE MACHINES WE THINK WITH Returned
33 123 NAME IT 2/21/2017 2/21/2017 [HISTORY OF] COMPUTERS: THE MACHINES WE THINK WITH Borrowed
![2]: http://i66.tinypic.com/28ajgwg.jpg
How dow I scan the whole rows in my table? If my code above does not look good I'm open in suggestion of how I am able make it clean. thanks
cfgotcall.tbl.Rows[0] refers to the the first row only.
You should iterate each row:
sql = "SELECT * FROM tbltransactionbooks WHERE fBarCodeNo LIKE '" + txtBARCODE_R.Text.Trim() + "%'";
cfgotcall.engageQuery(sql);
foreach(var row in cfgotcall.tbl.Rows)
{
if (row["fStatus"].ToString().Equals("Borrowed"))
{
txtTITLE_R.Text = row["fBookTitle"].ToString();
txtAUTHOR_R.Text = row["fAuthor"].ToString();
txtYEAR_R.Text = row["fBookYr"].ToString();
txtACCNO_R.Text = row["fAccNo"].ToString();
txtCALLNO_R.Text = row["fCallNo"].ToString();
txtBARCODE_BR.Text = row["fBarcodeNo"].ToString();
txtSEARCH.Text = row["fStudent"].ToString();
txtReturnDate.Text = row["fBorrowDate"].ToString();
txtIDNO.Text = row["fIDStudent"].ToString();
txtLEVEL.Text = row["fLevel"].ToString();
}
else
{
MessageBox.Show("Book already returned.");
}
}
To avoid getting run time errors due to typos in the column names and the SQL query, you can use LINQ to SQL or Entity Framework. This way each row is converted to an object and you can access each column by accessing an object property\field.
The first row is checked because use access only the first row:
if (cfgotcall.tbl.Rows[0]...)
To check all the rows, iterate through the cfgotcall.tbl.Rows collection either using the for or foreach loop.
You are only accessing the first row [0] of the table. You need to itterate through all of them using for or foreach loop.
Side note: I guess this is a homework. It will not do you any good if you find complete solution in the internet. You should rather try to understand how collections/arrays work and how to traverse them using loops.
A couple of tutorials to help you with the task:
https://msdn.microsoft.com/en-us/library/aa288462(v=vs.71).aspx
http://csharp.net-informations.com/collection/csharp-collection-tutorial.htm

DBConcurrency Exception Occured While Updating Using Dataadapter

I am trying to edit DataTable Filled by NpgsqlDataAdapter.
After calling Fill() method, I have only one row in DataTable. Then I changed value of one column only and tried to update as below.
Then I am getting this error:
DBConcurrencyException occured
My code is:
NpgsqlDataAdapter getAllData = new NpgsqlDataAdapter("SELECT sn,
code,product, unitprice, quantity, InvoiceNo, Date FROM stocktable WHERE Code='" + product + "'
ORDER BY EDate ASC", DatabaseConnectionpg);
DataTable ds1 = new DataTable();
ds1.Clear();
getAllData.Fill(ds1);
if (ds1.Rows.Count > 0)
{
ds1.Rows[0]["Quantity"] = qty;// calculated value
}
ds1 = ds1.GetChanges();
NpgsqlCommandBuilder cb = new NpgsqlCommandBuilder(getAllData);
//getAllData.RowUpdating += (sender2, e2) => { e2.Command.Parameters.Clear(); };
//cb.SetAllValues = false;
getAllData.DeleteCommand = cb.GetDeleteCommand();
getAllData.InsertCommand = cb.GetInsertCommand();
getAllData.UpdateCommand = cb.GetUpdateCommand();
int x = getAllData.Update(ds1);
if (x > 0)
{
ds1.AcceptChanges();
}
EDIT: I have three fields as primary keys and I am calling only two fields in select statement. Is it reason for DBConcurrency error? But I am able to update the table with same (three fields as primary key) parameters in SQL Server 2005.
UPDATE:
I found the solution and the solution is
I created and used second DataAdapter to update data.
I used getAllData(NpgSqlDataAdapter) To fill table as
NpgsqlDataAdapter getAllData = new NpgsqlDataAdapter("SELECT
code,product, unitprice, quantity, InvoiceNo, Date FROM stocktable WHERE Code='" + product + "'
ORDER BY EDate ASC", DatabaseConnectionpg);
And Also created next Adapter to update as
NpgsqlDataAdapter updateadap= new NpgsqlDataAdapter("SELECT sn, quantity FROM stocktable WHERE Code='" + product + "'
ORDER BY EDate ASC", DatabaseConnectionpg);
NpgsqlCommandBuilder cb = new NpgsqlCommandBuilder(updateadap);
//getAllData.RowUpdating += (sender2, e2) => { e2.Command.Parameters.Clear(); };
//cb.SetAllValues = false;
updateadap.DeleteCommand = cb.GetDeleteCommand();
updateadap.InsertCommand = cb.GetInsertCommand();
updateadap.UpdateCommand = cb.GetUpdateCommand();
int x = updateadap.Update(ds1);
if (x > 0)
{
......
}
I tried alot and found that NpgsqlDataAdapter had problem with Column Code. When i ommited it then it worked. DataType of column code is varchar. I don't know why this was happening. Anybody has idea about it?
This is because DataAdapter uses Optimistic Concurrency by default. This means that if you are trying to update a row that no longer exists in the database or changed, the update from the DataAdapter will fail with the exception above.
Possible scenarios:
Between you selecting the data into the client and sending the
update, another user is deleting or updating this row from his application.
It can be that you are deleting the data from somewhere else in your application.
For example:
You fill the DataTable that will be used for the update.
Deletes the row with Code = 1101 (for example) directly from the database, i.e. you do not use the DataTable here. This is emulating another user deleting the row with Code = 1101 from another application. Or some other part in your code deleting the row with Code = 1101.
Selects out the row with Code = 1101 from the DataTable, this is just to show that it is still there even though you have deleted it from the database itself.
Edits the Quantity column in the row with Code = 1101 in the DataTable. This has to be done, otherwise the call to Update will ignore this row when updating.
Executes the update, this will throw the exception since you are trying to update a row that (no longer) exists in the database.
If you want to implement Last Writer Wins, Add the following code:
cb.ConflictOption = ConflictOption.OverwriteChanges;
Also there is one more possible thing : if you have Decimal/numeric as columns in the DB they may cause this error even though the data looks the same. This is due to a decimal rounding error.
An important note:
You should always use parameterized queries by the way. This kind of string concatenations are open for SQL Injection.

Update newly added rows of datagridview to oledb database using c#

I have a datagridview and an Add and Save button. Each time I add row to the datagridview with Add button and at the end save all rows to the database by Save button.
I want add/few few rows again to the same datagriview and then save to the database but while saving new items to the database it takes whole datagridview rows again and saves to database.
I wanted to save only new added data or edited data. Is there any way to set focus to the newly added rows or edited rows ? and at the end only saves the newly added or edited rows?
My datagridview always adds/inserts data to database at the end.
I am using below code for saving datagridvew rows to database :
int chkLoop;
chkLoop = dgvOrderList.Rows.Count;
MessageBox.Show(chkLoop.ToString());
foreach (DataGridViewRow row in dgvOrderList.Rows)
{
//MessageBox.Show(chkLoop.ToString());
//MessageBox.Show(row.co.ToString());
if (chkLoop != 1)
{
comm = new OleDbCommand("INSERT INTO Orders_Description (ItemCode, Quantity, Amount, OrderId, CreatedOn) VALUES ('" + Convert.ToInt32(row.Cells["Code"].Value) + "', '" + Convert.ToInt32(row.Cells["Quantity"].Value) + "', '" + Convert.ToInt32(row.Cells["Amount"].Value) + "', '" + Convert.ToInt32(txtOrderNo.Text) + "', '" + DateTime.Now + "')", conn);
MessageBox.Show(comm.CommandText);
comm.ExecuteNonQuery();
chkLoop = chkLoop - 1;
}
}
I'm lazy to think.......
so you can add additional column with checkbox and whenever you add a new row the default value for the checkbox become selected and then when you are saving just check of that specific checkbox is checked or not.
if not checked it means it's not new row then continue to next iteration.
If you didn't got what I said comment below i will give you an example.

New record isn't loading until application restarted using C# with MySQL

I'm using a MySQL database with a C# application. I have the application set to use a form to add a new record and display existing records. Once a record is inserted, the form should re-grab records from the database, and display the last record in the table in the form (ie. the newly created record).
As it stands, it's showing the first record as the first and last record when clicking on previous/next or first/last to browse through the records in the table. It seems to be looping the the first one in the data adapter for some reason. I'm new to using MySQL with C#. Is there a way that this can be reset or updated without having to restart the application?
To populate the form, it's calling the same method as on form load, connecting to the database, getting the row count, filling the data adapter, populating the text boxes, and then closing the connection to the database. Not sure why it can't grab everything the second, etc, time around.
When the user clicks add to add the new record:
//Recounts rows in table in the table
numberOfRows = GetRowCount("tblTable");
//Resets displayedRow counter and updates form data to show new record
displayedRow = numberOfRows - 1;
UpdateFormData(displayedRow);
The number of records is updating on the form properly, so I know that's working alright.
Then in the UpdateFormData method:
cmd = connection.CreateCommand();
cmd.CommandText = "SELECT * FROM `tblTable`;";
cmd.ExecuteNonQuery();
//Fill DataAdapter
using (tblTableDataAdapter = new MySqlDataAdapter(cmd))
{
tblTableDataAdapter.Fill(tblTableDataTable);
}
tblTableDataAdapter = new MySqlDataAdapter(cmd.CommandText, connection);
tblTableDataAdapter.Fill(tblTableDataSet);
//Displays row data in textbox
textBox1.Text = tblTableSet.Tables[0].Rows[displayedRow]["FirstName"].ToString();
textBox2.Text = tblTablefDataSet.Tables[0].Rows[displayedRow]["LastName"].ToString();
textBox3.Text = tblTableDataSet.Tables[0].Rows[displayedRow]["StaffAddress"].ToString();
textBox4.Text = tblStaffDataSet.Tables[0].Rows[displayedRow]["PostalCode"].ToString();
textBox5.Text = tblTableDataSet.Tables[0].Rows[rowNumber]["City"].ToString();
textBox6.Text = tblTableDataSet.Tables[0].Rows[rowNumber]["Phone"].ToString();
textBox7.Text = tblTableDataSet.Tables[0].Rows[rowNumber]["Email"].ToString();
Okay, I figured out the problem. The dataset needed to be reset before refilling the data adapter. Changed the update method to include:
tblTableDataSet.Reset();
tblTableDataAdapter = new MySqlDataAdapter(cmd.CommandText, connection);
tblTableDataAdapter.Fill(tblTableDataSet);
And it's showing the new record now.

Store multiple ListBox selections in database?

I have a ListBox called listbox. Its "multiple selection" property is set to true. I need to store the selections from this ListBox into a database field.
Note that I am using web forms, ASP.NET, C#, and Visual Studio Web Developer 2010 Express.
My code is as follows:
SqlCommand insertNL = new SqlCommand("insert into dbo.newsletter (newsletter_subject,newsletter_body,newsletter_sentto) VALUES ('" + TextBox1.Text + "', '" + TextBox2.Text + "', '" + ListBox1.SelectedItem + "')", badersql);
badersql.Open();
insertNL.ExecuteNonQuery();
badersql.Close();
Unfortunately, this code only stores the first selected value of the ListBox in the "newsletter_sentto" column of my newsletter table. Does anyone have any suggestions as to how to fix this code? Thanks in advance.
Things to fix:
Before doing anything else, parameterize your sql. This is ripe for injection. Tutorial here.
You aren't disposing of your cmd or connection string. Wrap those in Using clauses. Example here.
Do a foreach on the items to see which ones are selected. Either store those in a comma separated list in the database (which needs parsing on the way back out) or store them in their own table.
You need to decide how you want to store the multiple "newsletter_sentto" values first.
You're best solution is to create a new child table where you have 1 row and column per selected item, with a foreign key back to your newsletter table.
You can try to store them all together in one row with multiple columns (sentto1, sentto2, etc), this will limit the max number of values you can store, and will cause problems searching across multiple fields. How will you query what was sent to a particular person? WHERE sentto1=#user or sentto2=#user... no index can be used there.
You can stuff all the value in a single row and column using a "," or ";" to separate the values. this will cause many problems because you'll have to constantly split the string apart, every time you need to get at one of the sentto values.
First, you should use parametrized queries instead of straight concatenation to protect against SQL injection. Second, you need to cycle through the selected items and build (presumably) a delimited-list of the selections.
var selectedItems = new List<string>();
foreach( var item in ListBox1.SelectedItems )
selectedItems.Add( item.ToString() );
var sql = "Insert dbo.newsletter(newsletter_subject,newsletter_body,newsletter_sentto)"
+ " Values(#newsletter_subject, #newsletter_body, #newsletter_sentto)"
badersql.Open();
using ( qlCommand = new SqlCommand(sql, badersql) )
{
qlCommand.Parameters.AddWithValue("#newsletter_subject", TextBox1.Text);
qlCommand.Parameters.AddWithValue("#newsletter_body", TextBox2.Text);
qlCommand.Parameters.AddWithValue("#newsletter_sentto", string.Join(',', selectedItems.ToArray()));
qlCommand.ExecuteNonQuery();
};
Try to get selected items like that :
string newsletterSentTo = "";
foreach (ListItem item in ListBox1.Items)
{
if (item.Selected)
newsletterSentTo += "," + item.Text;
}

Categories

Resources