How to insert/update information in SQL Server - c#

I am trying to insert new information into my already created table where id = 2019;
I get the error incorrect syntax near WHERE:
private void button6_Click(object sender, EventArgs e)
{
xcon.Open();
SqlDataAdapter xadapter = new SqlDataAdapter();
xadapter.InsertCommand = new SqlCommand("INSERT into dbo.SysX VALUES (#fpp, #sdd, #sff) WHERE id = 2019", xcon);
xadapter.InsertCommand.Parameters.Add("#fpp", SqlDbType.Int).Value = Convert.ToInt32(textBox1.Text);
xadapter.InsertCommand.Parameters.Add("#sdd", SqlDbType.Int).Value = Convert.ToInt32(textBox2.Text);
xadapter.InsertCommand.Parameters.Add("#sff", SqlDbType.Int).Value = Convert.ToInt32(textBox3.Text);
xadapter.InsertCommand.ExecuteNonQuery();
xcon.Close();
}
How can I insert new information on click of button where ID = 2019?

You need to change the below line
xadapter.InsertCommand = new SqlCommand("INSERT into dbo.SysX VALUES (#fpp, #sdd, #sff) WHERE id = 2019", xcon);
to the as below line if you want to insert value/row into the table.
xadapter.InsertCommand = new SqlCommand("INSERT into dbo.SysX VALUES (#fpp, #sdd, #sff)", xcon);
If you want to update existing record then you need to replace your SQL Statement as
"Update dbo.SysX Set <Col1> = #fpp, <Col2> = #sdd, ... where id = 2019"
You can check this Answer and this link.

INSERT and UPDATE are two really separate SQL commands. As their name suggests, with INSERT you add new record to a table, with UPDATE you edit existing record, so either you provide a pointer to an existing record to edit it
UPDATE Table SET Column = data WHERE Field = ‘x’
or you just provide a number of values to be inserted
INSERT INTO Table (Columns) VALUES (Data)
On a side note, such insertions or updates are best done with stored procedures, in order to avoid sql injection attacks.

Related

Updating a database from selected row in another form

I am having issues updating a selected row on a datagridview that pulls from a database in another form.
I used this to get the information from the datagridview into the textboxes on the other form:
private void updateAppointmentButton_Click(object sender, EventArgs e)
{
UpdateAppointment updateAppointment = new UpdateAppointment();
updateAppointment.mainFormObject = this;
updateAppointment.customerIdBox.Text = appointmentCalendar.CurrentRow.Cells[0].Value.ToString();
updateAppointment.customerNameBox.Text = appointmentCalendar.CurrentRow.Cells[1].Value.ToString();
updateAppointment.typeBox.Text = appointmentCalendar.CurrentRow.Cells[2].Value.ToString();
updateAppointment.startTimeBox.Value = Convert.ToDateTime(appointmentCalendar.CurrentRow.Cells[4].Value.ToString());
updateAppointment.endTimeBox.Value = Convert.ToDateTime(appointmentCalendar.CurrentRow.Cells[3].Value.ToString());
updateAppointment.Show();
MySqlConnection c = new MySqlConnection(SqlUpdater.conString);
MySqlCommand updateCmd = new MySqlCommand();
updateCmd.Connection = c;
c.Open();
updateCmd.CommandText = $"UPDATE customer SET customerName = '{customerNameBox.Text}'";
updateCmd.ExecuteNonQuery();
c.Close();
MessageBox.Show("Appointment Updated");
I figure its the SQL query, but not sure how to limit it to JUST the information on the selected row. Right now, it'll update everyone on the datagridview and database.
Any ideas?
Thanks!
I've tried putting
MainForm.appointmentCalendar.CurrentRow.Cells[1].Value.ToString();
as WHERE in the SQL query, but it returns an "object reference is required" error.
have a column with unique customer ID, then in your query you want
Update customer SET customerName = '{customerNameBox.Text}' where customerID = 'UniqueID'
----- (whatever the ID that you are trying to update is)
probably something like int.Parse(otherDataGrid.selectedRows[0].Cells["ID"].Value.ToString())
#edit
I don't really understand what you're trying to say. You might want to try with parameteres. this would be your query:
Update appointment set type = #type, start = #start, end = #end where customerId = #id
then before you execute the command you say:
updateCmd.Parameters.AddWithValue("#type", typeBox.Text);
and do that for all other parameters too.
Also make sure that your text boxes are not empty, because they most likely are if your query is deleting the data (maybe it's updating it with an empty string)

Delete all access database table data

I have an access database that I am manipulating with C#.
I have connected to it, retrieved a data-set from it and can add rows to a table. Now I am trying to clear a table and I am unable to get it to work.
I have tried TRUNCATE TABLE table_name but that throws an exception saying that I must use either DELETE, INSERT, PROCEDURE, SELECT or UPDATE and I have tried Delete FROM table_name However that throws an DBConcurrenceyException.
Here is what I have to tried to clear the table:
private void ClearBut_Click(object sender, EventArgs e)
{
OleDbDataAdapter dtaAdpTestTableClear = new OleDbDataAdapter();
OleDbCommand command;
command = new OleDbCommand("DELETE FROM TestTable", con);
dtaAdpTestTableClear.DeleteCommand = command;
foreach (DataRow row in dsWCSDHDB.Tables["TestTable"].Rows)
{
row.Delete();
}
dtaAdpTestTableClear.Update(dsWCSDHDB.Tables["TestTable"]);
}
My other add method
private void Add_Click(object sender, EventArgs e)
{
OleDbDataAdapter dtaAdpTestTableInsertNewRow = new OleDbDataAdapter();
OleDbCommand command;
// Create the InsertCommand.
// This is needed as DataAdaptor.InsertCommand() is called during the update to insert the row into the database. It requires an insert query
command = new OleDbCommand("INSERT INTO TestTable (id, someData) " +"VALUES (?, ?)", con); //We create a dbcommand the command is, Querytype, what we are doing with it, what table, (columns we are using), concat, Values we will be adding(as ? for now as we will pass this data in latter), connection to the database
command.Parameters.Add("id", OleDbType.Char, 5, "id"); //this is where we add a parameter to the command function. we add one per column in the row (columns we are using name, value type, column length, source column, these parameters will replace the ? in the query above
command.Parameters.Add("someData", OleDbType.VarChar, 40, "someData");
dtaAdpTestTableInsertNewRow.InsertCommand = command;// we attach this command to the Insert command function of the adapter that we are using
//Create the new row
DataRow row = dsWCSDHDB.Tables["TestTable"].NewRow(); //Create a new empty row that is formated for the TestTable table
row["someData"] = AddValueTextBox.Text.ToString();// add in the values
//Add the new row to the dataset table
dsWCSDHDB.Tables["TestTable"].Rows.Add(row); //adds this new row to the clients dataset
//Updates the database table with the values of the clients dataset Table
//For this to work you need to build a proper data adapter that is using a query taylered for the table you are using.
//Unfortunately although it would be nice to be able to add and use tables to the database with out changing the code you cant build a generic one that works for all tables in the database.
//this is because different tables can have different fields and column lengths .
//there is a example of how to build one below
//Update the database table with the values of the clients dataset Table
dtaAdpTestTableInsertNewRow.Update(dsWCSDHDB.Tables["TestTable"]); // using the adapter that we created above we update the database with the clients dataset.
}
You will just need to call ExecuteNonQuery
private void ClearBut_Click(object sender, EventArgs e)
{
string comand = "DELETE FROM TestTable";
OleDbCommand cmd = new OleDbCommand(comand, con);
cmd.ExecuteNonQuery();
}

Updating SQLite DB from DGV (C#)

On one form I have a dgv. From another form, I can add an item to the dgv and also place the new item into the SQLite database.
What I'm trying to do is also be able to edit the item from the dgv, and have the edit be saved in the database also.
I have this code for CellEndEdit event:
SetConnection();
sqlconnection.Open();
this.dataGridView1.Rows[e.RowIndex].Selected = true;
this.rowIndex1 = e.RowIndex;
this.dataGridView1.CurrentCell = this.dataGridView1.Rows[e.RowIndex].Cells[0];
sqlcmd = new SQLiteCommand("UPDATE table1 SET item = #item, quantity = #quantity WHERE id= " + this.dataGridView1.Rows[this.rowIndex1].Cells["id"].Value, sqlconnection);
sqlcmd.Parameters.AddWithValue("#item", this.dataGridView1.Rows[this.rowIndex1].Cells["item1"].Value);
sqlcmd.Parameters.AddWithValue("#quantity", this.dataGridView1.Rows[this.rowIndex1].Cells["quantity1"].Value);
sqlcmd.ExecuteNonQuery();
sqlconnection.Close();
This code works, but only if I load the database to the dgv.
When the program is first opened, the database isn't loaded into the dgv. The problem I run into, is when I add a new item (and its the only item present in the dgv), and I try to edit it (aka. change name.etc.), I get the following error: SQL logic error or missing database
near " ": syntax error
Note: When the dgv is empty and I add a new item, the new item is successfully added to the database table.
Also Note: 'id' is the PRIMARY KEY and AUTOINCREMENTed
The situation you're having here is that when you add a new item to the DGV, you are not providing a value to the ID column. So at the end of the query
"UPDATE table1 SET item = #item, quantity = #quantity WHERE id= " + this.dataGridView1.Rows[this.rowIndex1].Cells["id"].Value
This will become like id = . because the ID column in the DGV is currently empty and is definitely a Syntax Error.
It works when you load data because, you are filling up this column. So the solution is to provide value to the ID column properly when you insert a new item.
After inserting an entry to the db, get the Automatically Incremented ID by using a query
Select last_insert_rowid();
Read the value using reader and apply it to the ID column of the table
This works for me.
private void btnUpdate_Click(object sender, EventArgs e)
{
using (SqlConnection con = new SqlConnection("Server=your_server_name;Database=your_db_name;Trusted_Connection=True;"))
{
using (SqlCommand cmd = new SqlCommand("SELECT * FROM Courses", con))
{
using (SqlDataAdapter da = new SqlDataAdapter(cmd))
{
{
SqlCommandBuilder sqlcmd = new SqlCommandBuilder(da);
DataSet ds = new System.Data.DataSet(); // remove this line
da.Update(this.ds, "Courses");
}
}
}
}
}

How do I store source code lines in SQL Server Database and access it via DataSet

I want to store the following code into the database:
fun(...);
int main()
{
fun(3, 7, -11.2, 0.66);
return 0;
}
fun(...)
{
va_list ptr;
int num;
va_start(ptr, n);
num = va_arg(ptr, int);
printf("%d", num);
}
and then get it back in the dataset and display on a page.
As of now I have successfully stored the questions with varchar(MAX) datatype but when I try to get it in the dataset i get the following error:
Failed To Enable Constraints. One Or More Rows Contain Values Violating Non-null, Unique, Or Foreign-key Constraints.
I am doing this in a ASP.NET web application.
EDIT:
Here is the Table definition of the table I am inserting the data into
The query I am using to insert the data into the table:
con.ConnectionString = constr;
cmd.Connection = con;
cmd.CommandText = "insert into QuesTable values(#D1,#D2,#D3,#D4,#D5,#D6,#D7, NULL)";
cmd.Parameters.Add("#D1", SqlDbType.Int).Value = txtQID.Text;
cmd.Parameters.Add("#D2", SqlDbType.VarChar).Value = txtques.Text;
cmd.Parameters.Add("#D3", SqlDbType.VarChar).Value = txtansa.Text;
cmd.Parameters.Add("#D4", SqlDbType.VarChar).Value = txtansb.Text;
cmd.Parameters.Add("#D5", SqlDbType.VarChar).Value = txtansc.Text;
cmd.Parameters.Add("#D6", SqlDbType.VarChar).Value = txtansd.Text;
cmd.Parameters.Add("#D7", SqlDbType.VarChar).Value = txtcorr.Text;
con.Open();
int i = cmd.ExecuteNonQuery();
con.Close();
And finally the code by which I am extracting the data from the dataset
DataSet1.QuesTableDataTable dt = new DataSet1.QuesTableDataTable();
DataSet1TableAdapters.QuesTableTableAdapter adp = new DataSet1TableAdapters.QuesTableTableAdapter();
dt = adp.GetData();
DataTable dtUser = dt.Clone();
Hope the information is helpful.
Since I can't see if you've got any other further constraints on the table, it looks like the value you're inserting into the primary key field (Qid) already exists in the table.
If you need to create a new row for every entry regardless, it would probably be easier to change the column Qid to maintain its own Identity. If you need to update an existing value, you'll need to add a separate piece of logic to determine if the primary key value already exists and update or insert accordingly.
That's an error related to either:
A not null field is having a null passed in when you load the data.
A foreign key or unique index check is invalid (for instance, FK value of 9 doesn't exist).
If you fill the dataset, the error that is generated should be retrievable from the dataset.
HTH.

add row to a BindingSource gives different autoincrement value from whats saved into DB

I have a DataGridView that shows list of records and when I hit a insert button, a form should add a new record, edit its values and save it.
I have a BindingSource bound to a DataGridView. I pass is as a parameter to a NEW RECORD form so
// When the form opens it add a new row and de DataGridView display this new record at this time
DataRowView currentRow;
currentRow = (DataRowView) myBindindSource.AddNew();
when user confirm to save it I do a
myBindindSource.EndEdit(); // inside the form
and after the form is disposed the new row is saved and the bindingsorce position is updated to the new row
DataRowView drv = myForm.CurrentRow;
avaliadoTableAdapter.Update(drv.Row);
avaliadoBindingSource.Position = avaliadoBindingSource.Find("ID", drv.Row.ItemArray[0]);
The problem is that this table has a AUTOINCREMENT field and the value saved may not correspond the the value the bindingSource gives in EDIT TIME.
So, when I close and open the DataGridView again the new rowd give its ID based on the available slot in the undelying DB at the momment is was saved and it just ignores the value the BindingSource generated ad EDIT TIME,
Since the value given by the binding source should be used by another table as a foreingKey it make the reference insconsistent.
There's a way to get the real ID was saved to the database?
I come up with this solution
First added a GetNextID() method directly to the table model:
SELECT autoinc_next
FROM information_schema.columns
WHERE (table_name = 'Estagio') AND (column_name = 'ID')
and whener I need a new row to be added I do
EstagioTableAdapter ta = new EstagioTableAdapter ();
nextID = ta.GetNextID();
row = (DataRowView)source.AddNew();
row.Row["ID"] = nextID;
(...)
source.EndEdit();
The same thing happens with Access databases. There is a great article (with solution) here. Basically, the TableAdapter normally sends 2 queries in a batch when you save the data. The first one saves the data and the second one asks for the new ID. Unfortunately, neither Access nor SQL CE support batch statements.
The solution is to add an event handler for RowUpdated that queries the DB for the new ID.
based on my answer on concurrency violation, use da.InsertCommand.UpdatedRowSource = UpdateRowSource.FirstReturnedRecord.
note: just change SQLiteConnection and SQLiteDataAdapter to MSSQL ones, and change the LAST_INSERT_ROWID() to SCOPE_IDENTITY()
const string devMachine = #"Data Source=C:\_DEVELOPMENT\__.NET\dotNetSnippets\Mine\TestSqlite\test.s3db";
SQLiteConnection c = new SQLiteConnection(devMachine);
SQLiteDataAdapter da = new SQLiteDataAdapter();
DataTable dt = new DataTable();
public Form1()
{
InitializeComponent();
da = new SQLiteDataAdapter("select product_id, product_name, abbrev from product", c);
var b = new SQLiteCommandBuilder(da);
da.InsertCommand = new SQLiteCommand(
#"insert into product(product_id, product_name, abbrev) values(:_product_id, :_product_name, :_abbrev);
select product_id /* include rowversion field here if you need */
from product where product_id = LAST_INSERT_ROWID();", c);
da.InsertCommand.Parameters.Add("_product_id", DbType.Int32,0,"product_id");
da.InsertCommand.Parameters.Add("_product_name", DbType.String, 0, "product_name");
da.InsertCommand.Parameters.Add("_abbrev", DbType.String, 0, "abbrev");
da.InsertCommand.UpdatedRowSource = UpdateRowSource.FirstReturnedRecord;
da.UpdateCommand = b.GetUpdateCommand();
da.DeleteCommand = b.GetDeleteCommand();
da.Fill(dt);
bds.DataSource = dt;
grd.DataSource = bds;
}
private void uxUpdate_Click(object sender, EventArgs e)
{
da.Update(dt);
}
here's the sample table on SQLite:
CREATE TABLE [product] (
[product_id] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
[product_name] TEXT NOT NULL,
[abbrev] TEXT NOT NULL
)
[EDIT Nov 19, 2009 12:58 PM CN] Hmm... I guess my answer cannot be used, SQLCE does not allow multiple statements.
anyway, just use my answer when you use server-based MSSQL or if you use SQLite. or perhaps, encapsulate the two statements to a function that returns scope_identity(integer):
da.InsertCommand = new SQLiteCommand(
#"select insert_to_product(:_product_id, :_product_name, :_abbrev) as product_id", c);
da.InsertCommand.Parameters.Add("_product_id", DbType.Int32,0,"product_id");
da.InsertCommand.Parameters.Add("_product_name", DbType.String, 0, "product_name");
da.InsertCommand.Parameters.Add("_abbrev", DbType.String, 0, "abbrev");
da.InsertCommand.UpdatedRowSource = UpdateRowSource.FirstReturnedRecord;
note: just change SQLiteConnection and SQLiteDataAdapter to MSSQL ones, and change the LAST_INSERT_ROWID() to SCOPE_IDENTITY()
use RowUpdated (shall work on SQLCE and RDBMS that doesn't support multi-statements):
const string devMachine = #"Data Source=C:\_DEVELOPMENT\__.NET\dotNetSnippets\Mine\TestSqlite\test.s3db";
SQLiteConnection c = new SQLiteConnection(devMachine);
SQLiteDataAdapter da = new SQLiteDataAdapter();
DataTable dt = new DataTable();
public Form1()
{
InitializeComponent();
da = new SQLiteDataAdapter("select product_id, product_name, abbrev from product", c);
var b = new SQLiteCommandBuilder(da);
da.InsertCommand = b.GetInsertCommand();
da.UpdateCommand = b.GetUpdateCommand();
da.DeleteCommand = b.GetDeleteCommand();
da.Fill(dt);
da.RowUpdated += da_RowUpdated;
bds.DataSource = dt;
grd.DataSource = bds;
}
void da_RowUpdated(object sender, System.Data.Common.RowUpdatedEventArgs e)
{
if (e.StatementType == StatementType.Insert)
{
int ident = (int)(long) new SQLiteCommand("select last_insert_rowid()", c).ExecuteScalar();
e.Row["product_id"] = ident;
}
}
private void uxUpdate_Click(object sender, EventArgs e)
{
da.Update(dt);
}
I haven't had a chance to use SQLiteConnection class but I do used SQLConnection and SQLCommand class. SqlCommand has a method ExecuteScalar that return the value of the first row and first column of your t-sql statement. You can use it to return the Auto-Identity column. Also, in SQL Server 2005 there is a keyword named OUTPUT you may also check it too.
I've come across this: all you need to do is set your autoincrement seed to -1 and have it "increment" by -1 too. This way all your datarows will have unique ids that DON'T map to anything in the real database. If you're saving your data with a DataAdapter, then after the save your datarow and any other rows with a datarelation pointing to that id will be updated

Categories