I have the following code:
SqlConnection con = new SqlConnection(#"Data Source=NUC\MICROGARDE;Initial Catalog=SQL;Integrated Security=True");
String Query;
for (int i = 0; i < this.dataGridView1.Columns.Count; i++)
{
MessageBox.Show(" " + this.dataGridView1.Columns.Count);
MessageBox.Show(" " + this.dataGridView1.Columns[i].Name + " ");
MessageBox.Show(" " + this.dataGridView1.SelectedRows[0].Cells[i].Value + " ");
Query = "insert into [" + this.comboBox1.Text + "] ([" + this.dataGridView1.Columns[i].Name + "]) Values ('" + this.dataGridView1.SelectedRows[0].Cells[i].Value + "') ;";
SqlCommand cmd = new SqlCommand(Query, con);
con.Open();
DataTable dt = new DataTable();
SqlDataAdapter sda = new SqlDataAdapter(Query, con);
cmd.CommandType = CommandType.Text;
cmd.Connection = con;
sda.SelectCommand = cmd;
sda.Fill(dt);
BindingSource bSource = new BindingSource();
bSource.DataSource = dt;
dataGridView1.DataSource = bSource;
}
con.Close();
It should insert a specific value into EVERY column of a table (shown in a dataGridView), but after it saves the first value (the value from the first column of the row that we want to insert) it refreshes the table and only that first value gets inserted... I want to insert the whole row
the code is behaving correctly as expected.
here is your code:
for each column
build sql string to take first row, current column and insert in db
create sql command using the above sql string
execute the above command
refresh datagrid
next
the above produces the exact behaviour you are experiencing, this is expected and correct in the sense that the code does exactly what it is told to do.
what your code should be based on your description:
for each row
build base sql statement
for each column
add current value and field name to the base statement
next
create sql command
fill the command with the statement built in the previous cycle
execute the sql statement
next
refresh datagrid
if you have to insert only one row then the outer foreach is not needed
while performing string concatenation to build the statements take care of input sanitization and datatypes.
con.open() should be outside the loop
Related
I am able to perform insert using the code which I've made comments here. How to achieve the same using MySqlDataAdapter ? The code I've written isn't working.
string sid, sname;
sid = Request.QueryString["StudentId"].ToString();
sname = Request.QueryString["StudentName"].ToString();
MySqlDataAdapter da = new MySqlDataAdapter("insert into tblStudent (StudentId, StudentName) values ('" + sid.ToString() + "', '" + sname.ToString() + "')", con);
// con.Open();
// MySqlCommand cmd = con.CreateCommand();
// cmd.CommandType = CommandType.Text;
// cmd.CommandText = "insert into tblStudent (StudentId, StudentName) values('" + sid.ToString() + "', '" + sname.ToString() + "')";
// cmd.ExecuteNonQuery();
// con.Close();
Help with suggestions.
To insert a single record you could simply use the MySqlCommand instead of a MySqlDataAdapter. MySqlDataAdapter has many functionality and allows you to execute Insert, Update and Delete actions on your data but you first need to reach the server to fill a DataTable, then add a new record to the datatable and finally call Update. Not worth the effort if you just need to insert a single record
However if you really want to try to use an DataAdapter then you need this code
string sid, sname;
sid = Request.QueryString["StudentId"].ToString();
sname = Request.QueryString["StudentName"].ToString();
string selectText = "SELECT studentID, StudentName FROM tblStudent WHERE 1=0";
using(MySqlDataAdapter da = new MySqlDataAdapter(selectText, con))
{
MySqlCommandBuilder bd = new MySqlCommandBuilder(da);
DataTable dt = new DataTable();
da.Fill(dt);
// This is important, because Update will work only on rows
// present in the DataTable whose RowState is Added, Modified or Deleted
dt.Rows.Add(sid, sname);
da.Update(dt);
}
Im using Visual Studio C# and using Access as my database. I have two columns, ItemCode and ProductName. I want to auto input of the productname on its textbox whenever its itemcode was selected. how can I do this?
some codes:
try
{
con.Open();
OleDbCommand command = new OleDbCommand(#"Select * from TblInventory where ItemCode='" + txtItem.Text + "'");
command.Connection = con;
command.Parameters.AddWithValue("itemcode", txtItem.Text);
OleDbDataReader reader = command.ExecuteReader();
if (reader.Read())//Update Item Code is already exist
{
.........
Feel free to edit my question and please be kind. thank you guys
Try this .
text_box.Text=reader["ProductName"].ToString();
You are filtering the rows by specifying the ItemCode in the Where clause, So The reader will contains the corresponding row/s that matches the specified code. What you need to do is Access the required column value by specifying the name as like the above snippet.
For extracting data from database, I prefer that use OleDbDataAdapter.
You can simply use:
string command = #"Select * from TblInventory where ItemCode='" + txtItem.Text + "'";
OleDbDataAdapter da = new OleDbDataAdapter(command, con);
DataTable dt = new DataTable();
da.Fill(dt);
Now, use dt :
if (dt.Rows.Count == 0)
//Error Message
else
cmbTreatyTitle.Text = dt.Rows[0]["ProductName"].ToString();
I hope this is helpful.
I use SqlDataAdapter and SqlCommandBuilder to perform DML transactions on rows in a SQL Server database.
I am able to add and delete multiple rows in database but update.
This is the code:
SqlDataAdapter da = new SqlDataAdapter(#"select top 1 * from " + tableName,
ConnectionString);
SqlCommandBuilder cmdBuilder = new SqlCommandBuilder(da);
da.Update(dt);
I'm trying to use AcceptChanges, so far it doesn't work.
This is how I usually do within C#. If you want to give this a try.
//you may put this as a direct string or in a static class when layering
//you can pass table as hard-coded value or as a parameter
String SqlQuery = "UPDATE " +
" [tableName] " +
" SET [Column1ToBeUpdated]=#Column1Value," +
" [Column2ToBeUpdated]=#Column2Value" +
" WHERE ([ColumnxWithCondition] = #Condition)";
//add OR, AND operators as per your needs
//choose the correct SqlDbType for your column data types
public bool UpdateMyTable(String SqlQuery, Someclass obj)
{
SqlCommand sCommand = new SqlCommand(this.SqlQuery, (new SqlConnection(ConnectionString)));
sCommand.Parameters.Add("#Column1Value", SqlDbType.VarChar).Value = obj.col1Value;
sCommand.Parameters.Add("#Column2Value", SqlDbType.VarChar).Value = obj.col2Value;
sCommand.Parameters.Add("#Condition", SqlDbType.VarChar).Value = obj.condition;
sCommand.Connection.Open();
var rowsAffected = sCommand.ExecuteNonQuery();
sCommand.Connection.Close();
return rowsAffected > 0;
}
//if you want to see the number, you may return rowsAffected
i have found reason, a column is set DateTime type. So, this Column isn't saving to the database.
Okay basically I have a SQL Server database that has details in it.
Column names: Student_Id, Student_name, Unit_number, Unit_grade
I would like to query this database using two textboxes where you enter the id and unit_number and it will return the results in a message box when a button is clicked.
Where the question marks in the code are is where I am unsure of how to display a message box with the result. Unless this is completely the wrong way of doing things, I am only starting out with SQL in C#
I shouldn't be prone to SQL Injection using parameters as far as I know?
try
{
string str = "SELECT * FROM Students WHERE (Student_Id, Unit_number LIKE '%' + #search + '%')";
SqlCommand command = new SqlCommand(str, connect);
command.Parameters.Add("#search", SqlDbType.NVarChar).Value = textBox1.Text;
command.Parameters.Add("#search", SqlDbType.NVarChar).Value = textBox2.Text;
connect.Open();
command.ExecuteNonQuery();
SqlDataAdapter dataAdapt = new SqlDataAdapter();
dataAdapt.SelectCommand = command;
DataSet dataSet = new DataSet();
dataAdapt.Fill(dataSet, "Student_Id, Unit_number");
//?
//?
connect.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
Your SQL is wrong in that your WHERE clause is syntactically incorrect. You probably want something like:
string str = "SELECT * FROM Students WHERE Student_ID = #id AND " +
"Unit_number LIKE #search";
This assumes that Student_ID is a text type. The syntax would be slightly different if it was a number.
You are trying to add the same parameter to the query twice, which you won't want. Instead you'd want two parameters to match with the new SQL definition:
command.Parameters.Add("id", SqlDbType.NVarChar).Value =
textBox1.Text;
command.Parameters.Add("search", SqlDbType.NVarChar).Value =
"%" + textBox2.Text + "%";
Running ExecuteNonQuery on the SqlCommand object doesn't do much for you as it is a query and you're not asking for the result back.
If you're only expecting one table back from your query, you'd probably be better off with a DataTable rather than a DataSet (the DataSet can contain many tables which is overkill for what you need).
try
{
string str = "SELECT * FROM Students WHERE Student_Id = #id AND " +
"Unit_number LIKE #search";
connect.Open();
SqlCommand command = new SqlCommand(str, connect);
command.Parameters.Add("id", SqlDbType.NVarChar).Value =
textBox1.Text;
command.Parameters.Add("search", SqlDbType.NVarChar).Value =
"%" + textBox2.Text + "%";
SqlDataAdapter dataAdapt = new SqlDataAdapter();
dataAdapt.SelectCommand = command;
DataTable dataTable = new DataTable();
dataAdapt.Fill(dataTable);
// At this point you should have a DataTable with some results in it.
// This is not going to be the best way of displaying data,
// but it should show you _something_
// It just iterates through the rows showing the columns
// which you've shown as being in your data.
foreach (DataRow dr in dataTable.Rows)
{
MessageBox.Show(String.Format("{0} - {1} - {2} - {3}",
dr["Student_Id"], dr["Student_name"],
dr["Unit_number"], dr["Unit_grade"]));
}
connect.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
EDITED to change the parameter handling as it didn't quite do what was needed. The % symbols are not part of the parameter rather than the SQL string.
I have a dataset that is dynamically created from a csv file. What I want to do is insert the rows into my MS Access table but I cannot figure out where to start with this.
The headers of the data in the dataset can vary as far as the order but the name of the header will always match the access database. Do I have to statically call out the header name in the insert command or can I build the headers from the dataset?
I know how to create the connection and open it to the database but am not sure how to create in insert command to dynamically pull the table headers.
I am pretty green when it comes to C# programming so if you can spell it out for me I would really appreciate it!
Here is an example of the access table headers:
ID, Item, Cost, Retail
Then the CSV which will fill the dataset table. It might have Retail or it might not:
Item, Cost
Here is the code I have so far but it doesn't write to the access table. If I vew the dtAccess it shows correctly.
OleDbConnection myConnection = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=\"C:\\Database.accdb\";Persist Security Info=False;");
myConnection.Open();
string queryString = "SELECT * from " + lblTable.Text;
OleDbDataAdapter adapter = new OleDbDataAdapter(queryString, myConnection);
DataTable dtAccess = new DataTable();
DataTable dtCSV = new DataTable();
dtCSV = ds.Tables[0];
using (new OleDbCommandBuilder(adapter))
{
adapter.Fill(dtAccess);
dtAccess.Merge(dtCSV);
adapter.Update(dtAccess);
}
myConnection.Close();
Figured it out. Here is the code I used:
OleDbConnection myConnection = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=\"Database.accdb\";Persist Security Info=False;");
//command to insert each ASIN
OleDbCommand cmd = new OleDbCommand();
//command to update each column (ASIN, Retail... from CSV)
OleDbCommand cmd1 = new OleDbCommand();
//load csv data to dtCSV datatabe
DataTable dtCSV = new DataTable();
dtCSV = ds.Tables[0];
// Now we will collect data from data table and insert it into database one by one
// Initially there will be no data in database so we will insert data in first two columns
// and after that we will update data in same row for remaining columns
// The logic is simple. 'i' represents rows while 'j' represents columns
cmd.Connection = myConnection;
cmd.CommandType = CommandType.Text;
cmd1.Connection = myConnection;
cmd1.CommandType = CommandType.Text;
myConnection.Open();
for (int i = 0; i <= dtCSV.Rows.Count - 1; i++)
{
cmd.CommandText = "INSERT INTO " + lblTable.Text + "(ID, " + dtCSV.Columns[0].ColumnName.Trim() + ") VALUES (" + (i + 1) + ",'" + dtCSV.Rows[i].ItemArray.GetValue(0) + "')";
cmd.ExecuteNonQuery();
for (int j = 1; j <= dtCSV.Columns.Count - 1; j++)
{
cmd1.CommandText = "UPDATE " + lblTable.Text + " SET [" + dtCSV.Columns[j].ColumnName.Trim() + "] = '" + dtCSV.Rows[i].ItemArray.GetValue(j) + "' WHERE ID = " + (i + 1);
cmd1.ExecuteNonQuery();
}
}
myConnection.Close();
Access has hidden tables that provide database access to the tables and columns in the database. The names of them are dependent upon access version, but they're typically something like systables? It's been a while, but if you "show hidden tables" you should be able to find them.
If the the two datatable have the same structure you can merge the "CSV" Datatable with the Database table datatable, so for example you can retrieve the database table into a datatable using a data adapter :
string queryString = "SELECT * FROM sometable";
SqlDataAdapter adapter = new SqlDataAdapter(queryString, connection);
DataTable dtAccess = new DataTable();
adapter.Fill(dtAccess);
then you can merge the content of this DataTable with the content of the CSV DataTable :
dtAccess.Merge(dtCSV);
After that you can write the content of the datatable into the access database table with a command builder :
using (new SqlCommandBuilder(adapter)) {
adapter.Update(dtAccess);
}
If the datatables have the same structure should work without any problem ...