How do I get an DataTable from IDataReader? - c#

I'm trying to get a DataTable or DataSet from an IDataReader, but I'm failing. Here's the code:
string sql = #"SELECT ID, DOCNUMBER FROM TBDOCUMENT";
using (IDbConnection conn = CreateConnection(provider, connectionString))
{
conn.Open();
using (IDbCommand command = conn.CreateCommand())
{
command.CommandText = sql;
IDataReader reader = command.ExecuteReader();
using (reader)
{
while (reader.Read())
{
long key = reader.GetInt64(0);
decimal value = reader.GetDecimal(1);
}
}
}
}
I'm using IDbConnection and IDbCommand because it will works with three different databases (the method CreateConnection(provider, connectionString) gets the specific type of connection according to the database).
My query gets an ID (as Int64) and a DocNumber (as Decimal), but every time I try to get the decimal value, it throws an OverflowException with a message: "Conversion overflows." Both of values are important to me, but I don't know how do I get these values.
Actually, the code I'm not trying to convert to a DataTable, I have to get the value of the two without exception.
Some help?

Though I haven't check by executing but it should work...
// Load the data into the existing DataSet.
DataTableReader reader = GetReader();
dataSet.Load(reader, LoadOption.OverwriteChanges,
customerTable, productTable);
// Load the data into the DataTable.
SqlDataReader dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
DataTable dt = new DataTable();
dt.Load(dr);

Related

How to use C# connect to mysql and get json data?

As mentioned above:
I'm using C# to connect to a MySQL database and I want to read JSON data type.
I use the method MySqlCommand.ExecuteReader:
using (MySqlConnection sconn = new MySqlConnection(sqlConnectString))
{
sconn.Open();
String sql_Command = #"SELECT `id` FROM orders.jsontest;";
using (MySqlCommand scmd = new MySqlCommand(sql_Command, sconn))
{
**MySqlDataReader sdr = scmd.ExecuteReader();** // fatal error
DataTable datatable = new DataTable();
// ...
}
}
Can it be that I cannot use ExecuteReader here?
I know this question is old, but just in case you do not yet have a solution to your problem or anyone else encounters a similar problem, the following code should work for you:
private IEnumerable<int> GetIds()
{
using (MySqlConnection connection = new MySqlConnection(connectionString))
{
connection.Open();
string commandText = #"SELECT id FROM jsontest"; // Assuming that `orders` is your database, then you do not need to specify it here.
using (MySqlCommand command = new MySqlCommand(commandText, connection))
{
MySqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
yield return reader.GetInt32(0);
}
}
}
}
Now what you should pay attention to is this line
while (reader.Read())
which fetches results from the jsontest table as long as the MySqlDataReader can still read valid results and this line
yield return reader.GetInt32(0);
which instructs the reader to get and return each record of the fetched table one at a time as an Int32 (int). You need to change this if your tables column type is not INT.
Since you selected just one column (i.e. "SELECT id"), the parameter is 0, because your fetched resul table consists of one column only.
Additionally, in your code you seem to want to get the results as a DataTable; if so, you should use MySqlDataAdapter instead of the MySqlDataReader as follows:
DataTable resultTable = new DataTable("ResultTable");
MySqlDataAdapter adapter = new MySqlDataAdapter(command);
adapter.Fill(table);
Correct your sql command
String sql_Command = #"SELECT id FROM orders.jsontest";

'Invalid attempt to read when no data is present' error

I've got this code block:
using (SqlConnection con2 = new SqlConnection(str2))
{
using (SqlCommand cmd2 = new SqlCommand(#"SELECT * FROM VW_MOS_DPL_AccountValidation WHERE CUST_NUM = #CNum", con2))
{
con2.Open();
cmd2.Parameters.AddWithValue("#CNum", TBAccountNum.Text);
using (SqlDataReader DT2 = cmd2.ExecuteReader())
{
// If the SQL returns any records, process the info
if (DT2.HasRows)
{
// If there's a BusinessID (aka Business Type), fill it in
string BizID = (DT2["Business_ID"].ToString());
if (!string.IsNullOrEmpty(BizID))
{
DDLBustype.SelectedValue = BizID;
}
}
}
con2.Close();
}
}
When it gets to the line
string BizID = (DT2["Business_ID"].ToString());
it throws an error:
Invalid attempt to read when no data is present.
Why would it get past if (DT2.HasRows) if there was no data?
You need to call
if(DT2.Read())
....
before proceding to read data from a DataReader.
The HasRows tells you only that the SqlDataReader contains data, but the SqlDataReader loads one record at time from the connection. Thus every tentative to extract the data from the SqlDataReader should be preceded by a call to Read to position the SqlDataReader on the first record returned through the connection.
And, because the Read method returns true if the call has been able to read a record, you could replace the call to HasRows with something like this
using (SqlDataReader DT2 = cmd2.ExecuteReader())
{
// If the SQL returns any records, process the info
while(DT2.Read())
{
// If there's a BusinessID (aka Business Type), fill it in
string BizID = (DT2["Business_ID"].ToString());
if (!string.IsNullOrEmpty(BizID))
{
DDLBustype.SelectedValue = BizID;
}
}
}
By the way, if it is possible to have a NULL for BusinessID then you need a different test to avoid exception problems
int bizColIndex = DT2.GetOrdinal("Business_ID");
string BizID = (DT2.IsDBNull(bizColIndex) ? string.Empty : DT2.GetString(bizColIndex));
if (!string.IsNullOrEmpty(BizID))
{
DDLBustype.SelectedValue = BizID;
}

I am not able to get the data from database into a textbox

string connstring = ConfigurationManager.ConnectionStrings["electionConnectionString"].ConnectionString;
protected void Page_Load(object sender, EventArgs e)
{
updatedata();
}
public void updatedata(){
int ward_no =Convert.ToInt32((Session["wardno"]));
string query = "select ward_no,part_no,part_leader1_name,part_leader1_mob,part_leader2_name,part_leader2_mob,t_streets,t_families,t_electoral,t_male,t_female,t_others from f_field_details where ward_no=#ward_no";
MySqlConnection con = new MySqlConnection(connstring);
con.Open();
MySqlCommand cmd = new MySqlCommand(query, con);
cmd.Parameters.AddWithValue("#ward_no", ward_no);
MySqlDataReader reader = cmd.ExecuteReader();
DataTable dt = new DataTable();
if (reader.Read())
{
txtward.Text = reader["ward_no"].ToString();
txtpart.Text = reader["part_no"].ToString();
txtleadername.Text = reader["part_leader1_name"].ToString();
txtphne1.Text = reader["part_leader1_mob"].ToString();
txtname1.Text = reader["part_leader2_name"].ToString();
txtphneno.Text = reader["part_leader2_mob"].ToString();
txtstreets.Text = reader["t_streets"].ToString();
txtfamilies.Text =reader["t_families"].ToString();
txttotvotes.Text = reader["t_electoral"].ToString();
txtMen.Text = reader["t_male"].ToString();
txtWomen.Text = reader["t_female"].ToString();
txtothers.Text = reader["t_others"].ToString();
}
}
}
this is my coding, i am getting the data from the database after the user is entering the data in the previous page after they click the submit button I am redirecting them into the next page that is this page, the issue is the data is getting inserted into the database but will retrieving the data from the database is not working. to get the data am using a where condition in the query and the object for the condition is coming from the previous page using session. the issue is the data is not displayed in the textboxes
There are few corrections in your code:
The session["string"] will return on object, that may or maynot be convertiable as an integer so better to use int.TryParse() instead for Convert.To..().
Reader may get null reference if reader has no rows, so i suggest you to check for reader.HasRows before accessing value from it. or use While(reader.Read()):
Retrieving data using a DataReader involves creating an instance of
the Command object and then creating a DataReader by calling
Command.ExecuteReader to retrieve rows from a data source. The
following example illustrates using a DataReader where reader
represents a valid DataReader and command represents a valid Command
object.
Use Parameters.Add() instead for Parameters.AddWithValue()
So your code looks like this(and this may solve your problem too):
int ward_no=0;
int.TryParse(Session["wardno"].ToString(), out ward_no);
string query = "select ward_no,part_no,part_leader1_name,part_leader1_mob,part_leader2_name,part_leader2_mob,t_streets,t_families,t_electoral,t_male,t_female,t_others from f_field_details where ward_no=#ward_no";
MySqlConnection con = new MySqlConnection(connstring);
con.Open();
MySqlCommand cmd = new MySqlCommand(query, con);
cmd.Parameters.Add("#ward_no", MySqlDbType.Int32).Value = ward_no; //this will be the type of field
MySqlDataReader reader = cmd.ExecuteReader();
DataTable dt = new DataTable();
while (reader.Read())
{
// assign values here
}

SqlDataReader to read into List<string>

I am writing a method in C# to query a SQL Server Express database from a WCF service. I have to use ADO.NET to do this (then rewrite it with LINQ later on).
The method takes two strings (fname, lname) then returns a "Health Insurance NO" attribute from the matching record. I want to read this into a list (there are some other attribs to retrieve as well).
The current code returns an empty list. Where am I going wrong?
public List<string> GetPatientInfo(string fname, string lname)
{
string connString = "Data Source=.\\SQLEXPRESS;AttachDbFilename=C:\\Users\\xxxx\\Documents\\Visual Studio 2010\\Projects\\ADOWebApp\\ADOWebApp\\App_Data\\ADODatabase.mdf;Integrated Security=True;User Instance=True";
SqlConnection conn = new SqlConnection(connString);
string sqlquery = "SELECT Patient.* FROM Patient WHERE ([First Name] = '"+fname+"') AND ([Last Name] = '"+lname+"')";
SqlCommand command = new SqlCommand(sqlquery, conn);
DataTable dt = new DataTable();
List<string> result = new List<string>();
using (conn)
{
conn.Open();
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader != null && reader.Read())
{
dt.Load(reader);
result.Add(Convert.ToString(reader["Health Insurance NO"]));
}
}
}
return result;
}
You are trying to load a DataTable via DataTable.Load >in a loop<. You just need that once. You're also using reader.Read() in the loop. SqlDataReader.Read() advances the reader to the next record without to consume it. If you're going to use DataTable.Load you don't need to read the reader first. So you just have to remove the loop completely to load the table.
But since you want to return a list you don't need the DataTable at all, just loop the reader:
List<string> result = new List<string>();
using (conn)
{
conn.Open();
using (SqlDataReader reader = command.ExecuteReader())
{
while(reader.Read())
{
result.Add(Convert.ToString(reader["Health Insurance NO"]));
}
}
}
Apart from that, you are open for sql-injection without sql-parameters.
I would do it this way:
conn.Open();
using (SqlDataReader reader = command.ExecuteReader())
{
dt.Load(reader);
}
foreach (var row in dt.AsEnumerable())
{
result.Add(row["Health Insurance NO"].ToString());
}

How to select number from Excel file?

I use this code to load an Excel file into a datatable:
public static DataTable ImportExcelFile(string connectionString)
{
DbProviderFactory factory =
DbProviderFactories.GetFactory("System.Data.OleDb");
var listCustomers = new DataTable();
using (DbConnection connection = factory.CreateConnection())
{
if (connection != null)
{
connection.ConnectionString = connectionString;
using (DbCommand command = connection.CreateCommand())
{
// Cities$ comes from the name of the worksheet
command.CommandText = "SELECT * FROM [Sheet1_2$]";
connection.Open();
using (DbDataReader dr = command.ExecuteReader())
{
listCustomers.Load(dr);
}
}
}
}
return listCustomers;
}
The problem is, some columns in the Excel file, for example, AccountID, contains both string data ('quanmv') and number (123456). When I use this code, it just ignores cell with number value, and leave it with blank.
How can I fix that?
Thank you so much.
By default, the connection to excel tries to guess data types of columns. If it guesses wrong, it may leave nulls where types don't convert. You can add IMEX=1 to the connection string to turn off this automatic guessing, and treat all values as strings.

Categories