Firebird dataReader - c#

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

Related

SQLDataReader bugging while using .Nest() or .Read()

I'm retrieving some information from an MSSQL via SQLDataReader, but while debugging it I notice in some cases the reader clears the result view with the error "Enumeration yielded no results" see the screenshot Before Running passing Read(),
After passing read()
this is my code,the error happens on getActiveUsers() method.
getDatabases() works just fine. could someone help me? cheers
public partial class automation : System.Web.UI.Page
{
SqlConnection con;
static List<ActiveUsers> activeUsers = new List<ActiveUsers>();
protected void Page_Load(object sender, EventArgs e)
{
ASPxGridView1.DataSource = activeUsers.ToList();
}
public List<ActiveUsers> getDatabases()
{
//passing query
string SqlQuery = "SELECT [WorkspaceName],[MaConfig_Customers].Name FROM [MaConfig_CustomerDatabases] INNER JOIN [MaConfig_Customers] ON [MaConfig_CustomerDatabases].CustomerId = [MaConfig_Customers].CustomerId where [MaConfig_Customers].Status = 0";
//creating connection
string sqlconn = ConfigurationManager.ConnectionStrings["MaxLiveConnectionString"].ConnectionString;
con = new System.Data.SqlClient.SqlConnection(sqlconn);
var cmd = new SqlCommand(SqlQuery, con);
con.Open();
SqlDataReader reader = cmd.ExecuteReader();
List<ActiveUsers> results = new List<ActiveUsers>();
if (reader.Read())
{
while (reader.Read())
{
ActiveUsers company = new ActiveUsers();
company.DatabaseName = String.Format("{0}", reader["WorkspaceName"]);
company.ClientName = String.Format("{0}", reader["Name"]);
results.Add(company);
}
}
con.Close();
return results;
}
public void getActiveUsers()
{
activeUsers.Clear();
List<ActiveUsers> Databases= getDatabases();
SqlConnection conn = new SqlConnection();
string SqlQuery = "select [disabled], [ADMN_Users1].[Record_Id] ,[ADMN_Users].[User_Id] from admn_Users1 inner join [ADMN_Users] on [ADMN_Users1].[record_Id] = [ADMN_Users].[Record_Id] Where [disabled] & 0x2 = 0 ";
for (int i = 0;i < Databases.Count;i++)
{
conn.ConnectionString =
"Data Source=MAXSQLCLUS01;" +
"Initial Catalog=" + Databases[i].ToString()+";"+
"User id=sa;" +
"Password=Max1m1zer;";
var cmd = new SqlCommand(SqlQuery, conn);
conn.Open();
SqlDataReader reader = cmd.ExecuteReader();
int NumberOfUsersCounter = 0 ;
//TODO Select Enabled users
if (reader.Read())
{
while (reader.Read())
{
string user = String.Format("{0}", reader["User_Id"]);
//logic to remove system users
if (user.Equals("master", StringComparison.CurrentCultureIgnoreCase))
{
}
else
if (user.Equals("emailuser", StringComparison.CurrentCultureIgnoreCase))
{
}
else
if (user.Equals("webuser", StringComparison.CurrentCultureIgnoreCase))
{
}
else
{
NumberOfUsersCounter++;
}
}
ActiveUsers newEntry = new ActiveUsers();
newEntry.NumberActiveUsers = NumberOfUsersCounter.ToString();
newEntry.DatabaseName = Databases[i].DatabaseName.ToString();
newEntry.ClientName = Databases[i].ClientName.ToString();
activeUsers.Add(newEntry);
}
conn.Close();
//Add to ActiveUsers list
}
ASPxGridView1.AutoGenerateColumns = true;
ASPxGridView1.DataSource = activeUsers.ToList();
ASPxGridView1.DataBind();
}
protected void ASPxButton1_Click(object sender, EventArgs e)
{
getActiveUsers();
}
protected void btnExportExcel_Click(object sender, EventArgs e)
{
ASPxGridView1.DataBind();
ASPxGridViewExporter1.Landscape = true;
ASPxGridViewExporter1.FileName = "User Count Report";
ASPxGridViewExporter1.WriteXlsToResponse();
}
}
}
if (reader.Read())
{
while (reader.Read())
{
ActiveUsers company = new ActiveUsers();
company.DatabaseName = String.Format("{0}", reader["WorkspaceName"]);
company.ClientName = String.Format("{0}", reader["Name"]);
results.Add(company);
}
}
use this
if (reader.HasRows)
{
while (reader.Read())
{
ActiveUsers company = new ActiveUsers();
company.DatabaseName = String.Format("{0}", reader["WorkspaceName"]);
company.ClientName = String.Format("{0}", reader["Name"]);
results.Add(company);
}
}
your if Condition is wrong
if(reader.Read()) ==> is Wrong
Read() is not return boolean Value
use HasRows to check rows in SQLDataReader
You are skipping the first result. if (reader.Read()) { while(reader.Read()) {.... Remove the enclosing if, all it does is see if there is a row and retrieve it but then you do not read it, instead you do it again in the if so the first result is always discarded.
public List<ActiveUsers> getDatabases()
{
//passing query
string SqlQuery = "SELECT [WorkspaceName],[MaConfig_Customers].Name FROM [MaConfig_CustomerDatabases] INNER JOIN [MaConfig_Customers] ON [MaConfig_CustomerDatabases].CustomerId = [MaConfig_Customers].CustomerId where [MaConfig_Customers].Status = 0";
//creating connection
string sqlconn = ConfigurationManager.ConnectionStrings["MaxLiveConnectionString"].ConnectionString;
using(con = new System.Data.SqlClient.SqlConnection(sqlconn))
using(var cmd = new SqlCommand(SqlQuery, con))
{
con.Open();
using(SqlDataReader reader = cmd.ExecuteReader())
{
List<ActiveUsers> results = new List<ActiveUsers>();
while (reader.Read())
{
ActiveUsers company = new ActiveUsers();
company.DatabaseName = reader.GetString(0);
company.ClientName = reader.GetString(1);
results.Add(company);
}
}
}
return results;
}
Side notes:
company.DatabaseName = String.Format("{0}", reader["WorkspaceName"]) would be better written as company.DatabaseName = reader.GetString(0). The same goes for the next line. No need to use string.Format and you are specifying the columns and order in the query so use the ordinal index so get the native value.
I would recommend you wrap the SqlConnection and SqlDataReader in using blocks to ensure they are closed/disposed after use even in the event of an exception.

ProductInsert() does not exist in current context

protected void Btn_CheckOut_Click(object sender, EventArgs e)
{
int result = 0;
Payment user = new Payment(txt_CardNumber.Text, txt_CardHolderName.Text, txt_ExpirationDate.Text, txt_Cvv.Text);
result = ProductInsert();
/* Session["CardNumber"] = txt_CardNumber.Text;
Session["CardHolderName"] = txt_CardHolderName.Text;
Session["ExpirationDate"] = txt_ExpirationDate.Text;
Session["Cvv"] = txt_Cvv.Text;*/
Response.Redirect("Payment Sucessful.aspx");
}
public int ProductInsert()
{
int result = 0;
string queryStr = "INSERT INTO CustomerDetails(CardNumber, CardHolderName, ExpirationDate, Cvv)"
+ "values (#CardNumber,#CardHolderName, #ExpirationDate, #Cvv)";
try
{
SqlConnection conn = new SqlConnection(connStr);
SqlCommand cmd = new SqlCommand(queryStr, conn);
cmd.Parameters.AddWithValue("#CardNumber", this.CardNumber);
cmd.Parameters.AddWithValue("#CardHolderName", this.CardHolderName);
cmd.Parameters.AddWithValue("#ExpirationDate", this.ExpirationDate);
cmd.Parameters.AddWithValue("#Cvv", this.Cvv);
conn.Open();
result += cmd.ExecuteNonQuery(); // Returns no. of rows affected. Must be > 0
conn.Close();
return result;
}
catch (Exception ex)
{
return 0;
}
}
}
I am trying to store credit card informations into database. I have created a productInsert() method and now I am trying to insert whatever values into the database.
This code is giving the error:
ProductInsert() does not exist in current context

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

C# - Populating a List with data from a database

I have a List (listOfQuestionIDs) stored in ViewState of 10 different numbers and an int counter (questionCounter) stored in ViewState which I intend to use to access the different numbers in the first list.
However, as I increment the value of ViewState["questionCounter"] by 1 the contents of listOfAnswerIDs and listOfAnswers remain exactly the same in the code below. Why is this?
protected void getAnswers()
{
string connStr = ConfigurationManager.ConnectionStrings["myConnectionString"].ConnectionString;
MySqlConnection conn = new MySqlConnection(connStr);
MySqlDataReader reader;
List<int> listOfQuestionIDs = (List<int>)(ViewState["listOfQuestionIDs"]);
int questionCounter = Convert.ToInt32(ViewState["questionCounter"]);
List<string> listOfAnswerIDs = new List<string>();
List<string> listOfAnswers = new List<string>();
List<string> listOfCorrectAnswerIDs = new List<string>();
try
{
conn.Open();
string cmdText = "SELECT * FROM answers WHERE question_id=#QuestionID";
MySqlCommand cmd = new MySqlCommand(cmdText, conn);
cmd.Parameters.Add("#QuestionID", MySqlDbType.Int32);
cmd.Parameters["#QuestionID"].Value = Convert.ToInt32(listOfQuestionIDs[questionCounter]);
reader = cmd.ExecuteReader();
while (reader.Read())
{
listOfAnswerIDs.Add(reader["answer_id"].ToString());
listOfAnswers.Add(reader["answer"].ToString());
if (reader["correct"].ToString().Equals("Y"))
{
listOfCorrectAnswerIDs.Add(reader["answer_id"].ToString());
}
}
for (int i = 0; i < listOfAnswerIDs.Count; i++)
{
lblTitle.Text += listOfAnswerIDs[i].ToString();
}
reader.Close();
populateAnswers(listOfAnswerIDs.Count, listOfAnswers, listOfAnswerIDs);
}
catch
{
lblError.Text = "Database connection error - failed to read records.";
}
finally
{
conn.Close();
}
ViewState["listOfQuestionIDs"] = listOfQuestionIDs;
ViewState["listOfCorrectAnswerIDs"] = listOfCorrectAnswerIDs;
}
Here's where I increment the questionCounter:
protected void btnNext_Click(object sender, EventArgs e)
{
.........
getNextQuestion();
}
protected void getNextQuestion()
{
int questionCounter = Convert.ToInt32(ViewState["QuestionCounter"]);
..........
getAnswers();
................
questionCounter += 1;
ViewState["QuestionCounter"] = questionCounter;
}
ViewState keys are case sensitive. In getAnswers() you use "questionCounter" and in getNextQuestion() you use "QuestionCounter". Pick one and keep it consistent.

C#, MySQL - fatal error encountered during command execution- Checked other solutions, something I am Missing

I have looked at the other questions with this title and I think the problem is something local with my code that I am missing.
The function that this button preforms is to calculate the points/rewards that a person earns based on the transaction total. For example, $10 = 1 point, 19=1 point, 20=2. 10 Points = 1 Rewards points, which is equal to a ten dollar credit.
My Code receives the title error message. I will include the entire function for completeness.
private void button1_Click(object sender, EventArgs e)
{
try{
string cs = #"server=localhost;userid=root;password=root;database=dockingbay94";
MySqlConnection conn;
//MySqlDataReader rdr = null;
using (conn = new MySqlConnection(cs));
if (conn.State != ConnectionState.Open)
{
conn.Open();
}
string input = textBox2.Text;
MySqlCommand myCommand2 = conn.CreateCommand();
myCommand2.CommandText = "SELECT Points FROM members WHERE id = #input";
MySqlDataAdapter MyAdapter2 = new MySqlDataAdapter();
MyAdapter2.SelectCommand = myCommand2;
double transaction = Convert.ToDouble(textBox3.Text);
double tmp_transaction = Math.Floor(transaction);
string transaction_date = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
double pointsbefore = (tmp_transaction / 10.0);
int currentpoints = Convert.ToInt32(pointsbefore);
int rewards = 0;
int oldpoints = 0;
string temp = "";
pointsbefore = Math.Floor(pointsbefore);
int new_points;
double tmp_rewards = 0.0;
double tmp_points;
int new_rewards;
oldpoints = (int)myCommand2.ExecuteScalar();
new_points = currentpoints + oldpoints;
tmp_points = new_points / 10;
int tmp_rewards2 = 0;
if (new_points > 10)
{
tmp_rewards = Math.Floor(tmp_points);
tmp_rewards2 = Convert.ToInt32(tmp_rewards);
}
else if (new_points == 10)
{
tmp_rewards2 = 1;
}
else
{
tmp_rewards2 = 0;
}
new_rewards = rewards + tmp_rewards2;
int points_left = 0;
if (new_points > 10)
{
for (int i = 10; i < new_points; i++)
{
points_left++;
}
}
else if (new_points == 10)
{
points_left = 0;
}
else if (new_points < 10)
{
for (int i = 0; i < new_points; i++)
{
points_left++;
}
}
string query = "UPDATE members Set Points=#Points, rewards_collected=#Rewards, transaction_total=#Transaction, transaction_date=#TransactionDate" + "WHERE id = #input;";
MySqlCommand cmdDataBase = new MySqlCommand(query, conn);
cmdDataBase.Parameters.Add("#input", SqlDbType.Int).Value = Convert.ToInt32(textBox2.Text);
cmdDataBase.Parameters.AddWithValue("#Points", new_points);
cmdDataBase.Parameters.AddWithValue("#Rewards", new_rewards);
cmdDataBase.Parameters.AddWithValue("#Transaction", textBox3.Text);
cmdDataBase.Parameters.AddWithValue("#TransationDate", transaction_date);
MySqlDataReader myReader2;
myReader2 = cmdDataBase.ExecuteReader();
MessageBox.Show("Data Updated");
if(conn.State == ConnectionState.Open){
conn.Close();
}
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
I am not sure where the error could be. Probably not sending the right value.
Thanks
This line is wrong
using (conn = new MySqlConnection(cs));
Remove the semicolon and include everything that needs the MySqlConnection variable inside a {} block
using (MySqlConnection conn = new MySqlConnection(cs))
{
// No need to test if the connection is not open....
conn.Open();
.........
// Not needed (at least from your code above
// MySqlDataAdapter MyAdapter2 = new MySqlDataAdapter();
// MyAdapter2.SelectCommand = myCommand2;
... calcs follow here
// Attention here, if the query returns null (no input match) this line will throw
oldpoints = (int)myCommand2.ExecuteScalar();
.... other calcs here
MySqlCommand cmdDataBase = new MySqlCommand(query, conn);
cmdDataBase.Parameters.Add("#input", SqlDbType.Int).Value = Convert.ToInt32(textBox2.Text);
cmdDataBase.Parameters.AddWithValue("#Points", new_points);
cmdDataBase.Parameters.AddWithValue("#Rewards", new_rewards);
cmdDataBase.Parameters.AddWithValue("#Transaction", textBox3.Text);
cmdDataBase.Parameters.AddWithValue("#TransationDate", transaction_date);
// Use ExecuteNonQuery for INSERT/UPDATE/DELETE and other DDL calla
cmdDataBase.ExecuteNonQuery();
// Not needed
// MySqlDataReader myReader2;
// myReader2 = cmdDataBase.ExecuteReader();
// Not needed, the using block will close and dispose the connection
if(conn.State == ConnectionState.Open)
conn.Close();
}
There is also another error in the final query. Missing a space between #TransactionDate parameter and the WHERE clause. In cases where a long SQL command text is needed I find very useful the verbatim string line character continuation #
string query = #"UPDATE members Set Points=#Points, rewards_collected=#Rewards,
transaction_total=#Transaction, transaction_date=#TransactionDate
WHERE id = #input;";

Categories