DataReader.Read() always returns false - c#

I've been searching for hours now. I can't find anything helpful for my problem.
The Read()-function always returns false. If I run the SQL-command with sqlplus I get this result:
GERA_ID GETY_BEZEICHNUNG
---------------------------
100001 Blackberry
100002 GSM
here's a simplified version of the code:
List<Divice> divices = new List<Divice>();
using (OracleConnection connection = new OracleConnection(connectionString))
{
OracleCommand cmd = new OracleCommand("select gera_id, gety_bezeichnung from idc_geraet, idc_geraettyp where idc_geraettyp.gety_id = idc_geraet.gety_id and pers_id = 4711");
cmd.Connection = connection;
connection.Open();
OracleDataReader reader = cmd.ExecuteReader();
while(reader.Read()) //returns always false
{
Divice g = new Divice();
g.gera_id = reader.GetDecimal(0);
g.gety_bezeichnung = reader.GetString(1);
divices.Add(g);
}
reader.Close();
}
EDIT:
This Code is called before. and it works fine:
IDC_PERSON p = new IDC_PERSON();
using (OracleConnection connection = new OracleConnection(connectionString))
{
OracleCommand cmd = new OracleCommand("select PERS_VNAME, PERS_NNAME, PERS_EINTRDATUM from idc_person where PERS_ID = 4711");
cmd.Connection = connection;
connection.Open();
OracleDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
if (reader.Read())
{
p.PERS_ID = user_id;
p.PERS_VNAME = reader.GetString(0);
p.PERS_NNAME = reader.GetString(1);
p.PERS_EINTRDATUM = reader.GetDateTime(2);
}
reader.Close();
}
So, here is the whole code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Oracle.DataAccess.Client;
using TelKoOpt.Models;
using System.Data;
namespace TelKoOpt.Controllers
{
public class HomeController : Controller
{
string connectionString = "user id=scott;password=tiger;" +
"data source=(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=localhost)" +
"(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=orcl)))";
public ActionResult Index(int user_id)
{
MyDbContext dbcontext = new MyDbContext();
IDC_PERSON p = new IDC_PERSON();
List<IDC_GERAET> geraete = new List<IDC_GERAET>();
List<TELGSMEGN> telgsmegn = new List<TELGSMEGN>();
dbcontext.pers = p;
dbcontext.geraete = geraete;
dbcontext.telgsmegn = telgsmegn;
using (OracleConnection connection = new OracleConnection(connectionString))
{
OracleCommand cmd = new OracleCommand("select PERS_VNAME, PERS_NNAME, PERS_EINTRDATUM from idc_person where PERS_ID = " + user_id);
//OracleCommand cmdTelg = new OracleCommand("select service, sum(betrag), sum(dauer), sum(anzahl), zonen from test_telgsmegn where gera_id = " + user_id + " and datumaktion between '" + "01.02.2012" + "' and '" + "20.03.2012" + "' group by service, zonen; ");
cmd.Connection = connection;
//cmdTelg.Connection = new OracleConnection(connectionString);
try
{
connection.Open();
OracleDataReader reader = cmd.ExecuteReader();
if (reader.Read())
{
p.PERS_ID = user_id;
p.PERS_VNAME = reader.GetString(0);
p.PERS_NNAME = reader.GetString(1);
p.PERS_EINTRDATUM = reader.GetDateTime(2);
}
reader.Close();
}
catch (OracleException)
{
//return View(dbcontext);
}
}
using (OracleConnection connection = new OracleConnection(connectionString))
{
OracleCommand cmd = new OracleCommand("select gera_id, gety_bezeichnung from idc_geraet, idc_geraettyp where idc_geraettyp.gety_id = idc_geraet.gety_id and pers_id = " + user_id);
cmd.Connection = connection;
try
{
connection.Open();
OracleDataReader reader = cmd.ExecuteReader();
while(reader.Read())
{
IDC_GERAET g = new IDC_GERAET();
g.gera_id = reader.GetDecimal(0);
g.gety_bezeichnung = reader.GetString(1);
geraete.Add(g);
}
reader.Close();
}
catch (OracleException)
{
//return View(dbcontext);
}
}
return View(dbcontext);
}
}
}

This may not be the answer for your case, but I ran into a similar issue when debugging code and it may help others who come across this question.
The solution I figured out was actually only specific to when you are debugging. When stepping through code, if you expand the "Results View" (which enumerates the enumerable), when you get to the part in your code that reads the data reader, the reader will already be at the end of the results, and will return false. This is because data readers are forward only, and once you've enumerated to the next result (which was done by the debugger in this case), you can't go back.

same issue faced by me this is how i fixed
use out type
public void ExecuteStoredProcReturnDataReader(string sQueryName, out IDataReader dr, List<DBParam> oParams =null)
{
try
{
dbHelper DBProvider = new dbHelper();
if (conn.State != ConnectionState.Open)
{
conn.Open();
}
oCmd = DBProvider.CreateCommand(sQueryName, conn);
if (oParams !=null)
DBProvider.CreateParameters(oParams, ref oCmd);
dr = oCmd.ExecuteReader();
}
catch (Exception e)
{
rethrow = DataAccessExceptionHandler.HandleException(ref e);
if (rethrow)
{
throw e;
}
dr = null;
}
}

Related

SQL Server not executing SqlExecuteReader

I'm stumped, I have been trying to execute this and nothing happens. I know that the code reaches this point but it doesn't matter if I put gibberish in the SQL statement, it doesn't throw an error.
protected string checkLaptopStatus(String cardID)
{
String ConnString = GetConnectSQLServer();
String currentStatus = "";
int i = 0;
using (SqlConnection m_dbConnection = new SqlConnection(ConnString))
{
String sql = "SELECT laptopStatus FROM tblDevices WHERE cardID = " + cardID + "'";
m_dbConnection.Open();
// CODE REACHES THIS POINT BUT NEVER PASSES THIS ?
using (SqlCommand cmd = new SqlCommand(sql, m_dbConnection))
{
using (SqlDataReader dr = cmd.ExecuteReader())
{
while (dr.Read())
{
currentStatus = Convert.ToString(dr["laptopStatus"]);
i++;
}
}
}
}
return currentStatus;
}
Changed the code as advised and used the exception error message to find out what went wrong. thanks Joel for being kind and helping.
protected void SQLReaderLaptops(string cardID)
{
String ConnString = GetConnectSQLServer();
int i = 0;
String todaysDate = DateTime.Now.ToString("yyyy'-'MM'-'dd");
String laptopID = "";
try {
using (SqlConnection m_dbConnection = new SqlConnection(ConnString))
{
String sql = "Select laptopID From tblDevices WHERE cardID= #cardID";
m_dbConnection.Open();
using (SqlCommand cmd = new SqlCommand(sql, m_dbConnection))
{
cmd.Parameters.AddWithValue("#cardID", cardID);
using (SqlDataReader dr = cmd.ExecuteReader())
{
while (dr.Read())
{
laptopID = Convert.ToString(dr["laptopID"]);
i++;
}
}
}
}
}
catch(Exception ex)
{
//CAUGHT THE ISSUE HERE AND FOUND IT WAS A BAD COLUMN NAME
}

Object reference is not set to an instance Access query C#

I'm trying to make a query into the Clients table, when the user enters a mobile number, the code checks if it matches any record, if it does, it returns the client's Name & Address into text boxes, but I'm getting this error "Object reference is not set to an instance of an object" by the time I enter anything into that textbox
here is the code, what could be the problem?
private void textBox11_TextChanged(object sender, EventArgs e)
{
clientsearch();
clientsearch2();
}
public void clientsearch()
{
using (System.Data.OleDb.OleDbConnection conn = new System.Data.OleDb.OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data source=|DataDirectory|\\crepeDB.accdb;"))
{
conn.Open();
string query = #"select Cname From Clients where Cmobile = #mobile";
System.Data.OleDb.OleDbCommand cmd = new System.Data.OleDb.OleDbCommand(query, conn);
cmd.Parameters.Add("#mobile", System.Data.OleDb.OleDbType.Integer).Value = textBox11.Text;
cmd.ExecuteNonQuery();
string result = cmd.ExecuteScalar().ToString();
textBox12.Text = #result;
}
}
public void clientsearch2()
{
using (System.Data.OleDb.OleDbConnection conn = new System.Data.OleDb.OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data source=|DataDirectory|\\crepeDB.accdb;"))
{
conn.Open();
string query = #"select Caddress From Clients where Cmobile = #mobile";
System.Data.OleDb.OleDbCommand cmd = new System.Data.OleDb.OleDbCommand(query, conn);
cmd.Parameters.Add("#mobile", System.Data.OleDb.OleDbType.Integer).Value = textBox11.Text;
cmd.ExecuteNonQuery();
string result = cmd.ExecuteScalar().ToString();
textBox13.Text = #result;
}
}
string result = cmd.ExecuteScalar().ToString();
textBox12.Text = #result;
#result isn't anything. You just want result. Additionally, sending separate queries to the server for this data is pointlessly inefficient. Do this instead:
public void clientsearch()
{
string query = #"select Cname, Caddress From Clients where Cmobile LIKE #mobile + '*'";
using (var conn = new System.Data.OleDb.OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data source=|DataDirectory|\\crepeDB.accdb;"))
using (var cmd = System.Data.OleDb.OleDbCommand(query, conn))
{
cmd.Parameters.Add("#mobile", System.Data.OleDb.OleDbType.Integer).Value = textBox11.Text;
conn.Open();
using (var rdr = cmd.ExecuteReader())
{
if (rdr.Read())
{
textBox12.Text = rdr["Cname"].ToString();
textBox13.Text = rdr["Caddress"].ToString();
}
rdr.Close();
}
}
}
Finally, it's better style to also abstract your database code away from user interface. Ideally you would return a Client class, but since I don't see one I'll show an example using a tuple instead:
public Tuple<string, string> FindClientByMobile(string mobile)
{
string query = #"SELECT Cname, Caddress FROM Clients WHERE Cmobile LIKE #mobile + '*'";
using (var conn = new System.Data.OleDb.OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data source=|DataDirectory|\\crepeDB.accdb;"))
using (var cmd = System.Data.OleDb.OleDbCommand(query, conn))
{
cmd.Parameters.Add("#mobile", System.Data.OleDb.OleDbType.Integer).Value = mobile;
conn.Open();
using (var rdr = cmd.ExecuteReader())
{
rdr.Read();
return Tuple<string, string>.Create(rdr["Cname"].ToString(), rdr["Caddress"].ToString());
}
}
}
If you're playing with a Visual Studio 2017 release candidate, you can also use the new Tuple shortcuts:
public (string, string) FindClientByMobile(string mobile)
{
string query = #"SELECT Cname, Caddress FROM Clients WHERE Cmobile LIKE #mobile + '*'";
using (var conn = new System.Data.OleDb.OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data source=|DataDirectory|\\crepeDB.accdb;"))
using (var cmd = System.Data.OleDb.OleDbCommand(query, conn))
{
cmd.Parameters.Add("#mobile", System.Data.OleDb.OleDbType.Integer).Value = mobile;
conn.Open();
using (var rdr = cmd.ExecuteReader())
{
rdr.Read();
return (rdr["Cname"].ToString(), rdr["Caddress"].ToString());
}
}
}
And then use them like this:
private void textBox11_TextChanged(object sender, EventArgs e)
{
var result = FindClientByMobile(textBox11.Text);
textBox12.Text = result.Item1;
textBox13.Text = result.Item2;
}

Returning multiple sqlcommands

I get that we can use using to have multiple commands in a sqlconnection.
Like this:
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
using (SqlCommand command1 = new SqlCommand(commandText1, connection))
{
}
using (SqlCommand command2 = new SqlCommand(commandText2, connection))
{
}
// etc
}
However, what if the using is in a method that returns a reader cast?
Like this:
public IEnumerable<LocationInfo> GetData()
{
using (var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["Database"].ConnectionString))
{
//connection.Close();
connection.Open();
using (SqlCommand command = new SqlCommand(#"SELECT .... ", connection))
{
command.Notification = null;
SqlDependency dependency = new SqlDependency(command);
dependency.OnChange += new OnChangeEventHandler(dependency_OnChange);
if (connection.State == ConnectionState.Closed)
{ connection.Open(); }
using (var reader = command.ExecuteReader())
{
return reader.Cast<IDataRecord>().Select(x => new LocationInfo()
{
Names = x.GetString(2),
Values = Math.Round(x.GetDouble(7), 2).ToString("#,##0.00"),
ValuesDouble = x.GetDouble(7),
Values2 = Math.Round(x.GetDecimal(9), 2).ToString("#,##0.00"),
ValuesDouble2 = x.GetDecimal(9),
truckDelivery=x.GetDecimal(3),
truckIdle = x.GetDecimal(4),
truckRepair = x.GetDecimal(5),
truckReady = x.GetDecimal(6),
presentEmp=x.GetInt32(11),
absentEmp = x.GetInt32(12),
ondutyEmp = x.GetInt32(13),
}).ToList();
}
/* I tried this but it just got ignored
using (var reader2 = command.ExecuteReader())
{
reader2.NextResult();
return reader2.Cast<IDataRecord>().Select(x => new LocationInfo()
{
SumVol = x.GetString(0)
}).ToList();
}*/
}
}
}
Help me please. My second using keeps getting ignored and don't assume that I know anything because I'm new to this. Thank you in advance.
You need to Read the record pointed by the SqlDataReader obtained by the ExecuteReader. Accumulate your LocationInfo in a List and return them when you have finished to loop over the reader.
public IEnumerable<LocationInfo> GetData()
{
List<LocationInfo> locations = new List<LocationInfo>();
using (var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["Database"].ConnectionString))
using (SqlCommand command = new SqlCommand(#"SELECT .... ", connection))
{
connection.Open();
using (var reader = command.ExecuteReader())
{
while(reader.Read())
{
LocationInfo x = new LocationInfo()
{
Names = x.GetString(2),
Values = Math.Round(x.GetDouble(7), 2).ToString("#,##0.00"),
ValuesDouble = x.GetDouble(7),
Values2 = Math.Round(x.GetDecimal(9), 2).ToString("#,##0.00"),
ValuesDouble2 = x.GetDecimal(9),
truckDelivery=x.GetDecimal(3),
truckIdle = x.GetDecimal(4),
truckRepair = x.GetDecimal(5),
truckReady = x.GetDecimal(6),
presentEmp=x.GetInt32(11),
absentEmp = x.GetInt32(12),
ondutyEmp = x.GetInt32(13),
};
locations.Add(x);
}
}
}
return locations;
}
OK so here is what you can do in your situation to merge results from two result sets into one object.
public IEnumerable<LocationInfo> GetData()
{
List<LocationInfo> locations = new List<LocationInfo>();
using (var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["Database"].ConnectionString))
using (SqlCommand command = new SqlCommand(#"SELECT .... ", connection))
{
connection.Open();
using (var reader = command.ExecuteReader())
{
LocationInfo x = new LocationInfo();
while(reader.Read())
{
{
x.Names = reader.GetString(2),
x.Values=Math.Round(reader.GetDouble(7),2).ToString("#,##0.00"),
x.ValuesDouble = reader.GetDouble(7),
Values2 = Math.Round(reader.GetDecimal(9), 2).ToString("#,##0.00"),
x.ValuesDouble2 = reader.GetDecimal(9),
x.truckDelivery=reader.GetDecimal(3),
x.truckIdle = reader.GetDecimal(4),
x.truckRepair = reader.GetDecimal(5),
x.truckReady = reader.GetDecimal(6),
x.presentEmp=reader.GetInt32(11),
x.absentEmp = reader.GetInt32(12),
x.ondutyEmp = reader.GetInt32(13),
};
}
if(reader.NextResult())
{
while (reader.Read())
{
x.SumVol=reader.GetString(0);
}
}
locations.Add(x);
}
}
return locations;
}

SQLite Database is not open Error

I have a constructor that takes data from a SQL Server database and puts it in a local SQLite database:
public ForemanController()
{
connectionString.DataSource = "dxdb02v";
connectionString.InitialCatalog = "QTRAX4619410";
connectionString.UserID = "tunnelld";
connectionString.Password = "david";
string queryString = "SELECT * FROM [QTRAXAdmin].[vwQT_Foreman]";
List<Foreman> list;
// Creates a SQL connection
using (var connection = new SqlConnection(connectionString.ToString()))
{
using (var command = new SqlCommand(queryString, connection))
{
connection.Open();
using (var reader = command.ExecuteReader())
{
list = new List<Foreman>();
while (reader.Read())
{
list.Add(new Foreman { ForeBadge = reader.GetString(0), ForeName = reader.GetString(1) });
}
}
}
connection.Close();
allForeman = list.ToArray();
}
string deleteSQL = "DELETE FROM Foreman;";
using (SQLiteConnection SQLconn1 = new SQLiteConnection(SQLiteConnectionString))
{
using (var command = new SQLiteCommand(deleteSQL, SQLconn1))
{
command.Connection.Open();
command.ExecuteNonQuery();
}
}
using (SQLiteConnection SQLconn2 = new SQLiteConnection(SQLiteConnectionString))
{
SQLiteCommand cmd2 = SQLconn2.CreateCommand();
foreach (Foreman row in allForeman)
{
cmd2.CommandText = "INSERT INTO Foreman (ForeBadge, ForeName) VALUES (#param1, #param2);";
cmd2.Parameters.Add(new SQLiteParameter("#param1", row.ForeBadge));
cmd2.Parameters.Add(new SQLiteParameter("#param2", row.ForeName));
cmd2.ExecuteNonQuery();
}
}
}
Everything seems to be working fine until the last using statement:
using (SQLiteConnection SQLconn2 = new SQLiteConnection(SQLiteConnectionString))
{
SQLiteCommand cmd2 = SQLconn2.CreateCommand();
foreach (Foreman row in allForeman)
{
cmd2.CommandText = "INSERT INTO Foreman (ForeBadge, ForeName) VALUES (#param1, #param2);";
cmd2.Parameters.Add(new SQLiteParameter("#param1", row.ForeBadge));
cmd2.Parameters.Add(new SQLiteParameter("#param2", row.ForeName));
cmd2.ExecuteNonQuery();
}
}
I'm getting this error:
That's because that's the only place you forgot to open the connection.
add this: SQLconn2.Open();
You forgot to open the connection.
SQLConn2.Open();

C# use a reader in another reader solution?

I need to get some mysql data into another mysql reader request anyway to workaround that I apparently can't have 2 readers open at the same time it will all end up in a datagrid
public void DBSelectPraktikanter(object sender)
{
string Command = "SELECT * FROM forlob WHERE firmaid = N'" + firmaid + "'";
MySqlConnection sqlConnection1 = new MySqlConnection(connectionString);
MySqlCommand command = new MySqlCommand(Command, sqlConnection1);
sqlConnection1.Open();
MySqlDataReader reader = command.ExecuteReader();
var items = new List<praktikanter>();
if (reader.HasRows)
{
while (reader.Read())
{
string praktikantid = String.Format("{0}", reader["praktikantid"]);
string Command2 = "SELECT * FROM praktikanter WHERE id = N'" + praktikantid + "'";
MySqlCommand command2 = new MySqlCommand(Command, sqlConnection1);
MySqlDataReader reader2 = command.ExecuteReader();
if (reader.HasRows)
{
while (reader2.Read())
{
Praktikant = String.Format("{0}", reader["Navn"]);
}
}
string Fra = String.Format("{0}", reader["fra"]);
string Til = String.Format("{0}", reader["til"]);
items.Add(new praktikanter(Praktikant, Fra, Til));
}
}
sqlConnection1.Close();
var grid = sender as DataGrid;
grid.ItemsSource = items;
}
Instead of nesting MySqlCommands and looping the first resultset to query again the database to collect all of your data you should really use one query. Also use the using-statement to ensure that the connection gets closed even on error and use sql-parameters to avoid sql-injection issues:
var items = new List<praktikanter>();
string sql = #"SELECT p.*, f. Navn
FROM praktikanter p INNER JOIN forlob f ON p.id = f.praktikantid
WHERE f.firmaid = #firmaid";
using (var con = new MySqlConnection(connectionString))
using (var command = new MySqlCommand(sql, con))
{
command.Parameters.Add(new MySqlParameter("#firmaid", MySqlDbType.VarChar).Value = firmaid);
con.Open();
using (var rd = command.ExecuteReader())
{
while (rd.Read())
{
string praktikant = rd.GetString("Navn");
string fra = rd.GetString("Fra");
string til = rd.GetString("Til");
items.Add(new praktikanter(praktikant, fra, til));
}
}
}

Categories

Resources