Getting data from each row in a SQL Server CE database - c#

I have done this before, but for the life of me I can't remember how this worked.
I have a database that has a bunch of rows with data in them like names and ID numbers. What I need to do is populate a treeview from names in the database. I am running up against an issue just getting the reader to read multiple rows in the database. It only seems to be reading the first row and not subsequent rows. the actual task would be similar to below :
For each row in database add a parent node to treeview where the name is = to (reader[4].ToString()). That's about it. At the moment all I am trying to do is just get it to pop a messagebox showing that it's reading the multiple rows.
Please what am I missing to get this working?
SqlCeConnection conn = null;
try
{
using (conn = new SqlCeConnection("Data Source =" + ConfigurationFile + "; Password =*********"))
{
conn.Open();
SqlCeCommand cmd = conn.CreateCommand();
cmd.CommandText = "select * from t_mainprofiles";
cmd.ExecuteNonQuery();
var reader = cmd.ExecuteReader();
while (reader.Read())
{
ID = (Convert.ToInt32(reader[1]));
profileID = (Convert.ToInt32(reader[2]));
profileNAME = (reader[4].ToString().Trim());
profileLOC = (reader[5].ToString().Trim());
profileCHILD = (reader[6].ToString().Trim());
}
MessageBox.Show(profileNAME);
reader.Close();
}
}
catch(Exception error)
{
MessageBox.Show(""+error);
System.Diagnostics.Process.GetCurrentProcess().Kill();
}
finally
{
conn.Close();
}

Try removing the line cmd.ExecuteNonQuery();
Here is an example from MSDN
http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqldatareader.read(v=vs.110).aspx

Related

Show data in Textboxes from database in C#

Is there anything wrong with my code? It is not showing data in textboxes. The same funtion is working for another table in database but not for this one.
private void metroButton1_Click(object sender, EventArgs e)
{
con = new SqlConnection(constr);
String query = "Select FROM Student WHERE Std_ID = '" + metroTextBox1.Text + "'";
cmd = new SqlCommand(query, con);
con.Open();
try
{
using (SqlDataReader read = cmd.ExecuteReader())
{
while (read.Read())
{
// metroTextBox1.Text = (read["ID"].ToString());
metroTextBox2.Text = (read["Name"].ToString());
metroTextBox3.Text = (read["F_Name"].ToString());
metroTextBox4.Text = (read["Std_Age"].ToString());
metroTextBox5.Text = (read["Address"].ToString());
metroTextBox6.Text = (read["Program"].ToString());
metroComboBox1.Text = (read["Course"].ToString());
}
}
}
finally
{
con.Close();
}
}
you need to give column names in the select statement or select *
for example :
String query = "Select * from Student WHERE Std_ID = '" + metroTextBox1.Text + "'";
Not related to Question: you can change the while loop to if condition if you have one record for given id. even there are many records for given id you will see the last record data only because of the while loop will overwrite the textboxes in every record.
Update :
There isn't anything wrong with Syntax because the same syntax is
working for modifying teacher funtion.
No, this is incorrect, remove the try catch in your code then you will see the exception of syntax error

GridView issue with more than 1000 records

I'm having some performance issues when I return a record set with more than 1,000 records.
Sometimes the records are in upwards of 2,100 but can be as low as 10.
I have some bulk actions that I take on all the records by selecting them.
However, when the number is low, the Gridview is fine. When the record count is greater than 500 I see performance issues on the page.
What I want to happen is: if there are more than 500 records, DO NOT DISPLAY THE GRID, instead show a download button that exports to CSV or do other control things on the page.
My issue:
Even if i tell it not to display the grid and instead display a message and a button, the performance is still slow.
Below is my C# code for populating the GridView. Some stuff has been removed that are unimportant and to help with readability.
How can I adjust my C# code for better performance?
SqlConnection conn = new SqlConnection(ConfigurationManager.AppSettings["ConnectString"].ToString());
SqlCommand cmd = conn.CreateCommand();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "SomeProcedure";
cmd.Parameters.Add(SearchParam);
try {
DataTable GridData = new DataTable();
conn.Open();
using(SqlDataAdapter Sqlda = new SqlDataAdapter(cmd)) {
Sqlda.Fill(GridData);
}
if (GridData.Rows.Count == 0) {
lblSearchMsg.Text = "No Fee Records are in the Queue at this time.";
} else {
if (GridData.Rows.Count > 500) {
lblSearchMsg.Text = "More than " + gridLimit.ToString() + " records returned.";
//Show the download button
} else {
//Persist the table in the Session object. (for sorting)
Session["GridData"] = GridData;
lblRowCount.Text = "Count: " + GridData.Rows.Count.ToString();
myGridView.DataSource = GridData;
myGridView.DataBind();
myGridView.Visible = true;
}
}
} catch (Exception ex) {
//Do the error stuff
} finally {
if (conn != null) {
conn.Close();
}
}
Create a separate procedure that returns only the row count.
Check that value not the row count of a fully retrieved data set then retrieve the full data set as needed.
Keep in mind you can use the same connection to do both retrievals, no need to close the connection between calls.
if you determine you need to fill a gridview and there is no need to edit the data you can read into the DataTable without the use of an adapter. Here is the basic idea modify with using statements or try/catch as you prefer:
conn = new SqlConnection(connString);
string query = "SELECT * FROM ....";
SqlCommand cmd = new SqlCommand(query, conn);
conn.Open();
SqlDataReader dr = cmd.ExecuteReader();
DataTable dt = new DataTable();
dt.Load(dr);
GridView1.DataSource = dt;
GridView1.DataBind();

SQL rows are not being deleted

So I have this code that is designed to delete a row in mySQL server database judging by what is selected in my list box. Here is the code I have to remove the rows:
private void remove_btn_Click(object sender, EventArgs e)
{
try
{
if (Calls_lsb.SelectedItem == null)
MessageBox.Show("Please select an item for deletion.");
}
else
{
int i = Calls_lsb.SelectedIndex;
if (i > 0)
{
SqlConnection connection = new SqlConnection(//My Connection String);
string sqlStatement1 = "DELETE FROM Records WHERE CallID = #Id";
string sqlStatement2 = "DELETE FROM Calls WHERE CallID = #Id";
connection.Open();
SqlCommand cmd1 = new SqlCommand(sqlStatement1, connection);
cmd1.Parameters.AddWithValue("#Id", Calls_lsb.Items[i]);
cmd1.ExecuteNonQuery();
SqlCommand cmd2 = new SqlCommand(sqlStatement2, connection);
cmd2.Parameters.AddWithValue("#Id", Calls_lsb.Items[i]);
cmd2.ExecuteNonQuery();
connection.Close();
Calls_lsb.Items.Remove(Calls_lsb.Items[i]);
}
else
{
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
I get no exceptions and I have similar code that adds records that works fine. I tried stepping into the code but it all seemed fine. It simply just does not delete the row from the database. It removes the correct item from the list, just not the database.
If anyone could shine some light on this situation that would be great, thanks!
Edit : Ok, I seem to have fixed the problem. I just removed the whole i = selected index stuff and replace the 'Calls_lsb.Items[i]' with '(Calls_lsb.SelectedIndex + 1)'. I don't really understand why I was getting an exception when I tried to add 1 to i as this is basically doing the same thing.
Replace your below line code.
cmd1.Parameters.AddWithValue("#Id", Calls_lsb.Items[i]);
//with
cmd1.Parameters.AddWithValue("#Id", Calls_lsb.Items[i].Value);
and
cmd2.Parameters.AddWithValue("#Id", Calls_lsb.Items[i]);
// with
cmd2.Parameters.AddWithValue("#Id", Calls_lsb.Items[i].Value);

How to get multiple rows from access database

I am trying to store each row of a access database, based on column Veh_ID. The found data may or may not be based on multiple rows. The code I am currently using can copy single row but if there are multiple results I can only get the first result. Can anyone please help me on this? I am noob when it comes to database. I tried to search Google but no one seems to be needing what I need. Here's the code I'm using:
string cmd1 = "SELECT * FROM Veh_checkup WHERE Veh_ID = " + veh_idd + "";
OleDbCommand cmd = new OleDbCommand(cmd1, con);
OleDbDataReader read = cmd.ExecuteReader();
read.Read();
veh_id=null;
int i=0;
foreach (var a in read)
{
try
{
veh_id = veh_id + " " + read[i].ToString();
}
catch { }
i++;
}
There are a few things I would point out, some specific to your question, some not:
USE PARAMETERISED QUERIES
Use OleDbDataReader.Read() to move to the next record.
Use a StringBuilder to concatenate strings in a loop, using string = string + "something" will create a new string on the heap with each iteration
Use using blocks on Disposable objects
catch { } is not good practice. You will never know an error occurred. At the very least you should log the error somewhere so you know you need to fix something.
OleDbDataReader[i] will get the data from column i for the current record being read, not the data from row i
Don't use SELECT * in production code, especially if you are only using 1 column. It is unnecessary data retrieval from the database and also unnecessary network traffic.
USE PARAMETERISED QUERIES
Okay, I know I included using parameterised queries twice, but that is how strongly I feel about it!
With the above changes made, your full code will become something like:
static string GetStringData(string vehID)
{
StringBuilder builder = new StringBuilder();
string cmd1 = "SELECT Column1 FROM Veh_checkup WHERE Veh_ID = #VehID";
using (OleDbConnection con = new OleDbConnection("YourConnectionString"))
using (OleDbCommand cmd = new OleDbCommand(cmd1, con))
{
con.Open();
cmd.Parameters.AddWithValue("#VehID", vehID);
using (OleDbDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
builder.Append(" " + reader.GetString(0));
}
}
}
return builder.ToString();
}
You are using the datareader in a wrong way. Instead of calling it once like you do, you have to call the datareader in a while loop like this:
while(theDataReader.Read())
{
// do your stuff in a loop now
}
So using this approach in your code would look something like this:
string cmd1 = "SELECT * FROM Veh_checkup WHERE Veh_ID = " + veh_idd + "";
OleDbCommand cmd = new OleDbCommand(cmd1, con);
OleDbDataReader read = cmd.ExecuteReader();
veh_id=null;
con.Open();
while(read.Read()) //your reader
{
try
{
veh_id = veh_id + " " + read[i].ToString();
}
catch { }
}

Not getting all results from SqlDataReader

Can anybody help me with the issue I'm seeing? For some reason when I run my page, I get my drop down lists to populate the data, however the first item in my database, per each SQL query, doesn't get populated.
For example, my database table is:
Category
1 Books
2 Clothing
3 Toys
4 Household Items
my first query -
SELECT Category FROM ProductCategories
my drop down list gets populated with
Clothing
Toys
Household Items
I have 2 other drop down lists I'm populating and those are doing the same thing. Once I get this figured out, I'll try to figure out the other problem I'm having with inserting the data in the database.
Thank you!
public partial class InsertItems : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
SqlConnection connection;
SqlCommand populateList;
SqlDataReader reader;
string connectionString = ConfigurationManager.ConnectionStrings["LakerBids"].ConnectionString;
connection = new SqlConnection(connectionString);
populateList = new SqlCommand("USE LakerBids SELECT Category FROM ProductCategories;" +
"USE LakerBids SELECT SubCategory FROM ProductSubCategories;" +
"USE LakerBids SELECT LName FROM Users", connection);
if (!IsPostBack)
{
try
{
connection.Open();
reader = populateList.ExecuteReader();
while (reader.Read())
{
pcategory.DataSource = reader;
pcategory.DataValueField = "Category";
pcategory.DataBind();
}
reader.NextResult();
while (reader.Read())
{
psubcategory.DataSource = reader;
psubcategory.DataValueField = "SubCategory";
psubcategory.DataBind();
}
reader.NextResult();
while (reader.Read())
{
user.DataSource = reader;
user.DataValueField = "LName";
user.DataBind();
}
reader.Close();
}
finally
{
connection.Close();
}
}
}
protected void AddItem(object sender, EventArgs e)
{
if (Page.IsValid)
{
SqlConnection connection;
SqlCommand insertData;
string connectionString = ConfigurationManager.ConnectionStrings["LakerBids"].ConnectionString;
connection = new SqlConnection(connectionString);
insertData = new SqlCommand("INSERT INTO Products (ProductName, ProductDesc, CategoryID, SubCatID, StatusID, UserID, ReservePrice, AuctionLength, BidID)" +
"VALUES (#ProductName, #ProductDesc, #CategoryID, #SubCatID, 1, #UserID, #ReservePrice, #AuctionLength, NULL)", connection);
insertData.Parameters.Add("#ProductName", System.Data.SqlDbType.NVarChar, 50);
insertData.Parameters["#ProductName"].Value = pname.Text;
insertData.Parameters.Add("#ProductDesc", System.Data.SqlDbType.NVarChar, 200);
insertData.Parameters["#ProductDesc"].Value = pdesc.Text;
insertData.Parameters.Add("#CategoryID", System.Data.SqlDbType.Int);
insertData.Parameters["#CategoryID"].Value = pcategory.SelectedIndex;
insertData.Parameters.Add("#SubCatID", System.Data.SqlDbType.Int);
insertData.Parameters["#SubCatID"].Value = psubcategory.SelectedIndex;
insertData.Parameters.Add("#UserID", System.Data.SqlDbType.Int);
insertData.Parameters["#UserID"].Value = user.SelectedIndex + 2;
insertData.Parameters.Add("#ReservePrice", System.Data.SqlDbType.Money);
insertData.Parameters["#ReservePrice"].Value = Convert.ToDecimal(reserveprice.Text);
insertData.Parameters.Add("#AuctionLength", System.Data.SqlDbType.Int);
insertData.Parameters["#AuctionLength"].Value = Convert.ToInt32(auctionlength.Text);
try
{
connection.Open();
insertData.ExecuteNonQuery();
Response.Redirect("Categories.aspx");
}
catch (Exception error)
{
dberror.Text = error.ToString();
}
finally
{
connection.Close();
}
}
}
}
You need to either use a DataSet or populate business entities within a collection and then bind to the collection.
List<Category> cats = new List<Category>();
while (reader.Read())
{
Category cat = new Category();
// fill properties from DataReader
cats.Add(cat);
}
pcategory.DataSource = cats;
pcategory.DataValueField = "Category";
pcategory.DataBind();
Sab0tr0n, I suspect one of two things are happening.
1) If you are saying the first item does not appear AFTER you do some kind of "Add Category" action, then it might be that the dropdown is populated BEFORE the insert completes. Meaning, you need to requery after allowing the insert to be committed to the database.
OR
2) Put a breakpoint on this line:
string connectionString = ConfigurationManager.ConnectionStrings["LakerBids"].ConnectionString;
Then confirm the connectionString is to the correct database. I've seen old config files that point to test or staging databases cause this kind of confusion.
Good luck. If these aren't the answer, maybe simplify your example to us or elaborate on exactly what you do with your application and when you see the problem.
The "reader.read()" statement in each block is actually reading the first row of data, so when you set the DataSource, the first row has already been read. Try taking it out
You should use "while (reader.Read())" if you want to iterate over each result, not bind the resulset in one step.
That being said, the comments about using a Dataset, seperating logic, etc., are valid

Categories

Resources