How can I avoid duplicate items in a checkListBox - c#

I am working on my windows form application using c#. I have a checkListBox that is binded to db. I am wondering is there a way to delete any duplicate record from the database?
Here is my code
private void fill_checkListBox()
{
try
{
string query = "select * from table_1 ";
SqlCommand myTeacherCommand = new SqlCommand(query, myConn);
//reading the value from the query
dr = myCommand.ExecuteReader();
//Reading all the value one by one
teacherCB.Items.Clear();
while (dr.Read())
{
string name = dr.IsDBNull(2) ? string.Empty : dr.GetString(2);
teacherCB.Items.Add(name);
if (!checkBox.Items.Contains(name))
{
teacherCB.Items.Add(name);
}
}
dr.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}

The first answer - use DISTINCT in query:
select distinct * from table_1
Also, I advice you to specify column names in query:
select distinct ID, Name from table_1
But I don't know anything about your data in table.

Related

The specified field 'ID' could refer to more than one table

I keep getting this error when I try to find by ID:
system.data.oledb.oledbexception the speciefied field 'ID' could refer
to more than one table listed in the FROM clause of your SQL Statement
Here's my code:
public static Invoice GetInvoice(string id)
{
OleDbConnection conn = GetConnection();
Invoice invoice = null;
if (conn == null)
{
return null;
}
string sqlString = "SELECT * FROM Person INNER JOIN Employee ON " +
"Person.ID=Employee.ID WHERE ID = #ID";
OleDbCommand comm = new OleDbCommand(sqlString, conn);
comm.Parameters.AddWithValue("#ID", id);
OleDbDataReader dr = null;
try
{
conn.Open();
dr = comm.ExecuteReader(CommandBehavior.SingleRow);
if (dr.Read())
{
invoice = new Invoice();
invoice.PersonID = (string)dr["ID"];
invoice.FirstName = (string)dr["FirstName"];
invoice.LastName = (string)dr["LastName"];
invoice.Age = (int)dr["Age"];
}
}
catch (Exception ex)
{
invoice = null;
MessageBox.Show(ex.ToString());
}
finally
{
if (conn.State == ConnectionState.Open)
{
conn.Close();
}
}
return invoice;
}
You need to change your query, at the moment you're selecting a wildcard '*', which means it will pull both the Persons ID and the Employee ID, but wont have a unique reference. Change your wildcard to pull the exact tables ID like below:
SELECT Person.ID, FirstName, LastName FROM...
You will also need to change your WHERE statement to something like:
WHERE Person.ID = #ID
as the where statement doesnt know which tables ID to filter on (i know they're the same values, but SQL doesnt care about that)

Search 2 "unrelated" Access tables with button click

I have 2 tables in an Access database. Currently I have a c# winform app in VS 2015 with 2 forms that have a search button on each that will search that particular table The only similarity is the SerialNumber field but it is unrelated as the Serial Numbers for each table are for different equipment. Any tips on how to perform a search of both tables with 1 button?
private void searchItembtn_Click(object sender, EventArgs e)
{
if (!string.IsNullOrEmpty(serialSearch.Text))
{
try
{
connection.Open();
OleDbCommand command = new OleDbCommand();
command.Connection = connection;
command.Transaction = transaction;
command.Parameters.Add("#searchSerial", OleDbType.VarWChar).Value = serialSearch.Text;
string searchFB = "SELECT * FROM Inventory WHERE SerialNumber = #searchSerial";
command.CommandText = searchFB;
connection.Close();
OleDbDataAdapter db = new OleDbDataAdapter(command);
DataTable dt = new DataTable();
db.Fill(dt);
dataGridFB.DataSource = dt;
}
catch (OleDbException ex)
{
MessageBox.Show(ex.Message);
connection.Close();
}
searchHide();
connection.Close();
}
}
Create a UNION query in Access, that will contain data from both tables:
SELECT
SerialNumber,
InventoryField1 AS Field1,
InventoryFieldN AS FieldN
FROM Inventory
UNION ALL
SELECT
SerialNumber,
CompetitiveField1 AS Field1,
CompetitiveFieldN AS FieldN
FROM Competitive
Then use this query as the row source in your command (CompetitiveInventory would be the query name):
string searchFB = "SELECT * FROM CompetitiveInventory WHERE SerialNumber=#searchSerial";
Alternatively, a JOIN may be what you want, depending on the requirement.

how to generate unique max id from Data Base

I create a Applicant Registration form where Applicant Registration ID is generated by "Select Max(ID)...." Query. when this query is fetch out the MaxID from Data Base then i increment this ID by Plus one(+1) in this way i generate a Registration ID for all Applicant who register himself. But there is one problem occurred when i run my project from server and multiple clients (Approximately 10) Applicant try to Register then there is "primary key violation exception" occurred. There is 5 Insert Query is executed one-by-one after Max Query is executed
Code is Given Below
public long getUid()
{
try
{
string qry = "select isnull(max(Temp_Applicant_RegNo),0) as appregno FROM Temp_Reg";
if (cs.State == ConnectionState.Closed)
{
cs.Open();
}
cmd = new SqlCommand(qry, cs);
dr = cmd.ExecuteReader();
long cid = 0;
if (dr.Read())
{
cid = long.Parse(dr["appregno"].ToString());
cid++;
}
if (cs.State == ConnectionState.Open)
{
cs.Close();
}
return cid;
}
catch (Exception ex)
{
lbl_ErrorMsg.Text = ex.Message;
return 0;
}
}
protected void Save_btn_Click(object sender, EventArgs e)
{
SqlTransaction trn = null;
try
{
long Regid = getUid();
con.Open();
trn = con.BeginTransaction();
cmd = new SqlCommand("insert into....", con, trn);
cmd.Parameters.AddWithValue("#RegNo", Regid);
cmd.ExecuteNonQuery();
cmd = new SqlCommand("insert into....", con, trn);
cmd.Parameters.AddWithValue("#RegNo", Regid);
cmd.ExecuteNonQuery();
cmd = new SqlCommand("insert into....", con, trn);
cmd.Parameters.AddWithValue("#RegNo", Regid);
cmd.ExecuteNonQuery();
trn.Commit();
}
catch (Exception ex)
{
lbl_ErrorMsg.Text = ex.Message;
trn.Rollback();
}
}
Please give me suggestion that how can i generate Max ID for Applicant so that there is no chance to any duplication. Because i am working in live project.
for there i am using Asp.net C#
Don't do that, let the database generate the key for you when you insert a new row. Here is for example how to do it with SQL Server or MySQL. If you really want to do it on the client, use GUIDs as keys because you can generate them without consulting the database. There are some minor issues with GUIDs as keys because they are usually partially random and this may have negative performance effects on clustered indices, but for 99.9 % of all databases they are just fine.
Solution 1:
You can create a table with only one column, For example "GeneralID", and in your application control this Id to insert in another tables.
Solution 2:
Another solution is create a table and only one column, and a trigger to each table before insert to popule the id getting frmo the "Ids table" to insert.
Before we had auto incrementing columns we would have a table to hold the IDs. It would only have 2 columns IdType varchar(10) and NextId int. Then in a stored proc we would have something like:
while(1=1)
begin
select #nextId = nextId
from MyIds
where IdType=#IdType
update MyIds
set nextId = #nextId + 1
where IdType=#IdType
and nextId = #nextId
if(##ROWCOUNT > 0)
break;
end
select #nextId as nextId
Note that this would only update in the second statement if the nextId didn't change. If it did change it would try again.
I don't see when do you save the new value into Temp_Reg, but how if you save that value immediately after calculation, then you can safety update others tables:
public long getUid()
{
try
{
string qry = "select isnull(max(Temp_Applicant_RegNo),0) as appregno FROM Temp_Reg";
if (cs.State == ConnectionState.Closed)
{
cs.Open();
}
cmd = new SqlCommand(qry, cs);
dr = cmd.ExecuteReader();
long cid = 0;
if (dr.Read())
{
cid = long.Parse(dr["appregno"].ToString());
cid++;
}
UPDATE Temp_reg HERE !!!!
if (cs.State == ConnectionState.Open)
{
cs.Close();
}
return cid;
}
catch (Exception ex)
{
lbl_ErrorMsg.Text = ex.Message;
return 0;
}
}
Then you'll have to take this update into account inside the catch block of Save_btn_Click.
All of this if you can't use Autonumbers but If you can, use it.
If you could change your field Temp_Applicant_RegNo in an IDENTITY column, then you don't need to worry about the next number assigned to your table Temp_Reg. It is all a jopb made by your database.
All you need to know is what number has been assigned and use that number in your subsequent inserts.
This could be easily done using the SELECT SCOPE_IDENTITY() after the insert in your
protected void Save_btn_Click(object sender, EventArgs e)
{
SqlTransaction trn = null;
try
{
con.Open();
trn = con.BeginTransaction();
cmd = new SqlCommand("insert into....; SELECT SCOPE_IDENTITY()", con, trn);
int Regid = Convert.ToInt32(cmd.ExecuteScalar());
cmd = new SqlCommand("insert into....", con, trn);
cmd.Parameters.AddWithValue("#RegNo", Regid);
cmd.ExecuteNonQuery();
cmd = new SqlCommand("insert into....", con, trn);
cmd.Parameters.AddWithValue("#RegNo", Regid);
cmd.ExecuteNonQuery();
trn.Commit();
}
catch (Exception ex)
{
lbl_ErrorMsg.Text = ex.Message;
trn.Rollback();
}
The trick is possible adding the SELECT SCOPE_IDENTITY() as a second query to the first insert and then call ExecuteScalar. ExecuteScalar executes the queries and then returns the value of the first column in the first row of the last query executed.

check if a Name from a table is already listed in a combobox in wpf

I want to check if a Name from a table is already listed in a combobox, if so do not insert. if not insert. I have tried the following:
public void display()
{
try
{
sc.Open();
string Query = "select * from Part";
SqlCommand createCommand = new SqlCommand(Query, sc);
SqlDataReader dr = createCommand.ExecuteReader();
while (dr.Read())
{
string Name = dr.GetString(1);
if (Name != cbPartners.Text)
{
cbPart.Items.Add(Name);//Displaying a list in the Combo Box
}
else
{
cbPart.Items.Clear();
}
}
sc.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Try this ( using linq)
if (cbPart.Items.Cast<ListItem>().Select(f => f.Text).Contains(Name))
{
cbPart.Items.Add(Name);//Displaying a list in the Combo Box
}
else
...
if (cbPart.FindStringExact(Name) == -1)
{
cbPart.Items.Add(Name);
}
as side note, you don't need to select all the column, since you only need one column
string Query = "select partname from Part";
not clear why you removing all the items in else case by using cbPart.Items.Clear(); and that line will remove already existing combobox items when matching item found.

set Id equal to number contained in textbox

Hi I want to fill a combo box with names from a table where id is the number contained in textbox.The txtPartId is populated from another page as is the name in txtPart. The error I get when I run this is "Invalid column name "txtPartId"
public ReList(string Str_value, string id)//declare value
{
InitializeComponent();
txtPart.Text = Str_value;
txtPartId.Text = id.ToString();
displayRe();
}
private void displayRe()
{
try
{
sc.Open();
string Query = "select * from Re where Part_PartID =txtPartId ";
SqlCommand createCommand = new SqlCommand(Query, sc);
SqlDataReader dr = createCommand.ExecuteReader();
while (dr.Read())
{
string Name = dr.GetString(1);
cbRe.Items.Add(Name);//Displaying a list in the Combo Box
}
sc.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
The quick and dirty answer is to make the following change:
string Query = "select * from Re where Part_PartID = " + txtPartId.Text;
assuming Part_PartID is an integer.
If it is a string then you can use:
string Query = string.Format("select * from Re where Part_PartID = '{0}'", txtPartId.Text);
The compiler is not going to inject the value of the text in txtPartId into your query string for you.
However, that introduces the scope for SQL injection, so I strongly suggest you parameterize your query. There are many examples of this on SO.

Categories