Check if a row exists using windows form? - c#

I was creating an Appointment Table and i want to check if the row contains same Date,Slot,HR exists before another user enter.
The Connection is Opened Before this shown code.
SqlCommand slot_check = new SqlCommand("select * from Appointment where AppoinmentDate='"+textBox1.Text+"' and Slot='"+comboBox3.Text+ "'and HRName='" +comboBox2.Text+"'");
SqlDataReader Exist = slot_check.ExecuteReader();
if (Exist.HasRows)
{
string message = "Appointment Already Exists!!!!!";
MessageBox.Show(message);
}
else
{
string message = "Update";
MessageBox.Show(message);
}
System.InvalidOperationException: 'ExecuteReader: Connection property has not been initialized.'

To execute a command two informations are essential:
The sql string to execute and the connection to reach the database.
Without the connection your command cannot be executed because the framework doesn't know how to read or write the database.
There is an overload for the SqlCommand constructor that takes the two required parameters:
SqlCommand cmd = new SqlCommand(sqlText, connectionInstance);
So your code should be something like this
// The command text to run, without string concatenations and with parameters placeholders
string sqlText = #"select * from Appointment
where AppoinmentDate=#aptDate
and Slot=#slot
and HRName=#name";
// Using statement to correctly close and dispose the disposable objects
using(SqlConnection cnn = new SqlConnection(connectionString))
using(SqlCommand slot_check = new SqlCommand(sqlText, cnn))
{
// A parameter for each placeholder with the proper datatype
cmd.Parameters.Add("#aptDate", SqlDbType.Date).Value = Convert.ToDateTime(textBox1.Text);
cmd.Parameters.Add("#slot", SqlDbType.NVarChar).Value = comboBox3.Text;
cmd.Parameters.Add("#name", SqlDbType.NVarChar).Value = comboBox2.Text;
cnn.Open();
// Even the SqlDataReader is a disposable object
using(SqlDataReader Exist = slot_check.ExecuteReader())
{
if (Exist.HasRows)
{
string message = "Appointment Already Exists!!!!!";
MessageBox.Show(message + " " + Exist + comboBox2.Text);
}
else
{
string message = "Update";
MessageBox.Show(message);
}
}
}
As you can see the code now has a connection passed to the command constructor and a command text built without concatenating strings but using parameters.
Using parameters is a mandatory approach for any kind of database related operation. Without parameters your code could be exploited with the well known Sql Injection hack, but also, the simple presence of a single quote in your values, could break the sql syntax resulting in a Syntax Error Exception
Note that this code could still be wrong because I don't know what kind of data is stored in your table in the columns used in the WHERE statement. I assumed some kind of type but you should check against your table and verify if they are correct.

Related

How to delete from Access database from C#

I am trying to add code that will delete from 2 tables in access db file. Sometimes one of them will work and the other wont then when I try it another way it will do the opposite. So in the end only 1 of the 2 works.
Here is my code I hope someone can spot something I did wrong.
try
{
Conn.Open();
OleDbCommand command = new OleDbCommand();
command.Connection = Conn;
command.CommandText = "DELETE FROM TBLNAME WHERE name =#name";
command.Parameters.AddWithValue("#name", lvlist.SelectedItems[0].Text);
command.ExecuteNonQuery();
command.CommandText = "DELETE from TBLNAME WHERE cb_listName =#listname";
command.Parameters.AddWithValue("#listname", lvlist.SelectedItems[0].Text);
command.ExecuteNonQuery();
Conn.Close();
}
catch (Exception ex)
{
MessageBox.Show("Error " + ex);
}
You should use different Command instances, one for each command you want to execute. If you do not do that then you need to clear the parameters. This is because parameters in OleDb queries are positional and not named. This means that when you add the 2nd parameter in the 2nd query the first parameter is used because it is first in the list.
using(var connection = new OleDbConnection("connection string here"))
{
connection.Open();
using(var command = new OleDbCommand("DELETE FROM TBLNAME WHERE name = #name", connection))
{
cmd.Parameters.Add(new OleDbParameter("#name", OleDbType.VarChar, 50)).Value = lvlist.SelectedItems[0].Text;
command.ExecuteNonQuery();
}
using(var command = new OleDbCommand("DELETE from TBLNAME WHERE cb_listName = #listname", connection))
{
cmd.Parameters.Add(new OleDbParameter("#listname", OleDbType.VarChar, 50)).Value = lvlist.SelectedItems[0].Text;
command.ExecuteNonQuery();
}
}
Also you should:
Use using blocks to ensure connections are closed after use. Do not try to create class scoped, or even worse global, connection instances.
You should also specify the db type for your parameters and do not use AddwithValue.
When possible also specify the length for your db types, in the above this is possible if you have a varchar type. note I toke a guess at your schema length for these columns
Finally, just a note on general best practices, do not add catch blocks that do nothing useful with the exception. At least log the type, message, and the stack trace and then repeat this recursively for each inner exception found in property InnerException. This useful information can help you figure out exactly why an exception occurred.
Use two different OleDbCommand objects.

Getting column information in SQL

I am somwhat new to SQL, so I am not sure I am going about this the right way.
I am trying to fetch data from my SQL Server database where I want to find out if checkedin is 1/0, but it needs to search on a specific user and sort after the newest date as well.
What I am trying to do is something like this:
string connectionString = ".....";
SqlConnection cnn = new SqlConnection(connectionString);
SqlCommand checkForInOrOut = new SqlCommand("SELECT CHECKEDIN from timereg ORDER BY TIME DESC LIMIT 1 WHERE UNILOGIN = '" + publiclasses.unilogin + "'", cnn);
So my question, am I doing this right? And how do I fetch the data collected, if everything was handled correctly it should return 1 or 0. Should I use some sort of SqlDataReader? I am doing this in C#/WPF
Thanks
using (SqlDataReader myReader = checkForInOrOut.ExecuteReader())
{
while (myReader.Read())
{
string value = myReader["COLUMN NAME"].ToString();
}
}
This is how you would read data from SQL, but i recommend you looking into Parameters.AddWithValue
There are some errors in your query. First WHERE goes before ORDER BY and LIMIT is an MySql keyword while you are using the Sql Server classes. So you should use TOP value instead.
int checkedIn = 0;
string cmdText = #"SELECT TOP 1 CHECKEDIN from timereg
WHERE UNILOGIN = #unilogin
ORDER BY TIME DESC";
string connectionString = ".....";
using(SqlConnection cnn = new SqlConnection(connectionString))
using(SqlCommand checkForInOrOut = new SqlCommand(cmdText, cnn))
{
cnn.Open();
checkForInOrOut.Parameters.Add("#unilogin", SqlDbType.NVarChar).Value = publiclasses.unilogin;
// You return just one row and one column,
// so the best method to use is ExecuteScalar
object result = checkForInOrOut.ExecuteScalar();
// ExecuteScalar returns null if there is no match for your where condition
if(result != null)
{
MessageBox.Show("Login OK");
// Now convert the result variable to the exact datatype
// expected for checkedin, here I suppose you want an integer
checkedIN = Convert.ToInt32(result);
.....
}
else
MessageBox.Show("Login Failed");
}
Note how I have replaced your string concatenation with a proper use of parameters to avoid parsing problems and sql injection hacks. Finally every disposable object (connection in particular) should go inside a using block

ExecuteScalar has not been initialized [duplicate]

This question already has answers here:
ExecuteNonQuery: Connection property has not been initialized.
(7 answers)
Closed 7 years ago.
I keep getting this error saying that "ExecuteScalar has not been initialized" I have new to C# but had a look through google and tutorials and still cant see what the problem is. Its probably a very silly mistake but if anyone could help. Thanks :)
// open connection
myConnection.Open();
// sql command
string Account_Num = txt_acc.Text;
string Pin_num = txt_pin.Text;
SqlCommand check_details = new SqlCommand("select Account_num, Pin_num from Cust_details where Account_num='" + txt_acc.Text + "'and Pin_num ='" + txt_pin.Text + "'");
check_details.Parameters.AddWithValue("#Account_num", txt_acc.Text);
check_details.Parameters.AddWithValue("#Pin_num", txt_pin.Text);
int result = Convert.ToInt32(check_details.ExecuteScalar());
if (result > 0)
{
Console.WriteLine("user exists");
}
else
{
Console.WriteLine("error");
}
}
Looks like you didn't connect your command with connection. Just set it's Connection property to myConnection.
check_details.Connection = myConnection;
or you can set it on your SqlCommand constructor as a second parameter;
SqlCommand check_details = new SqlCommand("yourCommand", myConnection);
or you can use CreateCommand method from your connection;
SqlCommand check_details = myConnection.CreateCommand();
And you are misunderstood the parameterized queries. You still do string concatenation in your sql query but you try to add parameters. That's meaningless.
Use using statement to dispose your connection and command automatically as well.
Also don't use AddWithValue as much as you can. It may generate unexpected and surprising results sometimes. Use Add method overload to specify your parameter type and it's size.
using(var myConnection = new SqlConnection(conString))
using(var check_details = myConnection.CreateCommand())
{
check_details.CommandText = #"select Account_num, Pin_num from Cust_details
where Account_num = #accnum
and Pin_num = #pinnum";
// I assume your column types as Int
check_details.Parameters.Add("#accnum", SqlDbType.Int).Value = int.Parse(txt_acc.Tex);
check_details.Parameters.Add("#pinnum", SqlDbType.Int).Value = int.Parse(txt_pin.Text);
myConnection.Open();
int result = (int)check_details.ExecuteScalar();
...
}
By the way, there is no point to select Pin_num column in your command since ExecuteScalar ignores it.

OleDBException was unhandled: Syntax error in query (Incomplete query clause)

I'm trying to execute a very simple SQL statement on an Access database through C#.
The statement is something like this:
select M_PASSWORD from TB_USERS where M_USERNAME = 'myuser'
and this is the C# code I'm using to execute the SQL statement:
string connString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + sources.global_variables.db_source;
using (OleDbConnection connection = new OleDbConnection(connString))
{
connection.Open();
OleDbDataReader reader = null;
OleDbCommand command = new OleDbCommand("SELECT #1 from #2 WHERE #3='#4'", connection);
command.Parameters.AddWithValue("#1", db_column);
command.Parameters.AddWithValue("#2", db_table);
command.Parameters.AddWithValue("#3", db_where_column);
command.Parameters.AddWithValue("#4", db_where_value);
reader = command.ExecuteReader();
//rest of code
Once I get to the line reader = command.ExecuteReader();, the reader fails the execution of the query giving me the following error message: OleDBException was unhandled: Syntax error in query (Incomplete query clause).
I've debugged the code to see if I could see any wrong assignment in the parameters values, but they look fine.
Moreover, executing the exact same query on the Query Analyzer of the Database, I retrieve the value I want.
Could anyone give a tip to spot the problem and understand where I'm wrong?
I think you cant pick column names as parameter such that. It might be the problem.
Use if statement or other conditional statements for parameter and move your query to inside of your conditional statement.
I don't believe that parameters can be used in the fashion you posted. Parameters are used for filling in values (ie, placing a DateTime value into an update statement as the value of a DateTime column to be updated in a table).
Try changing your code such that the column names and table names are provided in text or are filled in as a string. You can build the query string up if you want to fill in different column names, different table names, and different column names in your where clause. So instead of what you posted, try something more like this:
string connString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + sources.global_variables.db_source;
using (OleDbConnection connection = new OleDbConnection(connString))
{
connection.Open();
OleDbDataReader reader = null;
string strQuery = "SELECT " + constStringColumnName1 + " FROM " + theTableNamePassedInAsString + " WHERE " + strWhereClauseBuiltEarlierInThisFunction + " = '#1'";
OleDbCommand command = new OleDbCommand( strQuery , connection);
command.Parameters.AddWithValue("#1", db_where_value);
reader = command.ExecuteReader();
//rest of code
}
Of course, you could format the string and plug in your changing selection column name, your table name, and your where clause. Build your select/command string, then use Parameters to fill in the actual value is the normal usage.
Try remove the ' on where parameter and use ? insted of # like that
OleDbCommand command = new OleDbCommand("SELECT ? from ? WHERE ?=?", connection);
command.Parameters.AddWithValue("column", db_column);
command.Parameters.AddWithValue("table", db_table);
command.Parameters.AddWithValue("where_column", db_where_column);
command.Parameters.AddWithValue("where_value", db_where_value);
I dont know if you can use parameters on column name. If it won´t running try to execute the query without parameters using concat and only use parameters on where value

c# Update Command to Access Database

I am trying to update data in access table. However, i keep receiving a syntax error when i attempt to update. Below is the code ive compiled. Textbox37 is the one that requires updates.
string constr1;
constr1 = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=F:\\Documents\\data.accdb;Jet OLEDB:Database";
string cmdstr = "Update Log(Notes,Status)Values(#a,#b) Where LogIncNum='" + LogInc + "'";
using (OleDbConnection con1 = new OleDbConnection(constr1))
{
using (OleDbCommand com = new OleDbCommand(cmdstr, con1))
{
com.CommandType = CommandType.Text;
com.Parameters.AddWithValue("#a", textBox37.Text);
com.Parameters.AddWithValue("#b", "Active");
con1.Open();
com.ExecuteNonQuery();
}
}
The correct syntax for an update statement is
UPDATE table SET field1=value1, field2=value2 WHERE field3=value3
You are using the wrong syntax hence the syntax error
As a side note, did you forget to use a parameter for the WHERE condition?
It is always correct to use a parameter for every value that you want to include in your query. Just remember to put it in the correct order because OleDb doesn't recognize the parameter by their name, but use a strictly positional order in the Parameters collection, so the first one goes assigned to the first parameter placeholder and so on.
easy way
using (var aq_pension = new System.Web.UI.WebControls.SqlDataSource())
{
aq_pension.ProviderName = "System.Data.OleDb";
aq_pension.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:/stat_tresor/stat_tresor/stat_tresor/db/stat1.mdb";
aq_pension.UpdateCommand = "UPDATE tableaux1 SET nbre=0, montant_mois=0,total=0 WHERE code <>''";
aq_pension.Update();
}

Categories