I have error in this code. What should happen is if I have two stall in the database, the stall price must be doubled, but what happened in this code is if I have two stall in the database, the stall price isn't doubled and if I only have one stall the stall price is 0.
public double GetStallPrice(int commtaxno)
{
try
{
string query = "SELECT * FROM contract_details WHERE comm_tax_no = " + commtaxno;
DatabaseString myConnectionString = new DatabaseString();
OleDbConnection connection = new OleDbConnection();
connection.ConnectionString = myConnectionString.connect();
connection.Open();
OleDbCommand command = new OleDbCommand();
command.Connection = connection;
command.CommandText = query;
OleDbDataReader stallReader = command.ExecuteReader();
stallReader.Read();
while(stallReader.Read())
{
try
{
string query2 = "SELECT section_ID FROM specific_stall WHERE stall_no = '" + stallReader["stall_no"].ToString() + "'";
OleDbCommand command2 = new OleDbCommand();
command2.Connection = connection;
command2.CommandText = query2;
OleDbDataReader sectionReader = command2.ExecuteReader();
sectionReader.Read();
sectionid = Convert.ToInt32(sectionReader["section_ID"].ToString());
try
{
string query3 = "SELECT stall_price FROM stall_sections WHERE section_ID = " + sectionid;
OleDbCommand command3 = new OleDbCommand();
command3.Connection = connection;
command3.CommandText = query3;
OleDbDataReader stallPriceReader = command3.ExecuteReader();
stallPriceReader.Read();
stall_price = Convert.ToDouble(stallPriceReader["stall_price"].ToString());
}
catch (Exception c)
{
MessageBox.Show(c.GetBaseException().ToString());
}
}
catch (Exception b)
{
MessageBox.Show(b.GetBaseException().ToString());
}
sum_stall_price = sum_stall_price + stall_price;
}
connection.Close();
}
catch (Exception a)
{
MessageBox.Show(a.GetBaseException().ToString());
}
return sum_stall_price;
}
I think the error is here:
stallReader.Read();
while(stallReader.Read())
You read first record and then read the second, without processing the first.
You have to remove first row and leave just
while(stallReader.Read())
As a side note, you should try to always use using syntax with classes that implement IDisposable interface. So, just an example:
using (OleDbConnection connection = new OleDbConnection())
{
// All the code inside
}
In this way you're sure that the object is properly released.
Finally: do not compose queries manually, but use parameters instead!!
Using parameters can avoid SQL injection and many headaches due to numeric (float, double, currency) and dates conversion!!
Related
I would like to create a variable in C# that represents the number of records of a query.
I tested the query and works correct , returning the correct value.
SELECT Count(c.Cell_ID) AS CountOfCell_ID
FROM Cells AS c
HAVING (((Exists (SELECT 1
FROM ΠΑΡΟΝΤΕΣ as cu
WHERE c.Cell_ID = cu.CellID))=False));
This returns a number only.
I would like to assign that number(result) to a variable in c#.
First step is to write the following C# code in visual studio
int: CountValue;
cnn.ConnectionString = CnnStr;
cnn.Open();
OleDbCommand command = new OleDbCommand();
command.Connection = cnn;
string query = "SELECT Count(c.Cell_ID) AS CountOfCell_ID FROM Cells AS c HAVING(((Exists(SELECT 1 FROM ΠΑΡΟΝΤΕΣ as cu WHERE c.Cell_ID = cu.CellID)) = False));";
what should i do next to assign the value contained in query to CountValue?
What you should do next is execute the command, and read the value:
OleDbCommand command = new OleDbCommand();
command.Connection = cnn;
string query = "SELECT Count(c.Cell_ID) AS CountOfCell_ID FROM Cells AS c HAVING(((Exists(SELECT 1 FROM ΠΑΡΟΝΤΕΣ as cu WHERE c.Cell_ID = cu.CellID)) = False));";
// Open connection
cnn.Open();
// Call command's ExcuteReader
OleDbDataReader reader = command.ExecuteReader();
while (reader.Read())
{
// Your value is here
Console.Write("OrderID :" + reader.GetInt32(0).ToString());
}
// close reader and connection
reader.Close();
cnn.Close();
The following worked for me
private void DashBoard_Load(object sender, EventArgs e)
{
// timer1.Start();
string sql = null;
sql = "SELECT Count(c.Cell_ID) AS CountOfCell_ID FROM Cells AS c HAVING(((Exists(SELECT 1 FROM ΠΑΡΟΝΤΕΣ as cu WHERE c.Cell_ID = cu.CellID)) = False));";
try
{
cnn.ConnectionString = CnnStr;
OleDbCommand command = new OleDbCommand();
command.Connection = cnn;
command= new OleDbCommand(sql, cnn);
cnn.Open();
Int32 count = Convert.ToInt32(command.ExecuteScalar());
command.Dispose();
cnn.Close();
MessageBox.Show(" No of Rows " + count);
cnn.Close();
}
catch (Exception ex)
{
MessageBox.Show("Error" + ex);
}
}
I am trying to populate my textbox after selecting a value from my comboBox.
My code is running fine, I don't have any errors when I run it but when I select a value from my comboBox, it's not populating my textbox. See my code below.
private OleDbConnection connection = new OleDbConnection();
public Form1()
{
InitializeComponent();
connection.ConnectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\ASUS\Documents\appointment2.accdb";
}
private void Lastname_SelectedIndexChanged(object sender, EventArgs e)
{
try
{
connection.Open();
OleDbCommand command = new OleDbCommand();
command.Connection = connection;
OleDbDataReader reader = command.ExecuteReader();
while (reader.Read())
{
string query = "select * from appointments where patientNo = '" + Lastname.Text + "' ";
command.CommandText = query;
Firstname.Text = reader["firstName"].ToString();
patientNum.Text = reader["patientNo"].ToString();
contactNum.Text = reader["contactNo"].ToString();
}
connection.Close();
}
catch (Exception ex)
{
MessageBox.Show("Error" + ex);
}
}
Two immediate issues that I see:
You are populating the CommandText property of the OleDbCommand object after issuing the ExecuteReader method, meaning there is no SQL statement being evaluated.
The SQL statement should be populated before the ExecuteReader method is issued, i.e.:
connection.Open();
OleDbCommand command = new OleDbCommand();
command.Connection = connection;
command.CommandText = "select * from appointments where patientNo = '" + Lastname.Text + "' ";
OleDbDataReader reader = command.ExecuteReader();
while (reader.Read())
{
Firstname.Text = reader["firstName"].ToString();
patientNum.Text = reader["patientNo"].ToString();
contactNum.Text = reader["contactNo"].ToString();
}
connection.Close();
The where clause of your SQL statement assumes that patientNo contains string data, which could be incorrect given the name of this field.
Just found out the issue. Had the wrong value to compare my Lastname.Text with and fixed the code's arrangement. Thanks for all your help everyone.
connection.Open();
OleDbCommand command = new OleDbCommand();
command.Connection = connection;
command.CommandText = "select * from appointments where lastName = '" + Lastname.Text + "' ";
OleDbDataReader reader = command.ExecuteReader();
while (reader.Read())
{
Firstname.Text = reader["firstName"].ToString();
patientNum.Text = reader["patientNo"].ToString();
contactNum.Text = reader["contactNo"].ToString();
}
connection.Close();
I have created Member Maintenance Code in which I will retrieve the members ID,Name and all basic things
My code is as follows:
private void Mem_Maintenance_Load(object sender, EventArgs e)
{
try
{
txt_mem_id.Text = Generate_no.gen_no("MEM").ToString();
}
catch(Exception Ex)
{
MessageBox.Show("Error\n\n"+Ex.ToString());
}
}
I have created a ClassLibrary named Library Whose code is as follows
namespace LIBRARY
{
public class Generate_no
{
public static int gen_no(string P_PRM_TYPE)
{ OleDbConnection connection = new OleDbConnection();
connection.ConnectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=E:\arekh\MS Access\soc_data.accdb;Persist Security Info=False;";
connection.Open();
int v_last_no = 0;
OleDbCommand command = new OleDbCommand();
command.Connection = connection;
string query = #"select PARM_VALUE from soc_parm_mast where PARM_TYPE = '" + P_PRM_TYPE + "';";
command.CommandText = query;
OleDbDataReader reader = command.ExecuteReader();
reader.Read();
v_last_no = Int32.Parse(reader["PARM_VALUE"].ToString()) + 1;
reader.Close();
command.CommandText = #"update soc_parm_mast set PARM_VALUE = PARM_VALUE+1 where PARM_TYPE = " + P_PRM_TYPE + ";";
command.ExecuteNonQuery();
connection.Close();
return v_last_no;
}
}
}
But during execution an error is coming up
System.FormatException:Input string was not incorrect format at
LIBRARY.Generate_no.gen_no(String P_PRM_TYPE)
command.CommandText = #"update soc_parm_mast set PARM_VALUE = PARM_VALUE+1 where PARM_TYPE = '" + P_PRM_TYPE + "';";
You were missing the single quotation marks in the update statement
The Line v_last_no = Int32.Parse(reader["PARM_VALUE"].ToString()) + 1; causing the specified Error, The Int32.Parse will throw FormatException if the input is not convertible. So i strongly advise you to use Int32.TryParse(). Then the code will be like the following:
public static int gen_no(string P_PRM_TYPE)
{
using (OleDbConnection connection = new OleDbConnection(#"Connection string here"))
{
connection.Open();
int v_last_no = 0;
using (OleDbCommand command = new OleDbCommand())
{
command.Connection = connection;
string query = #"select PARM_VALUE from soc_parm_mast where PARM_TYPE = #P_PRM_TYPE";
command.CommandText = query;
command.Parameters.AddWithValue("#P_PRM_TYPE", P_PRM_TYPE);
OleDbDataReader reader = command.ExecuteReader();
reader.Read();
if (!Int32.TryParse(reader["PARM_VALUE"].ToString(), out v_last_no))
{
// Conversion failed, Show message if needed
// v_last_no will be 0
}
reader.Close();
}
using (OleDbCommand command = new OleDbCommand())
{
command.CommandText = #"update soc_parm_mast set PARM_VALUE = PARM_VALUE+1 where PARM_TYPE =#P_PRM_TYPE";
command.Parameters.AddWithValue("#P_PRM_TYPE", P_PRM_TYPE);
command.ExecuteNonQuery();
}
}
return v_last_no;
}
One more advise for you : beware of SQL Injection while using the Concatenated string as queries. Use parameterized queries instead.
So,
I have a calculated int Answer in my program.
In my database are six columns.
The columns are ValueID, A, B, C, D and E.
When I press a button, I want the values from A, B, C, D and E where Answer matches ValueID, shown in a message box.
What I am doing now (possibly stupid) is below:
public void button1_Click(object sender, EventArgs e)
{
int Answer;
if (radioButton3.Checked)
{
Answer = Grade3 + Addition + PTime;
}
else
{
Answer = Grade + Addition + PTime;
}
//MessageBox.Show("Answer is: " + Answer);
int Value = Answer;
try
{
SqlConnection con = new SqlConnection(#"Data Source=(LocalDB)\MSSQLLocalDB; AttachDbFilename =|DataDirectory|\dbiss.mdf; Integrated Security = True; Connect Timeout = 30");
con.Open();
//SqlCommand comm = new SqlCommand("SELECT NC, Nodularity, UTS, Elongation, BHN FROM DataISS WHERE ValueID = '" + Value + "'", con);
SqlCommand comm = new SqlCommand("SELECT NC, Nodularity, UTS, Elongation, BHN FROM " +
"DataISS WHERE ValueID = #value", con);
comm.Parameters.AddWithValue("#value", Value);
using (SqlDataReader reader = comm.ExecuteReader())
{
if (reader.Read())
{
MessageBox.Show(String.Format("{0}", reader["id"]));
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Any help would be much appreciated.
Below is the proper way of adding parameters:
SqlCommand comm = new SqlCommand("SELECT NC, Nodularity, UTS, Elongation, BHN FROM " +
"DataISS WHERE ValueID = #value", con);
comm.Parameters.AddWithValue("#value", Value);
One of the overloads of AddWithValue takes the parameter name in used in the query and the value for that parameter.
If you still don't get any results, you need to try the same query using Query Window in Visual studio. You can then identify the problem that might be in a wrong Value sent from the c# application or in the way you're calculating the Value local parameter that is used as a parameter.
Structure command like below
SqlCommand comm = new SqlCommand("select NC, Nodularity, UTS, Elongation, BHN from DataISS where ValueID=#ValueID", con);
comm.Parameters.Add("#ValueID", SqlDbType.Int).Value = Value;
I would suggest using "using" in your code, so it closes connection itself. For example:
public static bool SomeMethod(int valueId)
{
bool result;
try
{
using (SqlConnection connection = new SqlConnection(DataConnection.MailForm))
{
connection.Open();
using (SqlCommand cmd = connection.CreateCommand())
{
cmd.CommandText = #"SELECT COUNT(*) FROM Mails
WHERE ValueID= #valueId";
cmd.Parameters.AddWithValue("#valueId", valueId);
int entryIdExist = Convert.ToInt32(cmd.ExecuteScalar());
result = entryIdExist <= 0;
}
}
}
catch (Exception)
{
result = false;
}
return result;
}
Use "#" before your string, this way you can use as many rows without connecting them with +
In my code below, the cmdquery works but the hrquery does not. How do I get another query to populate a grid view? Do I need to establish a new connection or use the same connection? Can you guys help me? I'm new to C# and asp. Here's some spaghetti code I put together. It may all be wrong so if you have a better way of doing this feel free to share.
if (Badge != String.Empty)
{
string cmdquery = "SELECT * from Employees WHERE Badge ='" + Badge + "'";
string hrquery = "SELECT CLOCK_IN_TIME, CLOCK_OUT_TIME FROM CLOCK_HISTORY WHERE Badge ='" + Badge + "'";
OracleCommand cmd = new OracleCommand(cmdquery);
cmd.Connection = conn;
cmd.CommandType = CommandType.Text;
conn.Open();
OracleDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
this.xUserNameLabel.Text += reader["EMPLOYEE_NAME"];
this.xDepartmentLabel.Text += reader["REPORT_DEPARTMENT"];
}
OracleCommand Hr = new OracleCommand(hrquery);
Hr.Connection = conn;
Hr.CommandType = CommandType.Text;
OracleDataReader read = Hr.ExecuteReader();
while (read.Read())
{
xHoursGridView.DataSource = hrquery;
xHoursGridView.DataBind();
}
}
conn.Close();
Your data access code should generally look like this:
string sql = "SELECT * FROM Employee e INNER JOIN Clock_History c ON c.Badge = e.Badge WHERE e.Badge = #BadgeID";
using (var cn = new OracleConnection("your connection string here"))
using (var cmd = new OracleCommand(sql, cn))
{
cmd.Parameters.Add("#BadgeID", OracleDbType.Int).Value = Badge;
cn.Open();
xHoursGridView.DataSource = cmd.ExecuteReader();
xHoursGridView.DataBind();
}
Note that this is just the general template. You'll want to tweak it some for your exact needs. The important things to take from this are the using blocks to properly create and dispose your connection object and the parameter to protect against sql injection.
As for the connection question, there are exceptions but you can typically only use a connection for one active result set at a time. So you could reuse your same conn object from your original code, but only after you've completely finished with it from the previous command. It is also okay to open up two connections if you need them. The best option, though, is to combine related queries into single sql statement when possible.
I'm not even going to get into how you should be using usings and methods :p
if (Badge != String.Empty)
{
string cmdquery = "SELECT * from Employees WHERE Badge ='" + Badge + "'";
string hrquery = "SELECT CLOCK_IN_TIME, CLOCK_OUT_TIME FROM CLOCK_HISTORY WHERE Badge ='" + Badge + "'";
OracleCommand cmd = new OracleCommand(cmdquery);
cmd.Connection = conn;
cmd.CommandType = CommandType.Text;
conn.Open();
OracleDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
this.xUserNameLabel.Text += reader["EMPLOYEE_NAME"];
this.xDepartmentLabel.Text += reader["REPORT_DEPARTMENT"];
}
OracleCommand Hr = new OracleCommand(hrquery);
Hr.Connection = conn;
Hr.CommandType = CommandType.Text;
OracleDataReader read = Hr.ExecuteReader();
//What's this next line? Setting the datasource automatically
// moves through the data.
//while (read.Read())
//{
//I changed this to "read", which is the
//datareader you just created.
xHoursGridView.DataSource = read;
xHoursGridView.DataBind();
//}
}
conn.Close();