below is the code I wrote to fill dropdown list from the database,and I am not getting where I did mistake..help me in finding out and correcting my mistake.
void filldistrict()
{
DropDownList4.Items.Clear();
DropDownList4.Items.Add("--District--");
String q="select * from DLIST";
SqlCommand cmd=new SqlCommand(q,cn);
SqlDataReader rec = cmd.ExecuteReader();
if (rec.Read())
DropDownList4.Items.Add(rec.getValue(1).ToString);
rec.Close();
}
Your code is very close - the only problem is this line:
if (rec.Read())
You can also use new ListItem() when adding to the Items collection. You can use the overload that takes two strings that will set the text and the value, as well.
That will only get the first row of the returned records, not all of them. What you want is to loop through the records in rec, like this:
void filldistrict()
{
DropDownList4.Items.Clear();
DropDownList4.Items.Add("--District--");
String q="select * from DLIST";
SqlCommand cmd=new SqlCommand(q,cn);
using (SqlDataReader rec = cmd.ExectueReader())
{
while (rec.Read())
{
DropDownList4.Items.Add(new ListItem(rec.GetValue(1).ToString()));
}
}
}
Note that I used a using block with the reader so its automatically closed while the block is exited. I would also suggest doing the same with your SqlConnection.
The alternative provided by Ali is also a valid approach.
SqlConnection sql_cnt=new SqlConnection("connectionString");
SqlCommand sql_cmd=new SqlCommand("select * from DLIST",sql_cnt);
Dataset dt_data=new Dataset();
SqlDataAdapter sql_adp=new SqlDataAdapter(cmd);
try
{
sql_cnt.Open();
sql_adp.Fill(dt_data);
sql_cnt.Close();
}
catch(Exception err)
{
//Do something;
}
DropDownList4.ValueMember="the name of the field which you want to be shown in dropdown list";
DropDownList4.DataSource=dt_data;
Related
I want to search data from another SQL Server table (Stocks_Item) to this form (IC) dataGridView1, I can view that data (from Stocks_Item) in this dataGridView1 but I couldn't search. Please help me.
Here is my code:
private void button5_Click(object sender, EventArgs e)
{
conn.Close();
try
{
conn.Open();
SqlCommand selectCommand = new SqlCommand("Select * from Stocks_Item where Stock_No = #Stocks_no", conn);
selectCommand.Parameters.Add(new SqlParameter("Stocks_no", txtsearch_stock_no.Text.ToString()));
SqlDataReader reader = selectCommand.ExecuteReader();
bool rowFound = reader.HasRows;
SqlDataAdapter data = new SqlDataAdapter("Select * from Stocks_Item", conn);
DataTable dt = new DataTable();
data.Fill(dt);
dataGridView1.DataSource = dt;
/* SqlDataAdapter sda;
DataTable dt1;
sda = new SqlDataAdapter("select * FROM colombo_branch ",conn);
dt1 = new DataTable();
sda.Fill(dt1);
dataGridView.DataSource = dt1;*/
MessageBox.Show("Search Found", "Form", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
conn.Close();
}
There are many flaws in your code, but the one that is specifically causing your error is because you are not properly closing the SqlDataReader here:
SqlDataReader reader = selectCommand.ExecuteReader();
bool rowFound = reader.HasRows;
As a result, the following line, which also attempts to open a data reader internally throws the exception:
data.Fill(dt);
Normally, you want to use a SqlDataReader inside a using block, something like:
bool rowFound;
using(SqlDataReader reader = selectCommand.ExecuteReader())
{
rowFound = reader.HasRows;
}
... to ensure proper and timely disposal. But in this case, I fail to see the point of that block of code anyways. So why not just remove it altogether?
Additional comments:
Avoid global connections. The fact that the method begins by closing the connection is not a good sign.
Always use using blocks around your SqlConnection, SqlCommand, SqlDataReader, SqlDataAdapter, etc... instances to make sure you don't run into these types of errors or leak resources.
I believe that SqlDataAdapter opens/closes a connection for you. Since you're doing that earlier in your code and using a reader against it, that would be the cause. You could use either the reader or the adapter, but typically wouldn't want to mix them in one connection without properly closing/disposing.
FYI, the MSDN SqlDataAdapter code example utilizes this auto open/close behavior of SqlDataAdapter
I am currently working on a college assignment in which I am having trouble reading data from a SQL Server database. I'm attempting to read the Dentist Name column and then add these names to a combobox.
However when I input the column name it shows an error.
My table is called dentistInfo with columns Dentist ID, Dentist Name, Dentist Surname, DOB and Gender.
Eventually when I get to the reading done correctly I will then hopefully be able to populate their details when the names are selected from the combobox.
public partial class Dentist_Info : Form
{
Surgery mySurgery = new Surgery();
private SqlConnection conn;
private SqlCommand cmd;
private SqlDataAdapter da;
Surgery _formsSurgery;
public Dentist_Info(Surgery SurgeryToDisplay)
{
_formsSurgery = SurgeryToDisplay;
}
public void FillCombo()
{
SqlConnection conn = new SqlConnection(#"Data Source = GGJG; Initial Catalog = DentistDB; Integrated Security = True");
SqlCommand SelectCommand = new SqlCommand("SELECT * FROM DentistInfo", conn);
SqlDataReader myreader;
conn.Open();
try
{
myreader = SelectCommand.ExecuteReader();
while (myreader.Read())
{
string dname = myreader.GetString("Dentist Name");
comboBox1.Items.Add(dname);
}
conn.Close();
}
catch (Exception ex)
{
throw new Exception(ex.Message, ex);
}
finally
{
if (conn != null)
{
conn.Close();
}
}
}
Pro-tip: If you want to ask about an error, post the error.
In any case, the problem is easy to spot in this case. There's no overload of GetString that accepts a string as an argument - you can only use the column index.
So either you need to pass the column index (myreader.GetOrdinal("Dentist Name")) or you need to use the indexer ((string)myreader["Dentist Name"]). In either case, make sure to handle possible NULL values properly - data reader simply throws an exception if you try to read an SQL NULL value.
As an aside, your try...catch can be simplified (and more useful):
When you want to rethrow an exception, use throw; (no "argument"). Wrap the exception only if you have some information to add.
The catch clause isn't required. It seems that you're only using it for the finally - it's perfectly fine to just use try...finally without the catch.
conn can never be null in the finally clause - your try isn't long enough.
For a pattern like this, you want to use using instead of try...finally anyway. You should also use using for the data reader.
Try this: I recommend you putting [] in the Dentist Name since it has a space between the two words, which might cause you the error, or change the name from the Database to DentistName
public void FillCombo()
{
SqlConnection conn = new SqlConnection(#"Data Source = GGJG; Initial Catalog = DentistDB; Integrated Security = True");
SqlCommand SelectCommand = new SqlCommand("SELECT * FROM DentistInfo", conn);
conn.Open();
DataSet ds = new DataSet();
SqlDataAdapter da = new SqlDataAdapter(SelectCommand);
da.fill(ds);
foreach(DataRow dr in ds.Tables[0].Rows)
{
comboBox1.Items.Add(dr["[Dentist Name]"].ToString());
}
conn.Close();
}
As per addition instead of using conn.Open() and conn.Close(), as the answer of the first user you can surround the connection inside a using like so:
using(SqlConnection conn = new SqlConnection(#"Data Source = GGJG; Initial Catalog = DentistDB; Integrated Security = True"))
{
//your codes here no need for conn.Open() and conn.Close()
}
I've been squeezing my mind trying to figure out why my code isn't working.
I am trying to read from a DataSet that filled with data from access database and insert the data into an Oracle database which is created previously.
When I try the following code it won't work and although I use the try and catch block, when debugging it would freeze and won't show me any error.
if can see that I have commented out the block just right above my foreach loop..which works perfectly, Any help from you is so much appreciated :
private void button3_Click(object sender, EventArgs e)
{
string query1 = "Select * from Test;";
string StrQuery= "Insert Into TEST (ID, DATA) Values (:ID, :DATA)";
Conn = new OleDbConnection(connStr);
Conn.Open();
using (OleDbConnection connection1 = new OleDbConnection(connStr))
{
using (OleDbDataAdapter adapter1 = new OleDbDataAdapter(query1, connection1))
{
DataSet ds1 = new DataSet();
adapter1.Fill(ds1);
// no need for refilling DataGridView1.DataSource = ds.Tables[0]
// insterting the dataset into oracle
try
{
using (OracleConnection connect = new OracleConnection(oradb1))
{
connect.Open();
using (OracleCommand comma = new OracleCommand(StrQuery, connect))
{
/*comma.Parameters.Add(new OracleParameter(":ID", 2));
comma.Parameters.Add(new OracleParameter(":DATA", 2));
comma.ExecuteNonQuery();*/
foreach (DataRow drRow in ds1.Tables[0].Rows)
{
for (int i = 0; i < ds1.Tables[0].Columns.Count; i++)
{
comma.Parameters.Add(new OracleParameter(":ID", drRow[i]));
comma.Parameters.Add(new OracleParameter(":DATA", drRow[i]));
comma.ExecuteNonQuery();
}
}
connect.Close();
connect.Dispose();
}
}
}
catch (OracleException)
{
System.Diagnostics.Debugger.Break();
}
catch (System.Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
Conn.Close();
}
You are looping columns but adding the drRow[i] as values in the parameters.
I do not think this is what you intended.
skip the columns loop and add the first column value to id and second column value to data.
that should be what you wanted.... if not then describe a bit more...
Expanding on Judgemaik's answer, I believe you need to do something like this instead (can't really tell what the names of the columns in your access table are but you get the idea:
foreach (DataRow drRow in ds1.Tables[0].Rows)
{
comma.Parameters.Add(new OracleParameter(":ID", drRow["IDColumnFromAccessDB"]));
comma.Parameters.Add(new OracleParameter(":DATA", drRow["DATAColumnFromAccessDB"]));
comma.ExecuteNonQuery();
}
A similar approach is outlined in my answer here. In that particular case I was moving data from SQL Server Compact into Access, but the same idea could very well be used to move data between any two OleDb data sources.
It uses an OleDbDataAdapter to pull the source table into a DataTable, copies it over to another DataTable, and then uses another OleDbDataAdapter to update the corresponding table in the destination database.
I want to ask more to show data from SQL Server to WinForm using a datagrid.
I've been creating a datagrid and the stored procedure to show data is
ALTER PROC [dbo].[SP_GetData]
AS
SELECT nama , nim
FROM tabledata
and I've created the function to access the database and the stored procedure in C#
string Sp_Name = "dbo.SP_GetData";
SqlConnection SqlCon = new SqlConnection("Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=DBMahasiswa;Data Source=.");
SqlCon.Open();
SqlCommand SqlCom = new SqlCommand(Sp_Name , SqlCon);
SqlCom.CommandType = CommandType.StoredProcedure;
List<mahasiswaData> listMahasiswa = new List<mahasiswaData>();
using (SqlDataReader sqlDataReader = SqlCom.ExecuteReader())
{
if (sqlDataReader.HasRows)
{
while (sqlDataReader.Read())
{
mahasiswaData DataMhs = new mahasiswaData();
DataMhs.Nama = sqlDataReader["Name"].ToString();
DataMhs.Umur = Convert.ToInt32(sqlDataReader["Age"]);
listMahasiswa.Add(DataMhs);
}
}
}
SqlCon.Close();
return listMahasiswa;
and finally, in the show button I add this code
dgvmahasiswa.DataSource = new MahasiswaDB().LoadMahasiswa();
Could somebody tell me where the fault is or the alternatives one?
Thank You So Much! :D
Some things to think about:
At the moment, if your code runs into exceptions, you'll leave a
SqlConnection hanging around; you've used the using pattern for your
SqlDataReader; you should extend it to all of your disposable
objects.
You are swallowing exceptions; if your query fails, the connection
cannot be made, or something else happens, you'll never really know - your function will just return null.
Is it possible for name or age to be null? Age to be non-numeric?
There's no test for any unexpected values, which you'll also never
know about.
If you don't have any records, you'll return an empty list. Is this
desired? Or would you prefer to know there were no records?
You might prefer to look at something like this:
public List<mahasiswaData> GetData(){
List<mahasiswaData> gridData = new List<mahasiswaData>();
try{
using(SqlConnection conn = new SqlConnection("Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=DBMahasiswa;Data Source=."))
{
using(SqlCommand command = new SqlCommand())
{
command.Connection = conn;
command.CommandType = CommandType.StoredProcedure;
command.Text = "dbo.SP_GetData";
using(SqlDataReader reader = command.ExecuteReader())
{
if(reader.HasRows){
while(reader.Read())
{
object rawName = reader.GetValue(reader.GetOrdinal("Name"));
object rawAge = reader.GetValue(reader.GetOrdinal("Age"));
if(rawName == DBNull.Value || rawAge == DBNull.Value)
{
//Use logging to indicate name or age is null and continue onto the next record
continue;
}
//Use the object intializer syntax to create a mahasiswaData object inline for simplicity
gridData.Add(new mahasiswaData()
{
Nama = Convert.ToString(rawName),
Umur = Convert.ToInt32(rawAge)
});
}
}
else{
//Use logging or similar to record that there are no rows. You may also want to raise an exception if this is important.
}
}
}
}
}
catch(Exception e)
{
//Use your favourite logging implementation here to record the error. Many projects use log4Net
throw; //Throw the error - display and explain to the end user or caller that something has gone wrong!
}
return gridData;
}
Note that if you are sure that age or name will never be null then you can simplify the middle section:
while (reader.Read())
{
//Use the object intializer syntax to create a mahasiswaData object inline for simplicity
gridData.Add(new mahasiswaData()
{
Nama = reader.GetString(reader.GetOrdinal("Name")),
Umur = reader.GetInt32(reader.GetOrdinal("Age"))
});
}
I am trying to read from datareader but i am gettin the error "Invalid attempt to call Read when reader is closed." The stored procedure is working fine but when i try to read fom datareader it throws error.Plz help me
protected void CheckDatabase()
{
SqlConnection conn = new SqlConnection(GetConnectionString());
conn.Open();
SqlParameter[] param = new SqlParameter[2];
param[0]= new SqlParameter("#EmpID", SqlDbType.Int);
param[0].Value = txtEmpId.Text;
param[1]= new SqlParameter("#Date", SqlDbType.VarChar,50);
param[1].Value = txtDate.Text;
SqlDataReader reader = DNDatabase.ExecuteStoredProcedureReader("RetrieveDeatails", param);
while (reader.Read())
{
gridConfirm.DataSource = reader;
gridConfirm.Columns[0].Visible = false;
gridConfirm.DataBind();
Session["Task_List"] = reader;
}}
here is stored Procedure code
public static SqlDataReader ExecuteStoredProcedureReader(string procedureName, SqlParameter[] parameters)
{
SqlConnection _conn = new SqlConnection(DNDatabase.SQLConnectionString);
SqlCommand cmd = new SqlCommand(procedureName, _conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = procedureName;
cmd.CommandTimeout = 300;
try
{
foreach (SqlParameter param in parameters)
{
cmd.Parameters.Add(param);
}
_conn.Open();
return cmd.ExecuteReader(CommandBehavior.CloseConnection);
}
catch (Exception sqlExc)
{
throw new Exception("An error occured", sqlExc);
}
finally
{
if (_conn != null)
_conn.Close();
}
}
This looks like a bad idea to me:
Session["Task_List"] = reader;
You execute that and then call reader.Read() again, continuing until there's nothing left to read. Presumably you also close the reader at some point (I'd hope - ideally with a using statement). Fundamentally, a SqlDataReader is a connected resource - it's like a stream to the database. It's not something you should be holding onto for longer than you need to, and it's certainly not something you should be putting in a session, even if you didn't effectively invalidate it with the subsequent Read() call.
I assume that data binding works by fetching the data when you call DataBind(), but there's no indication of what you're trying to achieve by putting a reference to the reader itself into the session.
I suggest that:
You isolate whether this is actually to do with the session or the databinding
If it's the session, you pull all of the data you need out (e.g. into a DataTable or some other "disconnected" form)
If it's the databinding, you'll need to do something similar - but as I say, you can hope that that's not the problem, to start with - I assume you saw this sort of databinding elsewhere?
Additionally, you should consider why you want to loop - currently you're basically going to loop over all the results and only the last one is going to be displayed (because you're overwriting the databinding each time). Is that really what you want?
check DNDatabase.ExecuteStoredProcedureReader code may it close the reader after fetchdata
and another thing i should say is:
you can'nt use Session["Task_List"] = reader; because reader is forwardonly
and if you want to keep current value of reader in a seesion load in data table and keep data row of table
DataTable dt = new DataTanle();
dt.Load(dr);
and loop over data table rows
Your method ExecuteStoredProcedureReader has a finally statement which closes the connection. Hence you cannot read anything from the reader. Either close the reader in your method where you call ExecuteStoredProcedureReader or merge both the methods to have them in a single method.