Number of query values and destinations fields are not the same - c#

This is the function for automatically stored value to TotalAmt_tx.Text..
void TotalAmount()
{
.
.
.
.
TotalAmt_tx.Text = Total.ToString("00.00");
.
.
.
catch { }
}
Save button code :here the image of my forms
private void Save_bt_Click(object sender, EventArgs e)
{
//Purchase Table
{
string insertPur = "Insert into Purchase (Invoice,VendorName,PurchaseDate,TotalAmt) values ("+Invoice_tx.Text+"," +
"'"+VendorName_cb.Text+"','"+PurchaseDate_dt.Value.Date.ToString()+"',"+TotalAmt_tx.Text+" )";
OleDbDataAdapter da = new OleDbDataAdapter(insertPur, conn);
DataSet ds = new DataSet();
da.Fill(ds);
}
//Purchase Item Table
for (int i = 0; i < metroGrid1.Rows.Count; i++)
{
string insertPur = "Insert into PurchaseItem (Invoice, PId, Product, Qty, Rate, Amount) values (" + Invoice_tx.Text + "," +
""+metroGrid1.Rows[i].Cells["PId"].Value.ToString()+ ",'" + metroGrid1.Rows[i].Cells["Product"].Value.ToString() + "'," +
"" + metroGrid1.Rows[i].Cells["Qty"].Value.ToString() + "," + metroGrid1.Rows[i].Cells["Rate"].Value.ToString() + "," +
"" + metroGrid1.Rows[i].Cells["Amount"].Value.ToString() + ")";
OleDbDataAdapter da = new OleDbDataAdapter(insertPur, conn);
DataSet ds = new DataSet();
da.Fill(ds);
}
MessageBox.Show("Data Saved!!");
The problems show up because this
TotalAmt_tx.Text = Total.ToString("00.00")
What should I do, to solve it??
I've try follow some tutorial about formatting string but nothings works.
Please help

I suggest you try to use OleDbParameter Class, because if one of the values you combine to your query string has the , character it will mess-up you query (for example a number in the following format 1,000).
Hope it helps!

You should always stick to parameterized queries to avoid SQL Injection. It also helps in avoiding mistakes like missing a "'"
using (OleDbConnection connection =new OleDbConnection(connectionString))
{
var query = "Insert into Purchase (Invoice,VendorName,PurchaseDate,TotalAmt) values (#invoice,#vendor,#purchasedate,#amt)";
OleDbDataAdapter adapter = new OleDbDataAdapter(queryString, connection);
adapter.SelectCommand.Parameters.Add("#invoic", OleDbType.Integer).Value = Convert.ToInt32(Invoice_tx.Text);
adapter.SelectCommand.Parameters.Add("#vendor", OleDbType.VarChar,100).Value = VendorName_cb.Text;
adapter.SelectCommand.Parameters.Add("#invoic", OleDbType.Date).Value = PurchaseDate_dt.Value.Date; // I do not know what PurchaseDate_dt.Value.Date type is, so I leave it to you to convert to approapriate type
adapter.SelectCommand.Parameters.Add("#CategoryName", OleDbType.Integer).Value = Convert.ToInt32(TotalAmt_tx.Text);
connection.Open();
DataSet ds = new DataSet();
adapter.Fill(ds);
}

Related

Invalid attempt to call read when reader is closed when inserting data

i have a button that when clicked inserts data from textbox and combobox fields into database tables, but every time i insert it gives me "Invalid attempt to call read when reader is closed". How can i get rid of this error. And tips on optimising the code are welcome, because i know im a total noob. thanks
private void btnSave_Click(object sender, RoutedEventArgs e)
{
try
{
SqlConnection sqlCon = new SqlConnection(#"Data Source=(localdb)\mssqllocaldb; Initial Catalog=Storagedb;");
sqlCon.Open();
string Query1 = "insert into location(Storage, Shelf, columns, rows) values(" + txtWarehouse.Text + ", " + txtShelf.Text + ", " + txtColumn.Text + ", " + txtRow.Text + ")";
SqlCommand sqlCmd = new SqlCommand(Query1, sqlCon);
SqlDataAdapter dataAdp = new SqlDataAdapter(sqlCmd);
dataAdp.SelectCommand.ExecuteNonQuery();
sqlCon.Close();
}
catch (Exception er)
{
MessageBox.Show(er.Message);
}
try
{
SqlConnection sqlCon = new SqlConnection(#"Data Source=(localdb)\mssqllocaldb; Initial Catalog=Storagedb;");
sqlCon.Open();
string Query3 = "SELECT LOCATION_ID FROM LOCATION WHERE storage='" + txtWarehouse.Text + "' AND shelf='" + txtShelf.Text + "' AND columns='"
+ txtColumn.Text + "' AND rows='" + txtRow.Text + "'";
SqlCommand sqlCmd1 = new SqlCommand(Query3, sqlCon);
SqlDataReader dr = sqlCmd1.ExecuteReader(); ;
while (dr.Read())
{
string LocationId = dr[0].ToString();
dr.Close();
string Query2 = "insert into product(SKU, nimetus, minimum, maximum, quantity,location_ID,category_ID,OrderMail_ID) values ('" + txtSku.Text + "','" + txtNimetus.Text + "', '"
+ txtMin.Text + "', '" + txtMax.Text + "', '" + txtQuan.Text + "', '" + LocationId + "', '" + (cbCat.SelectedIndex+1) + "', '" + (cbMail.SelectedIndex+1) + "')";
SqlCommand sqlCmd = new SqlCommand(Query2, sqlCon);
SqlDataAdapter dataAdp = new SqlDataAdapter(sqlCmd);
dataAdp.SelectCommand.ExecuteNonQuery();
}
sqlCon.Close();
}
catch (Exception ed)
{
MessageBox.Show(ed.Message);
}
}
Let's try to make some adjustments to your code.
First thing to consider is to use a parameterized query and not a
string concatenation when you build an sql command. This is mandatory
to avoid parsing errors and Sql Injections
Second, you should encapsulate the disposable objects in a using statement
to be sure they receive the proper disposal when you have finished to
use them.
Third, you can get the LOCATION_ID from your table without running a
separate query simply adding SELECT SCOPE_IDENTITY() as second batch to your first command. (This works only if you have declared the LOCATION_ID field in the first table as an IDENTITY column)
Fourth, you put everything in a transaction to avoid problems in case
some of the code fails unexpectedly
So:
SqlTransaction tr = null;
try
{
string cmdText = #"insert into location(Storage, Shelf, columns, rows)
values(#storage,#shelf,#columns,#rows);
select scope_identity()";
using(SqlConnection sqlCon = new SqlConnection(.....))
using(SqlCommand cmd = new SqlCommand(cmdText, sqlCon))
{
sqlCon.Open();
using( tr = sqlCon.BeginTransaction())
{
// Prepare all the parameters required by the command
cmd.Parameters.Add("#storage", SqlDbType.Int).Value = Convert.ToInt32(txtWarehouse.Text);
cmd.Parameters.Add("#shelf", SqlDbType.Int).Value = Convert.ToInt32(txtShelf.Text);
cmd.Parameters.Add("#columns", SqlDbType.Int).Value = Convert.ToInt32(txtColumn.Text );
cmd.Parameters.Add("#rows", SqlDbType.Int).Value = Convert.ToInt32(txtRow.Text);
// Execute the command and get back the result of SCOPE_IDENTITY
int newLocation = Convert.ToInt32(cmd.ExecuteScalar());
// Set the second command text
cmdText = #"insert into product(SKU, nimetus, minimum, maximum, quantity,location_ID,category_ID,OrderMail_ID)
values (#sku, #nimetus,#min,#max,#qty,#locid,#catid,#ordid)";
// Build a new command with the second text
using(SqlCommand cmd1 = new SqlCommand(cmdText, sqlCon))
{
// Inform the new command we are inside a transaction
cmd1.Transaction = tr;
// Add all the required parameters for the second command
cmd1.Parameters.Add("#sku", SqlDbType.NVarChar).Value = txtSku.Text;
cmd1.Parameters.Add("#nimetus",SqlDbType.NVarChar).Value = txtNimetus.Text;
cmd1.Parameters.Add("#locid", SqlDbType.Int).Value = newLocation;
.... and so on for the other parameters required
cmd1.ExecuteNonQuery();
// If we reach this point the everything is allright and
// we can commit the two inserts together
tr.Commit();
}
}
}
}
catch (Exception er)
{
// In case of exceptions do not insert anything...
if(tr != null)
tr.Rollback();
MessageBox.Show(er.Message);
}
Notice that in the first command I use parameters of type SqlDbType.Int because you haven't used single quotes around your text. This should be verified against the real data type of your table columns and adjusted to match the type. This is true as well for the second command where you put everything as text albeit some of those fields seems to be integer (_location_id_ is probably an integer). Please verify against your table.

Unable to fetch nvarchar type data with where clause in SQL Server 2008

string constr = Properties.Settings.Default.Subject_1ConnectionString;
SqlConnection conn = new SqlConnection(constr);
SqlCommand com = new SqlCommand("SELECT * from Subject_Title WHERE Date BETWEEN #hello and #hello1 ", conn);
// com.Parameters.Add("#hello", SqlDbType.NVarChar).Value = textBox1.Text;
// com.Parameters.Add("#hello1", SqlDbType.NVarChar).Value = textBox2.Text;
com.Parameters.Add("#hello", SqlDbType.NVarChar);
com.Parameters["#hello"].Value = textBox1.Text;
com.Parameters.Add("#hello1", SqlDbType.NVarChar);
com.Parameters["#hello1"].Value = textBox2.Text;
// com.Parameters.AddWithValue("#hello", textBox1.Text);
// com.Parameters.AddWithValue("#hello1", textBox2.Text);
SqlDataAdapter da = new SqlDataAdapter(com);
DataSet ds = new DataSet();
da.Fill(ds, "Subject_title");
for (int i = 0; i < 8; i++)
{
this.labeltext = this.labeltext + " " + ds.Tables["Subject_Title"].Rows[i]["Date"].ToString();
this.labeltext = this.labeltext + " " + ds.Tables["Subject_Title"].Rows[i]["Subject"].ToString();
this.labeltext = this.labeltext + " ";
}
this.label1.Text = this.labeltext;
Here I'm not getting any data from the database
Date is my column name with a nvarchar type, and Subject is another column of type text.
Pls anyone solve my problem
I guess you should use:
Con.Open();
Con.Close();
But if I were you I would have written this code like this:
string constr = Properties.Settings.Default.Subject_1ConnectionString;
SqlConnection conn = new SqlConnection(constr);
SqlCommand com = new SqlCommand("SELECT * from Subject_Title WHERE Date BETWEEN \"01-03-14\" and \"01-04-14\" ", conn);
conn.Open();
SqlDataReader reader =com.ExecuteReader();
while(reader.read()){
this.labeltext += " " + reader.GetString(0); //Use column ordinal for Date
this.labeltext += " " + reader.GetString(1)+" "; //Use column ordinal for Subject
}
conn.Close()
this.label1.Text = this.labeltext;
I tried to come up with a better code base for you.
You need to:
use more meaningful names! Parameters like hello and hello1 aren't very useful to someone reading your code.... also: don't name your columns with reserved keywords like Date - again: use something more meaningful to your context
if you want to use date-related methods, you must use DATE or DATETIME2(N) datatypes. If you have stored your data as nvarchar - you must convert it first to a DATE
please always put your SqlConnection and SqlCommand into using(...) { .. } blocks to ensure proper and speedy disposal
if you only need a single DataTable - just instantiate a DataTable and fill it - don't use the unnecessary additional overhead of a DataSet - that's just wasted resources...
Code:
string constr = Properties.Settings.Default.Subject_1ConnectionString;
// if you only need one single data table - use a DataTable - not a DataSet !
DataTable dt = new DataTable();
// *ALWAYS* put your SqlConnection and SqlCommand into using() blocks!
// also - if you want to use BETWEEN, you *MUST* use DATE!
// also: don't call your column "date" - that's a SQL Server reserved keyword! Use a more meaningful name
// like "DateCreated" or "DateLastUpdated" or something
// and please also use more meaningful parameter names - "hello" and "hello1" is very confusing and not clear!!
using (SqlConnection conn = new SqlConnection(constr))
using (SqlCommand com = new SqlCommand("SELECT * FROM dbo.Subject_Title WHERE CAST(DateCreated AS DATE) BETWEEN #start and #end ", conn))
{
// add parameters as DATE type!
com.Parameters.Add("#start", SqlDbType.Date);
com.Parameters["#start"].Value = DateTime.Parse(textBox1.Text).Date;
com.Parameters.Add("#end", SqlDbType.Date);
com.Parameters["#end"].Value = DateTime.Parse(textBox2.Text).Date;
SqlDataAdapter da = new SqlDataAdapter(com);
da.Fill(dt);
}
for (int i = 0; i < 8; i++)
{
this.labeltext = this.labeltext + " " + dt.Rows[i]["Date"].ToString();
this.labeltext = this.labeltext + " " + ds.Rows[i]["Subject"].ToString();
this.labeltext = this.labeltext + " ";
}
this.label1.Text = this.labeltext;

Want to create a comment system in asp.net

i am coding for a commenting system in asp.net C# but i am stopped at delete command because of i am not using any type of serial numbers to comments posted, then how can i able to delete a specific comment, i am just using a username, date, time, and text in comment. Can anyone help me please that how to use a delete command in this condition??
here is my code for posting:
protected void pospost_Click(object sender, EventArgs e)
{
string login;
if (HttpContext.Current.Session["UserName"] != null)
{
login = HttpContext.Current.Session["UserName"].ToString();
con.Open();
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
cmd.CommandText = "select * from mobiles_pos";
da = new SqlDataAdapter(cmd);
ds = new DataSet();
da.Fill(ds);
DataRow rw = ds.Tables[0].NewRow();
rw[0] = Model.Text.ToString();
rw[1] = titlepos.Text.ToString();
rw[2] = txtpos.Text.ToString();
rw[3] = DateTime.Today.Date.ToString();
rw[4] = DateTime.Now.TimeOfDay.ToString();
rw[5] = login.ToString();
ds.Tables[0].Rows.Add(rw);
SqlCommand cmd1 = new SqlCommand();
cmd1.Connection = con;
cmd1.CommandText = "insert into mobiles_pos values('" + Model.Text + "','" + titlepos.Text + "','" + txtpos.Text + "','" + DateTime.Today.Date + "','" + DateTime.Now.TimeOfDay + "','" + login + "')";
da.InsertCommand = cmd1;
da.Update(ds);
con.Close();
titlepos.Text = "";
txtpos.Text = "";
//DataList2.DataSource = ds;
//DataList2.DataBind();
BindDataList2();
}
}
Best - Add a Primary key to the "mobiles_pos" table since your using sql just use an identity field it will auto increment for you.
or
Quick - Use a combination of the User name and date comment was intered you must use the full date time or it will delete everything that user entered that day.
"Delete from mobiles_pos where username = #UserName and createdDate = #createdDate"

Query works in Access but not in my program. Why?

I have this query set up in my application to work for searching through my database. I put this query into Access and it works fine. However, when I put it into my program the table has 0 entries. Can you please help?
private async Task FilterDB()
{
List<string> Filter = new List<string>();
if (CardNameCheck.IsChecked == true)
Filter.Add("*" + CardNameBox.Text + "*");
else
Filter.Add("*");
if (CardExpanCheck.IsChecked == true)
Filter.Add("*" + CardExpanBox.Text + "*");
else
Filter.Add("*");
OleDbConnection DBCon = new OleDbConnection(#"Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" + Properties.Settings.Default.DatabaseLocation);
await DBCon.OpenAsync();
OleDbDataAdapter CardDA = new OleDbDataAdapter("SELECT * FROM Cards WHERE Name like '" + Filter[0] + "' and Expansion like '" + Filter[1] + "'", DBCon);
DataSet CardDS = new DataSet();
CardDA.Fill(CardDS);
DBCon.Close();
I tried your code and modified it a bit. Works for me for the Access2003 .mdb format.
OleDbConnection DBCon = new OleDbConnection(#"Provider=Microsoft.Jet.OLEDB.4.0; Data Source=(k:\mydatabases\mydatabase.mdb");
DBCon.Open();
// Create a select Command - you need System.Data.OleDb and System.Data for this
OleDbCommand selectCommand = new OleDbCommand();
// define the CommandText with two parameters #Filter1 and #Filter2
selectCommand.CommandText = "SELECT * FROM Cards WHERE Name like #Filter1 and Expansion like #Filter2";
selectCommand.Connection = DBCon;
// Create two string / VarChar Parameters -
// the following is a standard I commonly use
// for string/varchar; you might also use OleDbType.NVarChar
OleDbParameter param01 = new OleDbParameter();
param01.ParameterName = "Filter1";
param01.DbType = DbType.AnsiString;
param01.OleDbType = OleDbType.VarChar;
param01.SourceVersion = DataRowVersion.Current;
param01.SourceColumn = "Name";
// provide them with values - I used text boxes for input
// use '%' for like statement - if no parameter provided use single '%' only
if (txtFilter1.Text.ToString().Equals(""))
{
param01.Value = '%';
}
else
{
param01.Value = '%' + txtFilter1.Text.ToString() + '%';
}
// add the parameter to the SelectCommand
selectCommand.Parameters.Add(param01);
// same goes for the second parameter
OleDbParameter param02 = new OleDbParameter();
param02.ParameterName = "Filter2";
param02.DbType = DbType.AnsiString;
param02.OleDbType = OleDbType.VarChar;
param02.SourceVersion = DataRowVersion.Current;
param02.SourceColumn = "Expansion";
if (txtFilter2.Text.ToString().Equals(""))
{
param02.Value = '%';
}
else
{
param02.Value = '%' + txtFilter2.Text.ToString() + '%';
}
selectCommand.Parameters.Add(param02);
OleDbDataAdapter CardDA = new OleDbDataAdapter();
// tell the DataAdapter to use a SelectCommand
CardDA.SelectCommand = selectCommand;
CardDA.GetFillParameters(); // actually not sure if you need this but does no harm either
DataSet CardDS = new DataSet();
CardDA.Fill(CardDS, "TargetTable");
DBCon.Close();
foreach(DataRow row in CardDS.Tables["TargetTable"].Rows)
{
// do something ;
}
Good luck!

Datagrid filter in c# using sql server

How to filter data in datagrid for example if you select the combo box in student number then input 1001 in the text field. All records in 1001 will appear in datagrid. I am using sql server
private void button2_Click(object sender, EventArgs e)
{
if (cbofilter.SelectedIndex == 0)
{
string sql;
SqlConnection conn = new SqlConnection();
conn.ConnectionString = "Server= " + Environment.MachineName.ToString() + #"\; Initial Catalog=TEST;Integrated Security = true";
SqlDataAdapter da = new SqlDataAdapter();
DataSet ds1 = new DataSet();
ds1 = DBConn.getStudentDetails("sp_RetrieveSTUDNO");
sql = "Select * from Test where STUDNO like '" + txtvalue.Text + "'";
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.CommandType = CommandType.Text;
da.SelectCommand = cmd;
da.Fill(ds1);
dbgStudentDetails.DataSource = ds1;
dbgStudentDetails.DataMember = ds1.Tables[0].TableName;
dbgStudentDetails.Refresh();
}
else if (cbofilter.SelectedIndex == 1)
{
//string sql;
//SqlConnection conn = new SqlConnection();
//conn.ConnectionString = "Server= " + Environment.MachineName.ToString() + #"\; Initial Catalog=TEST;Integrated Security = true";
//SqlDataAdapter da = new SqlDataAdapter();
//DataSet ds1 = new DataSet();
//ds1 = DBConn.getStudentDetails("sp_RetrieveSTUDNO");
//sql = "Select * from Test where Name like '" + txtvalue.Text + "'";
//SqlCommand cmd = new SqlCommand(sql,conn);
//cmd.CommandType = CommandType.Text;
//da.SelectCommand = cmd;
//da.Fill(ds1);
// dbgStudentDetails.DataSource = ds1;
//dbgStudentDetails.DataMember = ds1.Tables[0].TableName;
//ds.Tables[0].DefaultView.RowFilter = "Studno = + txtvalue.text + ";
dbgStudentDetails.DataSource = ds.Tables[0];
dbgStudentDetails.Refresh();
}
}
It's difficult to answer pricisely to a vague question. I guess that you'll have to adapt your SQL query with a WHERE statement containing the user input.
If 'student number' is selected in the combo box, query like this (numbers starting with):
SELECT id, name, number FROM students WHERE number LIKE #search + '%'
If 'student name' is selected, use another query (names containing):
SELECT id, name, number FROM students WHERE name LIKE '%' + #search + '%'
Please explain in what sense C# is concerned.
You don't say what is wrong with the code you commented out. You also don't say what type the Studno column is.
Have you tried something like:
ds1.Tables[0].DefaultView.RowFilter = "Studno = '" + txtvalue.text + "'";

Categories