I'm making a fine calculator in a library system. In it,I need to calculate the fine of a given day. For this,I use a data table to load the fine amounts and then,I need to calculate the total fine amount by adding each fine amount.But I'm having a problem in parsing the fine values which are in string format to integer.Here is a screenshot of the error.
Here is a screenshot of the error.
And here is the code which I used to convert the string values to integer and calculate the total fine.
int sum1 = 0;
int myNum;
String Display;
private void btnNext_Click(object sender, EventArgs e)
{
try
{
if (rbtnToday.Checked == true)
{
DateTime today = DateTime.Today;
Con.Open();
String select_today_query = "SELECT Fine FROM BookReceiveMem WHERE RecDate='" + today + "'";
Sqlda = new SqlDataAdapter(select_today_query, Con);
DataTable Dt = new DataTable();
Sqlda.Fill(Dt);
Con.Close();
foreach (DataRow row in Dt.Rows)
{
myNum = int.Parse(Dt.Columns[0].ToString());
sum1 = sum1 + myNum;
}
Display = sum1.ToString();
MessageBox.Show("Today Fine Amount is= " + Display, "Today Fine Calculation", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
Is there any method to solve this problem?
Databases are really good at calculating things like a sum. If Fine is an integer in your database you can get it to sum all the rows and just return that:
SELECT SUM(Fine) As TotalFine
FROM BookReceiveMem
WHERE RecDate = #recDate
Which you could call from code without ever needing a DataTable as follows:
using(var cmd = Con.CreatCommand())
{
cmd.CommandText = "SELECT SUM(Fine) As TotalFine FROM BookReceiveMem WHERE RecDate = #recDate";
cmd.CommandType = CommandType.Text;
cmd.Parameters.Add("#recDate",DateTime.Today);
var result = (int)cmd.ExecuteScalar();
MessageBox.Show("Today Fine Amount is= " + result, "Today Fine Calculation", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
Note that the above uses a Parameterized Query which is much safer than using string concatenation
However, a more direct answer to your question:
myNum = int.Parse(Dt.Columns[0].ToString());
Here you're getting the Column and trying to turn that to an integer. What you actually meant to do was get the row value (and you dont need to Parse it - it's already an integer!)
myNum = (int)row["Fine"];
Related
i want to store date and time in SQL Server 2012 using asp.net but generate some error "Conversion failed when converting date and/or time from character string."
protected void btn Submit_Click(object sender, EventArgs e)
{
lbldate.Text = Convert.ToDateTime(this.txtdate.Text).ToString("dd/MM/yyyy");
lbltime.Text = Convert.ToDateTime(this.txttime.Text).ToLongTimeString();
TimeSpan time = new TimeSpan();
time.ToString();
SqlConnection con = new SqlConnection(#"Data Source=DESKTOP-O6SE533;Initial Catalog=Datertime;Integrated Security=True;Connect Timeout=15;Encrypt=False;TrustServerCertificate=False");
SqlCommand cmd = new SqlCommand("insert date,time into DateTimedemo values('" +txtdate.Text + "','"+txttime.Text+"')", con);
con.Open();
int r = cmd.ExecuteNonQuery();
if (r > 0)
{
Response.Write("success");
}
else
{
Response.Write("failed");
}
}
Use parameterized SQL instead of building the SQL dynamically. This avoids SQL injection attacks and string formatting differences, as well as making the code clearer.
Additionally, I believe both "date" and "time" are keywords in T-SQL, so you should put them in square brackets when using them as field names.
You should attempt to perform as few string conversions as possible. Without knowing exactly what your web page looks like it's hard to know exactly how you want to parse the text, but assuming that Convert.ToDateTime is working for you (sounds worryingly culture-dependent to me) you'd have code like this:
protected void btn Submit_Click(object sender, EventArgs e)
{
// TODO: Ideally use a date/time picker etc.
DateTime date = Convert.ToDateTime(txtdate.Text);
DateTime time = Convert.ToDateTime(txttime.Text);
// You'd probably want to get the connection string dynamically, or at least have
// it in a shared constant somewhere.
using (var con = new SqlConnection(connectionString))
{
string sql = "insert [date], [time] into DateTimeDemo values (#date, #time)";
using (var cmd = new SqlCommand(sql))
{
cmd.Parameters.Add("#date", SqlDbType.Date).Value = date;
cmd.Parameters.Add("#time", SqlDbType.Time).Value = time.TimeOfDay;
int rows = cmd.ExecuteNonQuery();
string message = rows > 0 ? "success" : "failed";
Response.Write(message);
}
}
}
I've guessed at what SQL types you're using. If these are meant to represent a combined date and time, you should at least consider using a single field of type DateTime2 instead of separate fields.
I am using sap.net web form. In this web form i have a text and a button. user enter name or id and hit search button. Searching with id is working fine but with name it is not working.
What i am missing here help me out please.
String Status = "Active";
String BDstring = ConfigurationManager.ConnectionStrings["CS"].ConnectionString;
using (SqlConnection conn = new SqlConnection(BDstring))
{
try
{
String query = "SELECT * from Driver where(Name LIKE '%' + #search + '%' OR DriverID = #search) AND Status = 'Active'";
SqlCommand cmd = new SqlCommand(query, conn);
cmd.Parameters.AddWithValue("#search", SearchTextBox.Text);
conn.Open();
SqlDataReader SDR = cmd.ExecuteReader();
DataTable DT = new DataTable();
if (SDR.HasRows)
{
DT.Load(SDR);
GridView.DataSource = DT;
GridView.DataBind();
}
}
catch (SqlException exe)
{
throw exe;
}
}
}
The code is generating an exception. The fact that you're unaware of this indicates that you have "error handling" somewhere in your system that is, in fact "error hiding". Remove empty catch blocks, or pointless catch blocks such as the one in your question that just destroys some information in the exception and re-throws it. Those aren't helping you.
The actual problem is that the DriverID column is int and your parameter is varchar. So long as the varchar contains a string that can be converted to a number (which is the direction that the conversion happens in due to precedence), the query is well-formed.
As soon as the parameter contains a string that cannot be implicitly converted to a number, SQL Server generates an error that .NET turns into an exception.
For your LIKE variant, you're forcing a conversion in the opposite direction (numeric -> varchar) since LIKE only operates on strings. That conversion will always succeed, but it means that you're performing textual comparisons rather than numeric, and also means there's no possible index usage here.
I'd suggest that you change your C# code to attempt a int.TryParse on the input text and then uses two separate parameters to pass strings and (optionally) their numeric equivalent to SQL Server. Then use the appropriate parameters in your query for each comparison.
Something like:
String Status = "Active";
String BDstring = ConfigurationManager.ConnectionStrings["CS"].ConnectionString;
using (SqlConnection conn = new SqlConnection(BDstring))
{
String query = "SELECT * from Driver where(Name LIKE '%' + #search + '%' OR " +
"DriverID = #driverId) AND Status = 'Active'";
SqlCommand cmd = new SqlCommand(query, conn);
cmd.Parameters.Add("#search", SqlDbType.VarChar,50).Value = SearchTextBox.Text;
cmd.Parameters.Add("#driverId", SqlDbType.Int);
int driverId;
if(int.TryParse(SearchTextBox.Text, out driverId))
{
cmd.Parameters["#driverId"].Value = driverId;
}
conn.Open();
SqlDataReader SDR = cmd.ExecuteReader();
DataTable DT = new DataTable();
if (SDR.HasRows)
{
DT.Load(SDR);
GridView.DataSource = DT;
GridView.DataBind();
}
}
"SELECT * from Driver where (Name LIKE '%" + #search + "%'
OR DriverID = '" + #search + "' ) AND Status = 'Active'";
how about this?
protected void btnBeds_click(object sender, EventArgs e)
{
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["DatabaseConnectionString"].ConnectionString);
con.Open();
String checkBeds = "SELECT Count (*) FROM Bed WHERE bedID NOT IN (SELECT DISTINCT(bedID) FROM Booking where startDate>='"+TxtArrivalDate.Text+"' and endDate<= '"+txtDepartureDate.Text+"'";
SqlCommand showcheckBeds = new SqlCommand(checkBeds, con);
ResultLabel.Text = showcheckBeds.ExecuteScalar().ToString();
con.Close();
}
I'm trying to display the amount of free beds there are in the database and im getting this error.
Always use parameters in your queries
Always wrap connections and other types that implement IDisposable in using statements to ensure the resource is released
Use the correct types in your database and match that type with the passed in parameter. Example: do not pass in a string for a date, do not store dates as strings.
Your actual problem was a missing ) at the end of your sql statement as pointed out by #Damien_The_Unbeliever
Updated code with changes:
const string checkBeds = "SELECT Count (*) FROM Bed WHERE bedID NOT IN (SELECT DISTINCT(bedID) FROM Booking where startDate >= #startDate and endDate<= #endDate)";
using(SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["DatabaseConnectionString"].ConnectionString))
using(SqlCommand showcheckBeds = new SqlCommand(checkBeds, con))
{
showcheckBeds.Parameters.Add(new SqlParameter("#startDate", SqlDbType.DateTime){Value = DateTime.Parse(TxtArrivalDate.Text) });
showcheckBeds.Parameters.Add(new SqlParameter("#endDate", SqlDbType.DateTime){Value = DateTime.Parse(txtDepartureDate.Text) });
con.Open();
ResultLabel.Text = showcheckBeds.ExecuteScalar().ToString();
}
Note: In the code above I used a direct DateTime.Parse to get an actual DateTime instance to pass as a parameter. It would probably be advisable to change that either to ParseExact or to provide a CultureInfo instance to the method.
Try This
String checkBeds = "SELECT Count (*) FROM Bed WHERE bedID NOT IN (SELECT DISTINCT(bedID) FROM Booking where startDate>='"+Convert.ToDateTime( TxtArrivalDate.Text).ToStrin("dd MMM yyyy")+"' and endDate<= '"+Convert.ToDateTime(txtDepartureDate.Text).ToString("dd MMM yyyy")+"'";
I created a sale table which Insert function does not work properly. It shows the error message
Must declare the scalar variable "#iProductID"
at the statement
using (var sdRead = cmdOrder.ExecuteReader())
I am really stuck here. I also want to know how I can achieve for inserting SaleID with auto-increment without with any input field at the form. Every time I insert a new record, SaleID should be auto-generated and saved in the database.
My code below work like this. I checked available stocks from my Product table. If quantity order is greater than quantity from Product table, show error message.
Otherwise, proceed to inserting order information into Sale table. Any help is appreciated.
private void btnOrder_Click(object sender, EventArgs e)
{
int iQuantityDB;
int iCustomerID = Convert.ToInt32(txtCustomerID.Text);
int iProductID = Convert.ToInt32(txtProductID.Text);
decimal dPrice = Convert.ToDecimal(txtPrice.Text);
int iQuantity = Convert.ToInt32(txtQuantity.Text);
decimal dSubtotal = Convert.ToDecimal(txtSubTotal.Text);
decimal dGST = Convert.ToDecimal(txtGST.Text);
decimal dTotal = Convert.ToDecimal(txtTotal.Text);
string strConnectionString = #"Data Source = KK\SQLEXPRESS; Integrated Security = SSPI; Initial Catalog = JeanDB; MultipleActiveResultSets=True;";
using (var sqlconn = new SqlConnection(strConnectionString))
{
sqlconn.Open();
string querySelectQuantity = #"Select Quantity from dbo.JeanProduct WHERE ProductID = #iProductID";
using (var cmdOrder = new SqlCommand(querySelectQuantity, sqlconn))
{
using (var sdRead = cmdOrder.ExecuteReader())
{
sdRead.Read();
iQuantityDB = Convert.ToInt32(sdRead["Quantity"]);
}
}
if (iQuantityDB > iQuantity)
{
string InsertQuery = #"INSERT INTO Sale(CustomerID, ProductID, Price, Quantity, Subtotal, GST, Total)VALUES(#iCustomerID, #iProductID, #dPrice, #iQuantity, #dSubtotal, #dGST, #Total)";
using (var InsertCMD = new SqlCommand(InsertQuery, sqlconn))
{
InsertCMD.Connection = sqlconn;
InsertCMD.Parameters.AddWithValue("#iCustomerID", iCustomerID);
InsertCMD.Parameters.AddWithValue("#iProdcutID", iProductID);
InsertCMD.Parameters.AddWithValue("#dPrice", dPrice);
InsertCMD.Parameters.AddWithValue("#iQuantity", iQuantity);
InsertCMD.Parameters.AddWithValue("#dSubtotal", dSubtotal);
InsertCMD.Parameters.AddWithValue("#dGST", dGST);
InsertCMD.Parameters.AddWithValue("#dTotal", dTotal);
InsertCMD.ExecuteNonQuery();
LoadDataonTable();
}
}
else
{
MessageBox.Show("no more stock");
}
sqlconn.Close();
}
}
At the line using (var sdRead = cmdOrder.ExecuteReader()) your SQL SELECT query is using a parameter - WHERE ProductID = #iProductID - but this hasn't been set. Hence the error message Must declare the scalar variable "#iProductID"
Just add cmdOrder.Parameters.AddWithValue("#iProductID", iProductID) between defining the SQL and executing it, and that should clear that problem.
Moving on to the next one - you're using AddWithValue("#dTotal" but it's #Total in the SQL :)
I have a few tables in a c# application I'm currently working on and for 4/5 of the tables everything saves perfectly fine no issues. For the 5th table everything seems good until I reload the program again (without modifying the code or working with a seperate install so that the data doesn't go away) The 4/5 tables are fine but the 5th doesn't have any records in it after it has been restarted (but it did the last time it was running). Below is some code excerpts. I have tried a few different solutions online including creating a string to run the sql commands on the database manually and creating the row directly as opposed to the below implementation which uses a generic data row.
//From main window
private void newInvoice_Click(object sender, EventArgs e)
{
PosDatabaseDataSet.InvoicesRow newInvoice = posDatabaseDataSet1.Invoices.NewInvoicesRow();
Invoices iForm = new Invoices(newInvoice, posDatabaseDataSet1, true);
}
//Invoices Table save [Works] (from Invoices.cs)
private void saveInvoice_Click(object sender, EventArgs e)
{
iRecord.Date = Convert.ToDateTime(this.dateField.Text);
iRecord.InvoiceNo = Convert.ToInt32(this.invoiceNumField.Text);
iRecord.Subtotal = (float) Convert.ToDouble(this.subtotalField.Text);
iRecord.Tax1 = (float)Convert.ToDouble(this.hstField.Text);
iRecord.Total = (float)Convert.ToDouble(this.totalField.Text);
iRecord.BillTo = this.billToField.Text;
invoicesBindingSource.EndEdit();
if (newRecord)
{
dSet.Invoices.Rows.Add(iRecord);
invoicesTableAdapter.Adapter.Update(dSet.Invoices);
}
else
{
string connString = Properties.Settings.Default.PosDatabaseConnectionString;
string queryString = "UPDATE dbo.Invoices set ";
queryString += "Date='" + iRecord.Date+"'";
queryString += ", Subtotal=" + iRecord.Subtotal;
queryString += ", Tax1=" + iRecord.Tax1.ToString("N2");
queryString += ", Total=" + iRecord.Total;
queryString += " WHERE InvoiceNo=" + iRecord.InvoiceNo;
using (SqlConnection dbConn = new SqlConnection(connString))
{
SqlCommand command = new SqlCommand(queryString, dbConn);
dbConn.Open();
SqlDataReader r = command.ExecuteReader();
dbConn.Close();
}
}
dSet.Invoices.AcceptChanges();
}
//Invoice Items save [works until restart] (also from Invoices.cs)
private void addLine_Click(object sender, EventArgs e)
{
DataRow iRow = dSet.Tables["InvoiceItems"].NewRow();
iRow["Cost"] = (float)Convert.ToDouble(this.costField.Text);
iRow["Description"] = this.descriptionField.Text;
iRow["InvoiceNo"] = Convert.ToInt32(this.invoiceNumField.Text);
iRow["JobId"] = Convert.ToInt32(this.jobIdField.Text);
iRow["Qty"] = Convert.ToInt32(this.quantityField.Text);
iRow["SalesPerson"] = Convert.ToInt32(this.salesPersonField.Text);
iRow["SKU"] = Convert.ToInt32(this.skuField.Text);
dSet.Tables["InvoiceItems"].Rows.Add(iRow);
invoiceItemsTableAdapter.Adapter.Update(dSet,"InvoiceItems");
PosDatabaseDataSet.InvoiceItemsDataTable dTable = (PosDatabaseDataSet.InvoiceItemsDataTable)dSet.InvoiceItems.Copy();
DataRow[] d = dTable.Select("InvoiceNo=" + invNo.ToString());
invoiceItemsView.DataSource = d;
}
Thanks in advance for any insight.
UPDATE: October 17, 2011. I am still unable to get this working is there any more ideas out there?
you must execute your Sql Command in order to persis the changes you made.
using (SqlConnection dbConn = new SqlConnection(connString))
{
dbConn.Open();
SqlCommand command = new SqlCommand(queryString, dbConn);
command.ExecuteNonQuery();
dbConn.Close();
}
The ExecuteReader method is intended (as the name says) to read the data from a SQL table. You need to use a different method as you can see above.
We need some more info first, you haven't shown the case where your code fails.
Common mistakes on this kind of code is calling DataSet.AcceptChanges() before actually committing the changes to the database.
Second is a conflict between databound data through the binding source vs edits to the dataset directly.
Lets see the appropriate code and we can try and help.
Set a breakpoint after teh call to invoiceItemsTableAdapter and check the InvoiceItems table for the row you have added. Release the breakpoint and then close your app. Check the database again. I would say that another table may be forcibly overwriting the invoice item table.