private void Filtriraj()
{
string filter = string.Empty;
if (txtID.Text.Length > 0)
{
filter = "ID LIKE '%" + txtID.Text + "%'";
}
if (txtName.Text.Length > 0)
{
filter = "Name LIKE '%" + txtName.Text + "%'";
}
}
I want to search thru ms access db tables in my c# app. The one above is connected to "Table1" that has some fields like ID, name, surname, address...ID type is set to autonumber, all others are to text. I'm able to search all fields except by ID, this way above wont work, i get exception when i try to search by ID (I type in txtbox some ID number that is in db, exmp: '1')
Search by txtName is working fine.
Autonumber is some form of number (long I think) so you can't use the LIKE keyword. You must search for an exact match (or greather than, less than etc.). You also can't surround a number with single quotes, so those will need to be removed.
I'd switch your code to something like this:
.
.
.
if (txtID.Text.Length > 0)
{
int id;
if (Int32.TryParse(txtID.Text, out id))
{
filter = "ID = " + id.ToString();
}
}
.
.
.
Also, your code looks like it may not work properly if you have multiple text boxes filled with data (because you are not using else if). Whatever text box you check last will end up being the filter that gets used because you're reassigning the filter variable each time. And if you're using the filter text directly from the text boxes, you're opening yourself up to possible SQL Injection. You should probably look into using parameterized queries.
Related
I have a 'DataTable' populated with items from a SqlServer table. There are two columns in the 'DataTable': 'id' which is the identity value for the row in the SqlServer table and 'job' which is the name of an object.
I have a database client written in 'C#' using the '.Net' framework. It contains a 'ListBox', a 'TextBox', a 'DataTable', and a 'DataView'. The 'DataView' 'DataSource' is set to the 'DataTable'. The 'ListBox' 'DataSource' is set to the 'DataView'. There are 1700 rows in the table.
My preferred method of finding the correct item is for the user to begin to type in the textbox and as with each letter the list diminishes until the user can easily spot the desired one. The user can then double click on it and some action is taken. I have used this technique with 'BindingSource' and it works well. I am having trouble using with the 'DataView'. The first two letters the user types work well. But when the third letter is typed, the 'ListBox' goes blank, even though the filter string is correct. Why does it stop working with the third letter? Any help would be appreciated.
This is a sample of the data in the field 'job': '08-CBM-01 -- Water Utilities Topo Survey'
The data in the field 'id' is just an 'int' identity from SqlServer.
I've tried examining the variable strLookup and strFilter as entry is made using the keyboard and it appears these are correct.
DataTable tblSelectList;
DataView dvSelectList;
private string strFilter = "";
private string strLookup = "";
private void tbLookup_TextChanged(object sender, EventArgs e)
{
strLookup = tbLookup.Text.ToString();
if (strLookup.Length > 1)
{
strFilter = "job Like '%" + strLookup + "%'";
dvSelectList.RowFilter = strFilter;
}
else { dvSelectList.RowFilter = "job = 'z'"; }
btnDone.Enabled = false;
}
private void SetupLbSelect()
{
if (dvSelectList == null) { dvSelectList = new DataView(tblSelectList); }
lbSelect.DataSource = dvSelectList;
dvSelectList.RowFilter = "job = 'z'";
lbSelect.DisplayMember = "job";
lbSelect.ValueMember = "id";
}
No error messages. The ListBox begins to populate as expected with the 1st two characters and then goes blank with the third. I would expect to type 'Topo' and have all the items containing 'Topo' appear.
I deleted the procedure and several others from the code page and typed them in again. After that the function worked as expected. Thank you to LarsTech who told me the original code worked for him.
So i'm making a library system, and i encounter a problem in my Borrowing and Returning of books.
When i borrow a book then return it changing the status to return, then borrowing that same book again success, then when i'm returning it my trapping for return books message show.
sql = "SELECT * FROM tbltransactionbooks WHERE fBarCodeNo LIKE '" + txtBARCODE_R.Text.Trim() + "%'";
cfgotcall.engageQuery(sql);
if (cfgotcall.tbl.Rows[0]["fStatus"].ToString().Equals("Borrowed"))
{
txtTITLE_R.Text = cfgotcall.tbl.Rows[0]["fBookTitle"].ToString();
txtAUTHOR_R.Text = cfgotcall.tbl.Rows[0]["fAuthor"].ToString();
txtYEAR_R.Text = cfgotcall.tbl.Rows[0]["fBookYr"].ToString();
txtACCNO_R.Text = cfgotcall.tbl.Rows[0]["fAccNo"].ToString();
txtCALLNO_R.Text = cfgotcall.tbl.Rows[0]["fCallNo"].ToString();
txtBARCODE_BR.Text = cfgotcall.tbl.Rows[0]["fBarcodeNo"].ToString();
txtSEARCH.Text = cfgotcall.tbl.Rows[0]["fStudent"].ToString();
txtReturnDate.Text = cfgotcall.tbl.Rows[0]["fBorrowDate"].ToString();
txtIDNO.Text = cfgotcall.tbl.Rows[0]["fIDStudent"].ToString();
txtLEVEL.Text = cfgotcall.tbl.Rows[0]["fLevel"].ToString();
}
else
{
MessageBox.Show("Book already returned.");
}
What i debug in my own code in the pic is it doesn't scan the whole rows in the tbltransactionbooks it only reads the first row of my table.
33 123 NAME IT 2/20/2017 2/20/2017 [HISTORY OF] COMPUTERS: THE MACHINES WE THINK WITH Returned
33 123 NAME IT 2/21/2017 2/21/2017 [HISTORY OF] COMPUTERS: THE MACHINES WE THINK WITH Borrowed
![2]: http://i66.tinypic.com/28ajgwg.jpg
How dow I scan the whole rows in my table? If my code above does not look good I'm open in suggestion of how I am able make it clean. thanks
cfgotcall.tbl.Rows[0] refers to the the first row only.
You should iterate each row:
sql = "SELECT * FROM tbltransactionbooks WHERE fBarCodeNo LIKE '" + txtBARCODE_R.Text.Trim() + "%'";
cfgotcall.engageQuery(sql);
foreach(var row in cfgotcall.tbl.Rows)
{
if (row["fStatus"].ToString().Equals("Borrowed"))
{
txtTITLE_R.Text = row["fBookTitle"].ToString();
txtAUTHOR_R.Text = row["fAuthor"].ToString();
txtYEAR_R.Text = row["fBookYr"].ToString();
txtACCNO_R.Text = row["fAccNo"].ToString();
txtCALLNO_R.Text = row["fCallNo"].ToString();
txtBARCODE_BR.Text = row["fBarcodeNo"].ToString();
txtSEARCH.Text = row["fStudent"].ToString();
txtReturnDate.Text = row["fBorrowDate"].ToString();
txtIDNO.Text = row["fIDStudent"].ToString();
txtLEVEL.Text = row["fLevel"].ToString();
}
else
{
MessageBox.Show("Book already returned.");
}
}
To avoid getting run time errors due to typos in the column names and the SQL query, you can use LINQ to SQL or Entity Framework. This way each row is converted to an object and you can access each column by accessing an object property\field.
The first row is checked because use access only the first row:
if (cfgotcall.tbl.Rows[0]...)
To check all the rows, iterate through the cfgotcall.tbl.Rows collection either using the for or foreach loop.
You are only accessing the first row [0] of the table. You need to itterate through all of them using for or foreach loop.
Side note: I guess this is a homework. It will not do you any good if you find complete solution in the internet. You should rather try to understand how collections/arrays work and how to traverse them using loops.
A couple of tutorials to help you with the task:
https://msdn.microsoft.com/en-us/library/aa288462(v=vs.71).aspx
http://csharp.net-informations.com/collection/csharp-collection-tutorial.htm
I know this is very basic, but I can't seem to get it right. I have this datatable that I will fill with processed information from my database.
After searching if the EmpRequestID has already been added in the Datatable, I want to be able to get the value of the column named "RequestedEmp" of the returned row and check if already contains the initials that my variable is currently hosting (it is in a loop). If it does not, append the initials in the variable in the existing initials in the row.
DataRow[] MyEmpReq_Row = MyEmpRequests_DataTable.Select("EmpRequestID='" + EmpRequestID + "'");
int SameReqID = MyEmpReq_Row.Length;
if (MyEmpReq_Row > 0) //REQ ID IN DT, MULTIPLE EMP 1 REQUEST
{
//INSERT HERE
}
else //ID NOT IN DT YET
{
MyEmpRequests_DataTable.Rows.Add(EmpRequestID, ActionBy, Requested_Initials, DateSubmitted, RequestStatus);
}
I want to be able to do something like this
string RetrievedInitials = MyEmpReq_Row["RequestedEmp"].ToString();
if (RetrievedInitials LIKE '%" + Requested_Initials + "'") // but if statements doesnt have LIKE
or this and then know if the column contains the value or not.
MyEmpReq_Row.Select("RequestedEmp LIKE '%" + Requested_Initials + "'");
if (RetrievedInitials.Contains(Requested_Initials))
Take a look at the string class:
http://msdn.microsoft.com/en-us/library/system.string.aspx
As already mentioned by some other posters, the Contains() method may be of use. However, you should also look at EndsWith() (which is more in line with your use of the wildcard in your LIKE query) and StartsWith().
Example:
if (RetrievedInitials.EndsWith(Requested_Initials))
string filter = string.Empty;
if (checkboxBalkon.Checked== true)
{
filter = "Balkon LIKE '%" + checkboxBalkon.Checked + "%'"; //???
}
I have search form. The code above is supposed to print down all fields from table that has checkbox checked. I compare it, but i don't know how to print it? I need some bool? How to do it?
I believe the answer you are looking for is something like this:
filter = "Balkon = " + checkboxBalkon.Checked;
I have a ListBox called listbox. Its "multiple selection" property is set to true. I need to store the selections from this ListBox into a database field.
Note that I am using web forms, ASP.NET, C#, and Visual Studio Web Developer 2010 Express.
My code is as follows:
SqlCommand insertNL = new SqlCommand("insert into dbo.newsletter (newsletter_subject,newsletter_body,newsletter_sentto) VALUES ('" + TextBox1.Text + "', '" + TextBox2.Text + "', '" + ListBox1.SelectedItem + "')", badersql);
badersql.Open();
insertNL.ExecuteNonQuery();
badersql.Close();
Unfortunately, this code only stores the first selected value of the ListBox in the "newsletter_sentto" column of my newsletter table. Does anyone have any suggestions as to how to fix this code? Thanks in advance.
Things to fix:
Before doing anything else, parameterize your sql. This is ripe for injection. Tutorial here.
You aren't disposing of your cmd or connection string. Wrap those in Using clauses. Example here.
Do a foreach on the items to see which ones are selected. Either store those in a comma separated list in the database (which needs parsing on the way back out) or store them in their own table.
You need to decide how you want to store the multiple "newsletter_sentto" values first.
You're best solution is to create a new child table where you have 1 row and column per selected item, with a foreign key back to your newsletter table.
You can try to store them all together in one row with multiple columns (sentto1, sentto2, etc), this will limit the max number of values you can store, and will cause problems searching across multiple fields. How will you query what was sent to a particular person? WHERE sentto1=#user or sentto2=#user... no index can be used there.
You can stuff all the value in a single row and column using a "," or ";" to separate the values. this will cause many problems because you'll have to constantly split the string apart, every time you need to get at one of the sentto values.
First, you should use parametrized queries instead of straight concatenation to protect against SQL injection. Second, you need to cycle through the selected items and build (presumably) a delimited-list of the selections.
var selectedItems = new List<string>();
foreach( var item in ListBox1.SelectedItems )
selectedItems.Add( item.ToString() );
var sql = "Insert dbo.newsletter(newsletter_subject,newsletter_body,newsletter_sentto)"
+ " Values(#newsletter_subject, #newsletter_body, #newsletter_sentto)"
badersql.Open();
using ( qlCommand = new SqlCommand(sql, badersql) )
{
qlCommand.Parameters.AddWithValue("#newsletter_subject", TextBox1.Text);
qlCommand.Parameters.AddWithValue("#newsletter_body", TextBox2.Text);
qlCommand.Parameters.AddWithValue("#newsletter_sentto", string.Join(',', selectedItems.ToArray()));
qlCommand.ExecuteNonQuery();
};
Try to get selected items like that :
string newsletterSentTo = "";
foreach (ListItem item in ListBox1.Items)
{
if (item.Selected)
newsletterSentTo += "," + item.Text;
}