I have used this code to display the employee's first name and last name from the provided database when an employee id number is typed into the text box and the “Find” button is clicked. But I will also need Previous and Next Button to display previous and next records respectively in textbox as well. Is there a method like MovePrevious and MoveNext sth to get it?
Here is my code :
private void button1_Click(object sender, EventArgs e)
{
string constr = #"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\\CCEMPLOYEE.mdb";
OleDbConnection con = new OleDbConnection(constr);
{
using (OleDbCommand cmd = new OleDbCommand("SELECT emp_fname, emp_lname, emp_mi FROM Employee WHERE emp_id =#ID "))
{
if (idText.Text != "")
{
cmd.Parameters.AddWithValue("#ID", int.Parse(idText.Text));
cmd.CommandType = CommandType.Text;
cmd.Connection = con;
con.Open();
using (OleDbDataReader sdr = cmd.ExecuteReader())
{
try
{
sdr.Read();
fnameText.Text = sdr["emp_fname"].ToString();
lnameText.Text = sdr["emp_lname"].ToString();
miText.Text = sdr["emp_mi"].ToString();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
else
{
MessageBox.Show("You did not enter any ID", "Enter the ID ",
MessageBoxButtons.OK);
}
con.Close();
}
}
}
You won't be able to go Next or Previous in your provided code because you only have one record in your recordset.
You will also have the problem that you haven't specified the basis for what "Previous" and "Next" mean, the framework has no idea that you mean next by emp_id (or do you mean next by alphabetical surname?)
I would suggest your Prev and Next buttons need to be aware of what "this" record is, and use that as a parameter to run a similar piece of code when they are clicked. You could add an int property to your class, have the Find button store the emp_id into that property, and then have the Next and Prev buttons call almost identical code except with the SQL adjusted to something like "SELECT TOP 1 emp_fname, emp_lname, emp_mi FROM Employee WHERE emp_id > #ID ORDER BY emp_id ASC" (note I don't have anything on me to test this at the moment, you might need to sort DESC).
The reason I've suggested TOP 1, > and ORDER By is I don't know if you have a guarantee that you have sequential emp_id - obviously if you know they're sequential and can guarantee that always you could just go "SELECT... WHERE emp_id = #ID-1" for Prev...
This answer is academic, not practical, I don't suggest this is a good solution to a production scenario - it's an answer to your question.
Related
I got a gridview which is connected to a datasource getting values from there.I created a selectedindexchanged function to work when select is clicked.it shows ID , orderID,From,To and Price values and opens panel which has 4 textbox's and a dropdownlist if user wants to change those values.Everything is fine until here.When user changes some values and clicks submit nothing changes in database.I got the values using id ; " string id = orderGrid.SelectedRow.Cells[1].Text; "
here is my submit button code ;
protected void submitButton_Click(object sender, EventArgs e)
{
string id = orderGrid.SelectedRow.Cells[1].Text;
OleDbConnection con = new OleDbConnection(#"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + Server.MapPath("db.mdb") + ";Persist Security Info=False");
string query = "update ordersTable set orderID=#testID,fromLocation=#from,toLocation=#to,price=#price WHERE ID = #id ";
OleDbCommand cmd = new OleDbCommand(query, con);
cmd.Parameters.AddWithValue("#id", id);
cmd.Parameters.AddWithValue("#testID", orderBox.Text);
cmd.Parameters.AddWithValue("#from", fromText.Text);
cmd.Parameters.AddWithValue("#to", toList.SelectedItem.Text);
cmd.Parameters.AddWithValue("#price", priceBox.Text);
try
{
con.Open();
cmd.ExecuteNonQuery();
con.Close();
Response.Write("Edit Complete !");
}
catch (Exception ex)
{
Response.Write("Error : " + ex);
}
orderGrid.DataBind();
}
id string works perfectly fine in my selectedindexchanged function.
In OleDb parameters are recognized by their position not by their name.
Your parameter placeholder #ID is the last one in the query, but you add it as the first one in the collection.
This result in your WHERE condition to be totally wrong
(you search for a record whose ID is equal to the content of the priceBox)
Just move the insert of the ID as last parameter
cmd.Parameters.AddWithValue("#testID", orderBox.Text);
cmd.Parameters.AddWithValue("#from", fromText.Text);
cmd.Parameters.AddWithValue("#to", toList.SelectedItem.Text);
cmd.Parameters.AddWithValue("#price", priceBox.Text);
cmd.Parameters.AddWithValue("#id", id);
This is the primary problem, but I can see another one caused by your use of AddWithValue. This is an handy shortcut, but sometime it make you pay for it.
In your case, you pass to the #price parameter a string and, if your price field is a decimal (as it should be) then the database engine will attempt a conversion from a string to a decimal and if the decimal separator is not the same you end with a wrong value in the database. Better check the value in the priceBox and convert it yourself to a decimal.
See Can we stop to use AddWithValue already?
I am having an issue with the increment for the ID. The ID would increase by one every time I click insert, but the problem occurs when the ID 2, it would insert the values twice, if ID 3, it would insert the values three times, and so on.
There are couple of options that I have been trying. One is Max and the other one is finding the last inserted value and add one to the ID just.
I would appreciate if anyone can help me out with this. Thanks
public partial class LoginInfo : System.Web.UI.Page
{
static string myConnectionString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
private void GenerateID()
{
SqlConnection myConnection = new SqlConnection(myConnectionString);
string myQuery1 = "Select Count(S_ID) from Student_Name";
SqlCommand cmd = new SqlCommand(myQuery1, myConnection);
myConnection.Open();
int addOneS_ID_Table1 = Convert.ToInt32(cmd.ExecuteScalar());
myConnection.Close();
addOneS_ID_Table1++;
lblstdID.Text = addOneS_ID_Table1.ToString();
myConnection.Open();
cmd.CommandText = "Select Count(P_ID) from Student_Pass";
int addOneP_ID_Table2 = Convert.ToInt32(cmd.ExecuteScalar());
myConnection.Close();
addOneP_ID_Table2++;
lblstdPass.Text = addOneP_ID_Table2.ToString();
/*-----------------------------------------------------------------*/
//SqlConnection myConnection = new SqlConnection(myConnectionString);
//SqlCommand cmd = new SqlCommand("SELECT MAX(S_ID) as max_S_ID from Student_Name",myConnection);
//cmd.CommandType = CommandType.Text;
//myConnection.Open();
//lblstdID.Text = Convert.ToString(cmd.ExecuteScalar());
//cmd.CommandText = "SELECT MAX(P_ID) as max_P_ID FROM Student_Pass";
//lblstdPass.Text = Convert.ToString(cmd.ExecuteScalar());
//myConnection.Close();
}
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
GenerateID();
}
}
protected void btnInsert_Click(object sender, EventArgs e)
{
SqlConnection myConnection = new SqlConnection(myConnectionString);
string myQuery = "Insert into Student_Name(S_ID,STUDENT_NAME) VALUES" + "(#S_ID,#STUDENT_NAME)";
SqlCommand cmd = new SqlCommand(myQuery,myConnection);
cmd.Parameters.Add("#S_ID", SqlDbType.Int).Value = lblstdID.Text;
cmd.Parameters.Add("#STUDENT_NAME", SqlDbType.VarChar).Value = txtstdName.Text;
if(myConnection.State == ConnectionState.Closed)
{
myConnection.Open();
}
cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
//Second Table
cmd.CommandText = "Insert into Student_Pass(P_ID,PASSWORD) VALUES" + "(#P_ID,#PASSWORD)";
cmd.CommandType = CommandType.Text;
cmd.Parameters.Add("#P_ID", SqlDbType.Int).Value = lblstdPass.Text;
cmd.Parameters.Add("#PASSWORD", SqlDbType.VarChar).Value = txtStdPass.Text;
cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
myConnection.Close();
GenerateID();
lblResult.Text = "Successfully Saved";
GridView1.DataBind();
}
}
Problem is with your query since you are getting COUNT(S_ID) which is going to get you count of records doesn't necessarily will give exact ID number. You should rather try MAX(S_ID) or ORDER BY clause saying
Select MAX(S_ID) from Student_Name
(OR)
Select TOP 1 S_ID from Student_Name ORDER BY S_ID DESC;
But recommended, You should actually go with SQL Server ##IDENTITY or SCOPE_IDENTITY() to get the last inserted record ID (assuming that S_ID is an IDENTITY column)
It's highly recommended to not use max or top in order to determine the "next" identifier to use, simply because of the cost associated with it.
However, there are some other pitfalls to using max and top especially if there is a chance that nolock is used (which is a whole other conversation). I've seen a lot of web applications use max and has proven to be a performance killer.
Rahul is right, ##identity or scope_identity are good alternatives. However, I think this calls for using a native SQL Server sequence, which was introduced in SQL Server 2012. It was something that application developers have been waiting for and Microsoft finally delivered.
The issue with using ##identity or scope_identity is that you actually have to write rows to some table before you can even contemplate doing something.
This makes it a bit more costly and messier than what it may need to be. In the case of using a sequence, you can issue a new sequence number and then decide what to do and once you decide what to do you're still guaranteed that you're the only one with that sequence number.
You would create a sequence like this. You should check out the documentation as well.
create sequence dbo.StudentIdSeq
as int -- this can be any integer type
start with 1 -- you can start with any valid number in the int, even negative
increment by 1;
go
Then you issue new sequence numbers by doing this ...
select next value for StudentIdSeq;
It may still be good to create a stored procedure with an output parameter that you can call from C# (which is what I would do). In fact you may want to take it a step further, in the case that you have a bunch of sequences, and create a slick stored procedure that will get a new sequence based on the type that is being requested from the caller.
This code is supposed to save some values in textboxes to a specific row. The code runs just fine with no hiccups, but refuses to actually update the database no matter what I do.
try
{
using (var con = new OleDbConnection())
{
con.ConnectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\User\Desktop\esoft\gym\gym\bin\Debug\Clients.accdb;";
con.Open();
using (var com = new OleDbCommand())
{
com.Connection = con;
com.CommandText = "UPDATE gym SET BMI = #bmi and Health = #health and weight_change_to_healthy_bmi = #weight WHERE ID = #id";
com.Parameters.AddWithValue("#bmi", bmi.Text);
com.Parameters.AddWithValue("#health", health.Text);
com.Parameters.AddWithValue("#weight", change.Text);
com.Parameters.AddWithValue("#id", id.Text);
com.ExecuteNonQuery();
}
}
MessageBox.Show("Saved");
}
catch (Exception ex)
{
MessageBox.Show("Not saved: " + ex.Message);
}
Any help would be much appreciated.
As Alex mentioned, SET part needs , instead of AND for multiple columns.
Check UPDATE syntax1;
UPDATE table_name
SET column1=value1,column2=value2,...
WHERE some_column=some_value;
But I wanna say a few things more;
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.
Open your connection just before you execute your command. That means, you should open your connection just before your ExecuteNonQuery line.
Based on it's name, ID column should be some numeric value instead of character. Consider to change it's type or consider to change it's column name that refers some character typed column name.
1: I know I know.. a w3school link
I am new to this sql replication. We have 4 subscribers. I have one column in one of the table has unique key. the data type is nvarchar. if subscriberA inserts a row with 'zxc' and subscriber B inserts a row with 'zxc'. One of the insert fails. how can i handle this in the application show the user proper message to the users.
For example I have Two Subscribers:
1.SubA
2.SubB
I have a table.
Table name : Names
I have City column(nvarchar) in my Names table and it is unique key.
User 'A' connects to SubA.
user 'B' connects to SubB.
'A' inserts a row with 'JAKARTA' in to Names table # 10:30 am. It will take 20 min to update the publisher.
'B' inserts a row with 'JAKARTA' in to Names table #10:35 am.
I have the unique constraint on the table so User A's input is updated in the publisher #10:50.
But user B's input caught in the conflicts.
I want the city column should be unique across all the subs.
How could i handle this? How should i display proper message for user B? How should i do validation across all the subscribers?
My application is winforms. I am using textbox for city.
I am validating on button click event. Ideal solution will be if i can able to capture this in click event
and display Message like "One record already exist with this name.try again."
private int Validation( string str)
{
SqlConnection conn = new SqlConnection("ConnectionString");
conn.Open();
SqlCommand cmd = new SqlCommand("SELECT COUNT(*) FROM dbo.Names where city = #str", conn);
cmd.Parameters.Add("#City", SqlDbType.VarChar, 100);
cmd.Parameters["#City"].Value = str;
int count = (Int32) cmd .ExecuteScalar();
conn.Close();
return count;
}
private void button1_Click(object sender, System.EventArgs e)
{
try
{
if(Validation(testbox1.text) == 0)
{
SqlConnection conn = new SqlConnection("ConnectionString");
string sql = "INSERT INTO dbo.Names ( city) VALUES( #City)";
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.Parameters.Add("#City", SqlDbType.VarChar, 100);
cmd.Parameters["#Name"].Value = textbox1.text;
cmd.ExecuteNonQuery();
}
else
{
//display message
}
}
catch(Exception ex)
{
}
}
Let me know if you need more information
This is an application/database design issue. In this case the first subscriber to synchronize their local copy of the Names table with the publication server wins and the second will get an error. The best solution is to avoid collisions altogether and add another column as part of the unique key (subscriber id?) which will make the record unique or just remove the unique constraint altogether and have a server process cull the duplicate city names later if needed.
I am pretty new in C# and I'm making a program where the user can add a Network provider and reload. I already did the Add, Edit, Delete Network but I don't know on how to to the Reload Part where I need to get the current value of the load from the DB and add (addition) it to the new amount.
Example: Current balance = 12 and Reload = 35 --> Current Balance = 47
By the way, I am using MS Access.
Feel like I'm taking risk to answer your question but anyway..
Since we have no idea what is your desing and code looks like but I suggest to use UPDATE statement.
Here it's syntax;
UPDATE table_alias
SET expression
WHERE <search_condition>
For your case, it can be like;
UPDATE YourTableName
SET Current_balance = Current_balance + 35
WHERE <search_condition>
This query adds 35 to your Current_balance column where you specified search condition in your table.
Of course, we could be more helpful if we see your desing and code..
The user inputs the amount in the textbox. I'm doing it on Windows
Forms Application.
Let's try to write an example like this;
string s = TextBox1.Text;
int i;
if(Int32.TryParse(s, NumberStyles.Integer, CultureInfo.InvariantCulture, out i))
{
using(SqlConnection con = new SqlConnection("YourConnectionString"))
{
using(SqlCommand cmd = new SqlCommand())
{
cmd.CommandText = "Update TableName SET Current_balance = Current_balance + #p";
cmd.Connection = con;
cmd.Parameters.AddWithValue("#p", i);
con.Open();
cmd.ExecuteNonQuery();
}
}
}
else
{
//TextBox string is not a valid integer.
}