Reputation: 147
I'm using this code to select the maxID from a database table and each time I want to add a new record, the autogenerated ID is not the last one +1.
public formularAddCompanie()
{
InitializeComponent();
try
{
string cs = "Data Source=CODRINMA\\CODRINMA;Initial Catalog=TrafficManager;Integrated Security=True";
string select = "SELECT max(IDCompanie) FROM Companii";
using (SqlConnection con = new SqlConnection(cs))
{
con.Open();
SqlCommand cmd2 = new SqlCommand(select, con);
SqlDataReader sda = cmd2.ExecuteReader();
DataTable idmax = new DataTable("idmax");
idmax.Load(sda);
if (idmax.Rows[0][0].ToString().Trim() == "") { txtID.Text = "1"; }
else { txtID.Text = (int.Parse(idmax.Rows[0][0] .ToString() + 1).ToString()); }
}
}
catch (Exception er) { MessageBox.Show(er.Message); }
}
The table from where the selection is made, looks like this:
IDCompany Name Address City RegNo
1 A Street NY 123
Each time I want to add a new record, the autogenerated ID is like this: 11, 111, 1111. It takes the last ID and add another 1 next to it. What am I missing?
Upvotes: 0
Views: 7063
Reputation: 55
Try This one, my id format is USR001.The code will generate auto id based on the last id inside the database. If the last id in the database is USR001, the the code will generate USR002 and put the id to the textbox
con.Open();
string sqlQuery = "SELECT TOP 1 kode_user from USERADM order by kode_user desc";
SqlCommand cmd = new SqlCommand(sqlQuery, con);
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
string input = dr["kode_user"].ToString();
string angka = input.Substring(input.Length - Math.Min(3, input.Length));
int number = Convert.ToInt32(angka);
number += 1;
string str = number.ToString("D3");
txtKodeUser.Text = "USR" + str;
}
con.Close();
Upvotes: 0
Reputation: 216273
I just add this because it seems that none cares about the weakness of the code posted by the poster. First the MAX function is not reliable if you want to find the next autoincrement value that will be assigned to an ID column. Concurrency could wreak havoc with any schema that use MAX. Just suppose that another user has already retrieved the MAX for its own INSERT operation, then depending on the relative speed of the two computers you or the other user will insert a duplicate value for the IDCompany field.
The only correct way to do this common task is to use the IDENTITY property for the column IDCompany and when you need to insert a new record you should write something like this
try
{
string insert = "INSERT INTO Companii (Name,Address,City,RegNo)
VALUES(@name,@address,@city,@regno);
SELECT SCOPE_IDENTITY()";
using (SqlConnection con = new SqlConnection(cs))
using (SqlCommand cmd = new SqlCommand(insert, con))
{
con.Open();
cmd.Parameters.Add("@name", SqlDbType.NVarChar).Value = txtBoxCity.Text;
.... and on for the other parameters ....
int companyID = Convert.ToInt32(cmd.ExecuteScalar());
... work with the just added company if required
}
}
catch (Exception er)
{ MessageBox.Show(er.Message); }
SCOPE_IDENTITY will return the last identity value inserted into an identity column in the same scope and in this context scope means the connection used by your command.
In any case, if the MAX approach is still required then the code could be simplified a lot using a modified query and SqlCommand.ExecuteScalar instead of building an SqlDataReader, filling a datatable, trying to parse the result with ifs
string getMax = @"select COALESCE(MAX(IDCompany), 0) + 1 AS maxPlusOne
from Companii"
using(SqlConnection cnn = new SqlConnection(.....))
using(SqlCommand cmd = new SqlCommand(getMax, cnn))
{
cnn.Open();
int nextCompanyID = Convert.ToInt32(cmd.ExecuteScalar());
}
The COALESCE function checks the result of the MAX function and if it is NULL returns the second parameter (here 0), then just increment by 1 to get the next MAX directly from the database. ExecuteScalar will do the call returning just the maxPlusOne
alias field
Upvotes: 0
Reputation: 150108
Interestingly, note that
string a = "The meaning of life is " + 42;
converts 42 to a string, creating the result
a == "The meaning of life is 42"
Look at this code:
(int.Parse(idmax.Rows[0][0] .ToString() + 1).ToString()); }
You are converting idmax.Rows[0][0] to a string and adding +1 to the end of the string rather than to an integer value. Try
(int.Parse(idmax.Rows[0][0].ToString()) + 1).ToString(); }
Note that idmax.Rows[0][0]
should already have an integer in it (as pointed out in the comments). If that's the case, you can simplify to
(idmax.Rows[0][0] + 1).ToString(); }
Upvotes: 2
Reputation: 10285
try this snippet:
Convert Your String
into Int
. String
with +
operator will con-cat and with int
it will add numbers.
if (idmax.Rows[0][0].ToString().Trim() == "") { txtID.Text = "1"; }
else {
txtID.Text = Convert.ToString(Convert.ToInt32(idmax.Rows[0][0] .ToString())+1); }
Upvotes: 0
Reputation: 4862
idmax.Rows[0][0].ToString() + 1
produces string
, not int
.
You can try
txtID.Text = (Convert.ToInt32(idmax.Rows[0][0]) + 1).ToString();
Upvotes: 2