OracleDataReader & datadridview list - c#

I try read data from oracle db and set data to datagridview component but I dont know where is the problem datagridview is empty, if I test reader throught while loop and get values I see all rows:
CODE:
Dbc dbc = new Dbc();
dbc.connect();
try
{
String sql = "SELECT * FROM " + _tname;
OracleCommand comm = new OracleCommand(sql, dbc.getConnection());
OracleDataReader reader = comm.ExecuteReader();
tableListhist.ColumnCount = reader.FieldCount;
for (int i = 0; i < reader.FieldCount; ++i)
{
tableListhist.Columns[i].HeaderText = reader.GetName(i).ToLower();
}
//tableListhist.DataMember = _tname;
tableListhist.DataSource = reader;
reader.Close();
tableListhist.ReadOnly = true;
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
finally
{
dbc.close();
}
But datagridview is empty :(

Usually you pass a DataTable or a DataSet as value for the DataSource property
DataTable dt = new DataTable();
dt.Load(reader);
tableListhist.DataSource = dt;

Related

How to successfully fill the datagridview - getting error invalid attempt to call read when reader is closed in C#

I need a quick help. I am getting an error invalid attempt to call read when reader is closed when trying to add my databagridview from the reader.
the databases is a class that calls the database connection string. and the databaseColumn is a class that has all columns names.
error for column Time_Completed
what is the issues please help
Here is the code:
//datagridview, bindingsource, data_apapter global objects variables
private DataGridView dataGridView = new DataGridView();
private BindingSource bindingSource = new BindingSource();
private SqlDataAdapter dataAdapter = new SqlDataAdapter();
//class objects
Databases lemars = new Databases();
Databases schuyler = new Databases();
Databases detroitlakeskc = new Databases();
public Form1()
{
InitializeComponent();
}
private void btn_Exit_Click(object sender, EventArgs e)
{
this.Close();
}
private void comboBox_Database_SelectedIndexChanged(object sender, EventArgs e)
{
if (comboBox_Database.SelectedItem.ToString() == "LeMars21St")
{
GetDataToDataGridView();
}
}
private void GetDataToDataGridView()
{
//prgBar_DataGridViewLoading
DatabaseColumns Obj = new DatabaseColumns();
String SqlcmdString = "Select * from dbo.AllInvoicesInReadyStatus";
SqlDataReader reader;
int i = 1;
try
{
using (SqlConnection conn = new SqlConnection(lemars._LeMarsConnectionString))
{
reader = null;
SqlCommand Sqlcmd = new SqlCommand(SqlcmdString, conn);
conn.Open();
reader = Sqlcmd.ExecuteReader();
if (reader.HasRows)
{
try
{
while (reader.Read())
{
Obj.Invoice = reader["invoice"].ToString();
Obj.Shipment = reader["shipment"].ToString();
Obj.Project = reader["Project"].ToString();
Obj.InvoiceDateTB = Convert.ToDateTime(reader["invoiceDateTB"]);
Obj.CreatedDate = Convert.ToDateTime(reader["CreatedDate"]);
Obj.TypeName = reader["typeName"].ToString();
Obj.ExportedDate = Convert.ToDateTime(reader["exportedDate"]);
Obj.StatusName = reader["statusName"].ToString();
Obj.Total = Convert.ToDecimal(reader["total"]);
Obj.ImportStatus = reader["import_status"].ToString();
//DateTime dateFacturation;
int colIndex = reader.GetOrdinal("Time_Completed");
if (!reader.IsDBNull(colIndex))
Obj.TimeCompleted = reader.GetDateTime(colIndex);
Obj.ErrorDescription = reader["ERROR_DESCRIPTION"].ToString();
//bindingSource.DataSource = reader;
DataTable dt = new DataTable();
dt.Load(reader);
dataGridView.DataSource = dt;
i++;
}
}
finally
{
reader.Close();
}
conn.Close();
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
}
DataTable.Load method automatically closes currently running DataReader instance, hence it will fail at the next iteration (the exception clearly said that the DataReader is already closed).
To fix this issue, call DataTable.Load immediately after ExecuteReader (i.e. after checking by HasRows) and you can iterate DataTable contents from that, as given in example below:
using (SqlConnection conn = new SqlConnection(lemars._LeMarsConnectionString))
{
reader = null;
SqlCommand Sqlcmd = new SqlCommand(SqlcmdString, conn);
conn.Open();
reader = Sqlcmd.ExecuteReader();
if (reader.HasRows)
{
try
{
DataTable dt = new DataTable();
dt.Load(reader);
for (int i = 0; i < dt.Rows.Count; i++)
{
Obj.Invoice = dt.Rows[i]["invoice"].ToString();
Obj.Shipment = dt.Rows[i]["shipment"].ToString();
Obj.Project = dt.Rows[i]["Project"].ToString();
// other stuff
}
dataGridView.DataSource = dt;
}
finally
{
conn.Close();
}
}
}
Update 1:
Since one of your datetime column may contain DBNull.Value, you can check using either Convert.IsDBNull:
for (int i = 0; i < dt.Rows.Count; i++)
{
if (!Convert.IsDBNull(dt.Rows[i]["Time_Completed"]))
{
Obj.TimeCompleted = Convert.ToDateTime(dt.Rows[i]["Time_Completed"]);
}
}
Or with is operator with DBNull:
for (int i = 0; i < dt.Rows.Count; i++)
{
if (!(dt.Rows[i]["Time_Completed"] is DBNull))
{
Obj.TimeCompleted = Convert.ToDateTime(dt.Rows[i]["Time_Completed"]);
}
}
Alternatively you can use ternary operator and set DateTime.MinValue if the column has null value.
Related issues:
Error: Invalid attempt to call Read when reader is closed after the while loop?
C# - Invalid attempt to call Read when reader is closed

Null Value appear in DataGridView in after new column added

My Datagridview have one name column. I am trying to add one image column with that datagridview. Once I add the image column it made that name column as null. Please refer the below code:
public void call(string usr)
{
user = usr;
queryString = "select NAME 'Name' from ADK_MY_PRODSYSSECGROUP";
try
{
specdataadapter = new SqlDataAdapter(queryString, con);
specds = new DataSet();
con.Open();
specdataadapter.Fill(specds, "REPORT_Table");
dgvdisp.DataSource = specds;
dgvdisp.DataMember = "REPORT_Table";
dgvdisp.Columns[dgvdisp.ColumnCount - 1].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
con.Close();
if (user == "Secgrp")
{
DataGridViewImageColumn set = new DataGridViewImageColumn();
set.Name = "set";
set.HeaderText = "Settings";
dgvdisp.Columns.Insert(1, set);
for (int rows = 0; rows < dgvdisp.Rows.Count; rows++)
{
MessageBox.Show(dgvdisp.Rows[rows].Cells[0].Value.ToString());
}
}
}
catch (Exception ex)
{
DispMessageBox disp = new DispMessageBox("Fail to retrieve data. Please try again");
disp.ShowDialog();
}
}
public void calling()
{
SqlConnection con = new SqlConnection(connetionString);
for (int rows = 0; rows < dgvdisp.Rows.Count; rows++)
{
SqlCommand command = new SqlCommand("select SETTINGS from ADK_MY_PRODSYSSECGROUP where NAME='" + Convert.ToString(dgvdisp.Rows[rows].Cells[0].Value) + "'", con);
con.Open();
SqlDataReader reader = command.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
if (reader.GetInt32(0) == 1)
{
Image image = Properties.Resources.start;
//set.Image = image;
dgvdisp.Rows[rows].Cells["set"].Value = image;
}
if (reader.GetInt32(0) == 0)
{
Image image = Properties.Resources.finish;
//set.Image = image;
dgvdisp.Rows[rows].Cells["set"].Value = image;
}
}
}
reader.Close();
con.Close();
}
}
Here in the call method, dgvdisp datagridview shows the value, But when I tried to get the value from calling method, the datagridview shows null value when I retrieve name field.
Please suggest...

Firebird dataReader

I would like to see all of the data with column names in my logfile.
private static void ExecuteSQL()
{
string conn = "User ID=SYSDBA;Password=masterkey;Database=XX.18.137.XXX:C:/ER.TDB;DataSource==XX.18.137.XXX;Charset=NONE;";
FbConnection myConnection = new FbConnection(conn);
FbDataReader myReader = null;
string sql = "SELECT * FROM RDB$RELATIONS";
FbCommand myCommand = new FbCommand(sql, myConnection);
try
{
myConnection.Open();
myCommand.CommandTimeout = 0;
myReader = myCommand.ExecuteReader();
while (myReader.Read())
{
// Log.WriteLog(myReader["rdb$relation_name"].ToString());
}
myConnection.Close();
}
catch (Exception e)
{
Log.WriteLog(e.ToString());
}
}
Right now it's only showing me the rdb$relation_name column.
I want to check the different tables for which I don't have the column's name.
All you need to do is iterate over all fields printing their names before iterating the results:
private static void ExecuteSQL()
{
string conn = "User ID=SYSDBA;Password=masterkey;Database=XX.18.137.XXX:C:/ER.TDB;DataSource==XX.18.137.XXX;Charset=NONE;";
FbConnection myConnection = new FbConnection(conn);
FbDataReader myReader = null;
string sql = "SELECT * FROM RDB$RELATIONS";
FbCommand myCommand = new FbCommand(sql, myConnection);
try
{
myConnection.Open();
myCommand.CommandTimeout = 0;
myReader = myCommand.ExecuteReader();
// 1. print all field names
for (int i = 0; i < myReader.FieldCount; i++)
{
Log.WriteLog(myReader.GetName(i));
}
// 2. print each record
while (myReader.Read())
{
// 3. for each record, print every field value
for (int i = 0; i < myReader.FieldCount; i++)
{
Log.WriteLog(myReader[i].ToString());
}
}
myConnection.Close();
}
catch (Exception e)
{
Log.WriteLog(e.ToString());
}
}
I am pretty sure, that this will give ugly output as it prints every output to a new line. You should be able to change this to print the fields and each record in rows.
public static List<string> GetColumnNames(string queryString)
{
string result = string.Empty;
List<string> listOfColumns = new List<string>();
try
{
using (FbConnection conn = new FbConnection(connString))
{
conn.Open();
using (FbCommand cmd = new FbCommand(queryString, conn))
{
// Call Read before accessing data.
FbDataReader reader = cmd.ExecuteReader();
if (reader.FieldCount > 0)
{
for (int i = 0; i < reader.FieldCount; i++)
{
listOfColumns.Add(reader.GetName(i));
}
}
}
}
}
catch (Exception e)
{
BinwatchLogging.Log(e);
}
return listOfColumns;
// return result;
}
where querystring is your query (eg: select * from yourtablename) and connstring is your firebird connectionstring

Update sql database using dataset

I need some help to complete this. I have searched and tried several ways but is not enetring in my head yet. It is not homework! I am a self learner.
I managed to populate a grid selecting the table from a dropdown:
private void radDropDownList1_SelectedIndexChanged(object sender, Telerik.WinControls.UI.Data.PositionChangedEventArgs e)
{
if (radDropDownList1.SelectedIndex > 0)
{
radGridView1.Visible = true;
label8.Text = radDropDownList1.SelectedValue.ToString();
DataTable dt = new DataTable();
var selectedTable = radDropDownList1.SelectedValue; //Pass in the table name
string query = #"SELECT * FROM " + selectedTable;
using (var cn = new SqlConnection(connString))
{
cn.Open();
try
{
SqlCommand cmd = new SqlCommand(query, cn);
using (var da = new SqlDataAdapter(cmd))
{
da.Fill(dt);
}
}
catch (SqlException ex)
{
//MessageBox.Show(ex.StackTrace);
}
}
radGridView1.DataSource = dt;
}
Now I am trying to write the event to update the sql table using the grid as datasource:
private void radGridView1_CellEndEdit(object sender, Telerik.WinControls.UI.GridViewCellEventArgs e)
{
DataTable dt = (DataTable)radGridView1.DataSource;
DataSet ds = new DataSet();
ds.Tables[0] = dt;
try
{
//**I am lost here!**
}
catch
{
}
}
Could you please help? How can I now update the sql table?
I don't really like the way you are managing the updates but... this code here will send an update statement:
using (var cn = new SqlConnection(connString))
{
cn.Open();
try
{
SqlCommand cmd = new SqlCommand("UPDATE YourTable SET Column = #Parm1 WHERE Col = #Parm2", cn);
var parm1 = cmd.CreateParameter("Parm1");
parm1.Value = "SomeValue";
var parm2 = cmd.CreateParameter("Parm2");
parm2.Value = "SomeOtherValue";
cmd.Parameters.Add(parm1);
cmd.Parameters.Add(parm2);
int rowsAffected = cmd.ExecuteNonQuery();
}
catch (SqlException ex)
{
//MessageBox.Show(ex.StackTrace);
}
}

listView Problem in C#

I have a problem in listview.I my listview i have five columns(question_number,question_text,start_time,end_time,status). the first four columns will be fetch the data from the database.once the data has entered i have to compare the starttime and with the current time.once the starttime is greater than current time then i have to update the status column as expired. otherwise i have to say not expired.
I have attached the code what i did so for.
I do no how to get the status updated in the status column.Please any one help me.thanks in advance.
public void GetData()
{
try
{
myConnection = new SqlConnection(#"User ID=sa;Password=password123;Initial Catalog=dish;Persist Security Info=True;Data Source=ENMEDIA-CCDDFE5\ENMEDIA");
//myConnection.Open();
//SqlDataReader dr = new SqlCommand("SELECT question_text,question_id FROM otvtbl_question ", myConnection).ExecuteReader();
// listView1.Columns.Clear();
listView1.Items.Clear();
myConnection.Open();
String MyString1 = string.Format("SELECT question_id,question_text,start_time,end_time FROM otvtbl_question");
SqlCommand cmd = myConnection.CreateCommand();
cmd.CommandText = MyString1;
dr = cmd.ExecuteReader();
//Adding The Column Name From The DataBase
for (int i = 0; i < dr.FieldCount; i++)
{
ColumnHeader ch = new ColumnHeader();
ch.Text = dr.GetName(i);
//listView1.Columns.Add(ch);
}
ListViewItem itmX;
//Adding the Items To The Each Column
while (dr.Read())
{
itmX = new ListViewItem();
itmX.Text = dr.GetValue(0).ToString();
for (int i = 1; i < dr.FieldCount; i++)
{
itmX.SubItems.Add(dr.GetValue(i).ToString());
}
listView1.Items.Add(itmX);
}
dr.Close();
myConnection.Close();
}
catch (Exception ex)
{
//Error Message While Fetching
MessageBox.Show("Error While Fetching the data From the DataBase" + ex);
}
finally
{
//Closing The Connection
if (dr != null)
dr.Close();
if (myConnection.State == ConnectionState.Open)
myConnection.Close();
}
Something like this?
while (dr.Read())
{
...
listView1.Items.Add(itmX);
if (dr.GetDateTime(2) > dr.GetDateTime(3))
{
itmX.SubItems.Add("Expired");
}
}

Categories