I don’t know if this is the correct way to be doing this but I'm trying to get all Job Numbers from a database table and checking that what the user inputs is in the database. I’m doing this by sending all data to an array and checking if it exists in there. However I’m sure there will be an easier way. This is the code I have so far:
public class IDNo
{
public int Col1 { get; set; }
}
private void button3_Click(object sender, EventArgs e)
{
String check = "SELECT * FROM Job";
using (SqlConnection con = new SqlConnection(str))
{
using (SqlCommand cmd = new SqlCommand(check, con))
{
con.Open();
var listOfId = new List<IDNo>();
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
var id = new IDNo();
id.Col1 = Convert.ToInt32(reader["JobNo"]);
listOfId.Add(id);
}
}
string JN = textBox10.Text;
int JoNo = Int32.Parse(JN);
if (JoNo == IDNo)
{
MessageBox.Show("No job number found, please try again!");
}
else
{
DO SOMETHING HERE WHEN CORRECT
}
}
}
}
I would just like some help on how to check if the number the user inputs exists in the array.
It is the database engine that should answer your question, not simply give you back all your job records and force your code through a, possible, very lengthy search of the matching data in your records...
int JoNo;
if(!Int32.TryParse(textBox10.Text, out JoNo))
{
MessageBox.Show("Not a valid number");
return;
}
String check = #"IF EXISTS( SELECT 1 FROM Job WHERE JobNo=#num)
SELECT 1 ELSE SELECT 0";
using (SqlConnection con = new SqlConnection(str))
using (SqlCommand cmd = new SqlCommand(check, con))
{
con.Open();
cmd.Parameters.Add("#num", SqlDbType.Int).Value = JoNo;
int result = (int)cmd.ExecuteScalar();
if(result == 0)
MessageBox.Show("No job number found, please try again!");
else
.....
}
First, you test if the user input is a valid number without throwning exceptions (Int32.TryParse) but just informing your user of the error, then you build an IF EXISTS query because you are just interested to know if the job number exists or not and you don't need to retrieve that value. Finally, the execution is done using ExecuteScalar because you are interested only in getting the single value 1 (for an existing JobNo or 0 for a not exisisting JobNo.
You can use the jobNo which is sent by the user as an input parameter for your search query in database. So you can simply do it using the query:
SqlCommand check = new SqlCommand("SELECT * FROM Job where JobNo = #JobNo" , conn);
check.Parameters.AddWithValue("#JobNo", id.Text);
int exists = (int)check.ExecuteScalar();
if(exists > 0)
{
//job no exist
}
else
{
//job no doesn't exist.
}
Related
I have this windows form code
private void StartGame_Click(object sender, EventArgs e)
{
if (player.Text == "")
{
MessageBox.Show("Enter A player to proceed.");
}
else
{
//SQL Connection String
using (SqlConnection conn = new SqlConnection("Data Source=Keith;Initial Catalog=SoftEngg;Integrated Security=True"))
{
conn.Open();
bool exists = false;
// create a command to check if the username exists
using (SqlCommand cmd = new SqlCommand("select * from PlayerData where PlayerName = #player", conn))
{
cmd.Parameters.AddWithValue("player", player.Text);
exists = (int)cmd.ExecuteScalar() > 0;
}
// if exists, show a message error
if (exists)
MessageBox.Show(player.Text, "is used by another user.");
else
{
// does not exists, so, persist the user
using (SqlCommand cmd = new SqlCommand("INSERT INTO PlayerData(PlayerName) values (#Playername)", conn))
{
cmd.Parameters.AddWithValue("Playername", player.Text);
cmd.ExecuteNonQuery();
}
}
conn.Close();
}
}
}
my goal is to alert the player and display the messagebox "player already exist" in the system. But my code doesn't seem to work. When I run the program I get an error over this code here:
exists = (int)cmd.ExecuteScalar() > 0;
and the error says: (Additional information: Object reference not set to an instance of an object.)
How to fix this, please help.
You should use select Count(*) from PlayerData where PlayerName = #player if you want to use ExecuteScalar
Your problem not was in the query.
i mean not in this select * from PlayerData where PlayerName = #player
you were getting the error because of exists = (int)cmd.ExecuteScalar() > 0;
Cause:
here you are trying to convert the output to Integer.
so, when cmd.ExecuteScalar() getting the null Value on that time you are getting the error.
Have to Remember
SqlCommand.ExecuteScalar:
Executes the query, and returns the first column of the first row in
the result set returned by the query. Additional columns or rows are
ignored.
you can use select * from PlayerData where PlayerName = #player but you must confirm that your first column of this table is a NonNullable column.
and your checking should be like
exists = (cmd.ExecuteScalar()!=null)?true:false;
Or, you can try by selecting your primary key column.
select your_Primary_Key_Name from PlayerData where PlayerName = #player
and check
exists = (cmd.ExecuteScalar()!=null)?true:false;
do not use AddWithValue
cmd.Parameters.Add("#player",SqlDbType.Varchar,200).Value=YourValue;
I have a problem with saving queries into my Local DB in the current session. However, the database got updated when I close the app.
Scenario: I have a login Window and Register Window, when user register I have queries to save his/her info into DB but after closing the whole application, it should save it in the same session without needing to close the app.
I'm using this code for registration window:
private async void button_Click(object sender, RoutedEventArgs e)
{
if (textBox.Text.Length >= 4 && textBox1.Password.Length >= 4)
{
using (var conn = new SqlConnection(#"Data Source"))
using (var cmd = conn.CreateCommand())
{
cmd.CommandText =
"Select Count(*) From Results Where PlayerName = #playerName";
conn.Open();
cmd.Parameters?.Add("#playerName", textBox.Text);
cmd.Parameters?.Add("#Password", textBox1.Password);
var count = (int) cmd.ExecuteScalar();
if (count == 0)
{
cmd.CommandText =
"INSERT INTO LoginInfo (PlayerName, Password) Values (#playerName , #Password)";
cmd.ExecuteNonQuery();
conn.Close();
Close();
}
else
{
label3.Content = "The UserName is already registerd!";
}
}
}
else
{
label3.Content =
"Please Enter Valid information User Name +" +
"and Password should be more than 4 Digits";
}
}
Edit: I used #displayName, suggestion and I saw that actually it updated because when I'm writing same info it gives that user already registered.
Probably there is a mistake with Linq to SQL in login window here is my login window code:
private void Login_Click(object sender, RoutedEventArgs e)
{
var db = new DataClasses1DataContext();
var userName = from t in db.LoginInfos
select new
{
t.Id,
t.PlayerName,
t.Password
};
foreach (var variable in userName)
{
if (UserName.Text == variable.PlayerName && text_Password.Password == variable.Password)
{
var openChoiceGame = new ChoiceGame(UserName.Text);
textBlock.Text = "The login information are correct ";
openChoiceGame.Show();
using (
var conn =
new SqlConnection(
#"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\Saif-DevEnv\Source\Workspaces\QuizClashGame\GameQuizClash\Players.mdf;Integrated Security=True;Connect Timeout=30")
)
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = "Select Count(*) From Results Where PlayerName = #playerName";
cmd.Parameters.Add("#playerName", UserName.Text);
conn.Open();
var count = (int) cmd.ExecuteScalar();
if (count == 0)
{
// It means it does not exist.
cmd.CommandText = "INSERT INTO Results(PlayerName) VALUES (#playerName)";
cmd.ExecuteNonQuery();
}
conn.Close();
var player = new SoundPlayer(#"C:\Users\Saif-DevEnv\Desktop\SoundRes\switch32.wav");
player.Play();
}
Close();
}
else
{
textBlock.Text = "The login information are not correct ";
}
}
}
Are there any errors with Login window code?
I don't see any reason for the async keyword. It should work fine after you remove that.
First thought: I see that you are ExecutingScalar() on Results while ExecutingNonQuery() on LoginInfo i.e. on two different tables. Is that the issue?
Second thought: You can change the way you are testing for inserting into LoginInfo. Do it this way rather -
if (cmd.ExecuteNonQuery() == -1)
{
label3.Content = "The UserName is already registerd!";
}
Maybe this helps: Asynchronous Programming
The problem was with Linq To Sql part.
However,the solution for it was I have added the source of data into DataContext(#DataSource) or in my code is DataClasses1DataContext(#DataSource);and also use Refresh Method db.Refresh(RefreshMode.OverwriteCurrentValues,_db.LoginInfos);
I have a textbox and a button in a windows form application.
I want to check if the primary key (persId) exists in my sql database/dataset (made with Visual studio) when I enter a number in the textbox and press the button. I dont know how to compare the text with persId from the database.
If the persId exists I want to fill two textboxes in a new form and show the persId and persName.
I am new to programming in C# so I have probably missed something. I looked at how to check if value exists in database from textbox c# but could not find an answer.
Thanks in advance!
public void searchPersId(string persId)
{
SqlConnection conn = new SqlConnection();
SqlCommand myCommand = new SqlCommand("SELECT persId FROM Customers WHERE persId = #persId", conn);
myCommand.Parameters.AddWithValue("#persId", persId);
if (textBox1.Text = myCommand ) //I dont know how to compare the values of textbox with myCommand..
{
//Show values (persId and persName) in two textBoxes in a new form.
}
else
{
MessageBox.Show("The ID does not exist.");
}
}
First, use the using-statement for everything implementing IDisposable like the connection to dispose unmanaged resources and to close the connection, even in case of an error.
Then you have to open the connection and to use ExecuteReader to get a datareader to check if there's at least one record with that ID, you can use reader.HasRows. You also have to select the persName if you want it as mentioned.
using(var conn = new SqlConnection())
using(var myCommand = new SqlCommand("SELECT persId, persName FROM Customers WHERE persId = #persId", conn))
{
myCommand.Parameters.AddWithValue("#persId", persId);
conn.Open();
using(var rd = myCommand.ExecuteReader())
{
bool personExists = rd.HasRows;
if(personExists)
{
// advance the reader to the first record, presuming there is only one, otherwise use a loop while(rd.Read)
rd.Read();
string persName = rd.GetString(1); // second field
// ...
}
else
{
MessageBox.Show("The ID does not exist.");
}
}
}
You can also use ExecuteScalar
public void searchPersId(string persId)
{
SqlConnection conn = new SqlConnection();
SqlCommand myCommand = new SqlCommand("SELECT persName FROM Customers WHERE persId = #persId", conn);
myCommand.Parameters.AddWithValue("#persId", persId);
object personName = myCommand.ExecuteScalar();
if(!string.IsNullOrEmpty(personName.ToString()))
//if (textBox1.Text = myCommand) //I dont know how to compare the values of textbox with myCommand..
{
//Show values (persId and persName) in two textBoxes in a new form.
textBox2.Text = personName.ToString();
}
else
{
MessageBox.Show("The ID does not exist.");
}
}
First you have to Execute the command.
SqlDataReader dr = myCommand.ExecuteReader(CommandBehavior.CloseConnection);
if (dr.HasRows)
{
// ... if it has rows then you know it match
}
else
{
// ... data doesn't exists
}
Then you can compare the result.
I have a database created in a server and I added a row by MySql query browser for testing. This row is visible either with PhpMyAdmin or MySql query browser.
But when I want to reach this table within my program it says me there is no rows (reader.HasRows = false)
cs is the connection string in PublicVariables class
Here is the code
public static int checkuser(string myuser, string mypass)
{
try
{
using (MySqlConnection conn = new MySqlConnection(PublicVariables.cs))
{
string MypassMd5 = MakeMD5(mypass);
conn.Open();
if (conn == null)
Environment.Exit(0);
using (MySqlCommand cmd =
new MySqlCommand("SELECT username, password " + "FROM Users WHERE username = 'myuser'" ,conn))
{
using (MySqlDataReader reader = cmd.ExecuteReader())
{
//DateTime mytime = DateTime.Now ;
if (reader.HasRows)
{
if (Convert.ToString(reader["password"]) != MypassMd5)
{
reader.Close();
conn.Close();
return -1;
}
else
{
PublicVariables.UserId = Convert.ToString(reader["username"]);
PublicVariables.UserDegre = Convert.ToInt16(reader["userdegre"]);
conn.Close();
reader.Close();
return 1;
}
}
else
{
reader.Close();
conn.Close();
return 2;
}
}
}
}
}
catch (MySqlException ex)
{
MessageBox.Show(ex.ToString());
}
return 0;
}
What's wrong in my code?
Well the primary error is in your command string , myuser is a variable and you cannot pass its value putting the variable name inside quotes.
new MySqlCommand("SELECT username, password FROM Users WHERE username = 'myuser'" ,conn)
instead this line should be converted to use a parameterized query
string commandText = "SELECT username, password, userdegre FROM Users WHERE username = #uname";
using (MySqlCommand cmd = new MySqlCommand(commandText ,conn)
{
cmd.Parameters.AddWithValue("#uname", myuser);
....
Looking at your code you have another error after this. You try to read the field userdegre, but this field is not retrieved by your query, so you need to add it to the list of retrieved fields.
But the only field you really need to know is userdegre because you already know the username and the password, so you could remove the datareader and use ExecuteScalar and pass the username and the password as parameters for the WHERE clause. If you get anything in return then you are sure that your user is authenticated by the database.
string commandText = "SELECT userdegre FROM Users WHERE username = #uname AND Password =#pwd";
using(MySqlCommand cmd = new MySqlCommand( commandText ,conn))
{
cmd.Parameters.AddWithValue("#uname", myuser);
cmd.Parameters.AddWithValue("#pwd", MypassMd5);
var result = cmd.ExecuteScalar();
if(result != null)
{
PublicVariables.UserId = myuser;
PublicVariables.UserDegre = result.ToString();
}
}
Don't check reader.HasRows. You need to call reader.Read(), and check the result of that.
Also, some side issues:
MD5 is incredibly weak for a password hash. Really. Just don't use it for that. Look into bcrypt as a much better alternative. Better still if you're not writing authentication code yourself at all. Look for a library for help to get this stuff right... it's just so easy to write authentication code that seems to work, passes all your tests, but has a subtle flaw that gets you hacked a few months down the road.
No need to call conn.Close(). That's what your using blocks are for. They will handle this for you.
I'd remove the try/catch as well. Since you're already returning error conditions to the calling code, I'd leave that as the place where errors are processed, such that your try/catch should go at that level.
You're looking for userdegre in the results that was not in the select list.
Parameterized queries are your friend.
Put it all together you and you end up with this:
public static int checkuser(string myuser, string mypass)
{
string passHash = BCrypt(mypass); //Need to get bcyrpt library and make the function
using (MySqlConnection conn = new MySqlConnection(PublicVariables.cs))
using (MySqlCommand cmd =
new MySqlCommand("SELECT username, password, userdegre FROM Users WHERE username = #user" ,conn))
{
cmd.Parameters.Add("#user", SqlDbType.NVarChar, 20).Value = myuser;
conn.Open();
using (MySqlDataReader reader = cmd.ExecuteReader())
{
if (!reader.Read()) return 2;
if (Convert.ToString(reader["password"]) != MypassMd5) return -1;
PublicVariables.UserId = Convert.ToString(reader["username"]);
PublicVariables.UserDegre = Convert.ToInt16(reader["userdegre"]);
return 1;
}
}
}
I would try something like this new MySqlCommand("SELECT username, password, userdegre " + "FROM Users WHERE username = 'myuser'" ,conn))
adding userdegre the column name in your select statement.
Finally for c# 2008 net 3.5 WORKING COPY of this after the help of #Joel and # Steve is as this:
public static int usertrue(string myuser, string mypass)
{
try
{
using (MySqlConnection conn = new MySqlConnection(PublicVariables.cs))
{
string MypassMd5 = MakeMD5(mypass);
using (MySqlCommand cmd =
new MySqlCommand("SELECT username, password ,userdegre FROM Users WHERE username = #user",conn))
{
cmd.Parameters.Add("#user", MySqlDbType.VarChar, 15).Value = myuser;
conn.Open();
using (MySqlDataReader reader = cmd.ExecuteReader())
{
if (!reader.Read()) return 2;
if (Convert.ToString(reader["password"]) != MypassMd5) return -1; {
PublicVariables.UserId = Convert.ToString(reader["username"]);
PublicVariables.UserDegre = Convert.ToInt16(reader["userdegre"]);
return 1;
}
}
}
}
}
I am generating a random number admission no and this is my DAL
public static int randomgen()
{
int id=0;
int number = r.Next(100);
HttpContext.Current.Session["number"] = "SN" + (" ") + number.ToString();
SqlConnection con = DBConnection.OpenConnection();
try
{
string sql1 = "select admissionno from tblstudent_details";
SqlCommand cmd=new SqlCommand(sql1,con);
SqlDataReader dr = cmd.ExecuteReader();
if (dr.Read())
{
id = Convert.ToInt32(dr[0]);
}
dr.Close();
return id;
}
catch (Exception)
{
throw;
}
}
and i am checking if there is any duplicate is getting generated but i am getting an error like Input string is not in a correct format?Where i am doing wrong?Is any better way than this?
You asked if there is a better way...
From what I understand about the question what you are trying to do is pick a random value and then check the database to see if that value already exists. You want to return a value back to the UI to tell the UI whether the value exists or not...
Here is a couple alternatives to consider...
public static bool randomgen()
{
bool isFound = false;
string admissionNumber = "SN " + r.Next(100);
HttpContext.Current.Session["number"] = admissionNumber;
using (SqlConnection con = new SqlConnection()) // use "using" to guarantee connection is closed
{
string sql1 = "SELECT CASE WHEN EXISTS(SELECT admissionno FROM tlblstudent_details WHERE admissionno = #admissionno) THEN 1 ELSE 0 END";
using (SqlCommand cmd = con.CreateCommand())
{
cmd.CommandText = sql;
cmd.Parameters.AddWithValue("#admissionno", number);
using (SqlDataReader dr = cmd.ExecuteReader())
{
if (dr.Read())
{
isFound = (Convert.ToInt32(dr[0]) == 1)
}
}
}
}
return isFound;
}
This way you let SQL Server check to see if the value exists.
Another approach...
Not sure if you are required to prompt the user if the value is not unique, if that is not a requirement then I would consider a different approach; Keep trying until you find a unique value...Like this...
public static int randomgen()
{
bool isFound = true;
while (isFound)
{
string admissionNumber = "SN " + r.Next(100);
using (SqlConnection con = new SqlConnection()) // use "using" to guarantee connection is closed
{
string sql1 = "SELECT CASE WHEN EXISTS(SELECT admissionno FROM tlblstudent_details WHERE admissionno = #admissionno) THEN 1 ELSE 0 END";
using (SqlCommand cmd = con.CreateCommand(sql1))
{
cmd.Parameters.AddWithValue("#admissionno", admissionNumber);
using (SqlDataReader dr = cmd.ExecuteReader())
{
if (dr.Read())
{
isFound = (Convert.ToInt32(dr[0]) == 1)
}
}
}
}
return number;
}
This keeps checking until a unique value is returned. Then you return that unique value to the calling method. Now you set HttpContent.Current session from the caller, leaving the responsibility of this method to only be finding a unique Admission Number. The downside to the second approach is that it may take a long time to find a unique value, depending on how many values are already used, especially considering you are only allowing 100 values.
Hope this gives you good alternatives to consider. Let me know if you have additional questions.