I'm trying to get information from database access with this method
public List<gerant> getinfogerant()
{
List<gerant> gerer = new List<gerant>();
string sql_gerant = "select CIN,NOM,PRENOM,ADRESS_PERSONNEL,NUM_TEL,MAIL,MOBILE,CP_GERANT,VILLE_GERANT,DATE_CIN from GERANT";
connexion connect = new connexion();
OleDbConnection connection = connect.getconnexion();
connection.Open();
OleDbCommand cmd = new OleDbCommand(sql_gerant, connection);
OleDbDataReader reader = cmd.ExecuteReader();
while(reader.Read())
{
gerer.Add(new gerant(reader.GetInt64(0),
reader.GetString(1),
reader.GetString(2),
reader.GetString(3),
reader.GetDouble(4),
reader.GetString(5),
reader.GetDouble(6),
reader.GetInt32(7),
reader.GetString(8),
reader.GetDateTime(9))
);
}
connection.Close();
return gerer;
}
In my database access I define the field cin as long integer and formatted "00000000"
But I'm getting an error in reader.GetInt64(0):
Specified cast is not valid
How can I solve that?
Try this code
public List<gerant> getinfogerant()
{
List<gerant> gerer = new List<gerant>();
try
{
connexion connect = new connexion();
OleDbCommand cmd = new OleDbCommand();
cmd.Connection = new OleDbConnection(connect.getconnexion());
cmd.CommandType = CommandType.Text;
comd.CommandText = "select CIN,NOM,PRENOM,ADRESS_PERSONNEL,NUM_TEL,MAIL,MOBILE,CP_GERANT,VILLE_GERANT,DATE_CIN from GERANT";
connection.Open();
OleDbDataReader reader = cmd.ExecuteReader();
while(reader.Read())
{
gerant g = new gerant();
if (!reader.IsDBNull(0)) g.CIN = int.Parse(reader.GetValue(0).ToString());
if (!reader.IsDBNull(1)) g.NOM = reader.GetValue(1).ToString();
if (!reader.IsDBNull(2)) g.PRENOM = reader.GetValue(2).ToString();
if (!reader.IsDBNull(3)) g.ADRESS_PERSONNEL = reader.GetValue(3).ToString();
if (!reader.IsDBNull(4)) g.NUM_TEL = Convert.ToDouble(reader.GetValue(4).ToString());
if (!reader.IsDBNull(5)) g.MAIL = reader.GetValue(5).ToString();
if (!reader.IsDBNull(6)) g.MOBILE =Convert.ToDouble(reader.GetValue(6).ToString());
if (!reader.IsDBNull(7)) g.CP_GERANT = int.Parse(reader.GetValue(7).ToString());
if (!reader.IsDBNull(8)) g.VILLE_GERANT = reader.GetValue(8).ToString();
if (!reader.IsDBNull(9)) g.DATE_CIN = Convert.ToDateTime(reader.GetValue(9).ToString());
gerer.add(g);
}
return gerer;
}
catch(Exception ex)
{
throw ex;
}
finally
{
reader.Close();
connection.Close();
}
}
and please adjust the names of your classes and methods:
- public List getinfogerant() -> public List getInfoGerant()
connexion connect = new connexion(); -> connection (not x)
Please check for DBNULL values, might be you are getting a null value.
Regards
Jasbeer Singh
Integers in Access come in 1, 2 and 4 byte varieties. The single byte number is named Byte (Range 0-255), the two-byte number is named Integer (-32768 to 32767) and then there is the Long Integer (-2 billion to 2 billion).
https://eggerapps.at/mdbviewer/docs/en/field-types.html
use getint32
I guess, you're getting exception not in the reader.GetInt64(0) but in the gerant constructor, so it could be any column.
To check this modify your code as follows
while (reader.Read())
{
var cin = reader.GetInt64(0);
var nom = reader.GetString(1);
var prenom = reader.GetString(2);
var addressPersonel = reader.GetString(3);
var numTel = reader.GetDouble(4);
var mail = reader.GetString(5);
var mobile = reader.GetDouble(6);
var cpGerant = reader.GetInt32(7);
var villeGerant = reader.GetString(8);
var dateCin = reader.GetDateTime(9);
gerer.Add(new gerant(cin,
nom,
prenom,
addressPersonel,
numTel,
mail,
mobile,
cpGerant,
villeGerant,
dateCin)
);
}
And you will get exception in real line.
I recommend to check column NUM_TEL and MOBILE for double numbers.
Also, check non-string columns for DbNull value before reading. long, int, double and DateTime can not be null.
Related
I am trying to get int value from the database but It is throwing an error
Unable to cast object of type 'System.Byte' to type 'System.Int32'.
In the database, Active field is tinyint.
Also, how to return both values from this method.
private string CheckData(string firstValue, string SecondValue, int Active)
{
string Data = "";
StringBuilder sb = new StringBuilder();
string query = #"select M.ident Mi, mmp.active Active
from Iden.Iden M
inner join PtM.MPt MMP on MMP.mPat = M.id
where M.ident = 'firstValue'
and Mi.ident = 'SecondValue'";
sb.Append(query);
sb.Replace("firstValue", firstValue);
sb.Replace("SecondValue", SecondValue);
SqlConnection connection = new SqlConnection(connString);
SqlCommand cmd = new SqlCommand(sb.ToString());
cmd.CommandTimeout = 0;
cmd.CommandType = CommandType.Text;
cmd.Connection = connection;
try
{
connection.Open();
SqlDataReader reader = cmd.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
Data = reader.GetString(reader.GetOrdinal("Mi"));
Active = reader.GetInt32(reader.GetOrdinal("Active"));
}
}
}
catch (Exception ex)
{
_log.Error($"Exception:{ex.Message}");
}
finally
{
connection.Close();
connection.Dispose();
}
return Data;
}
Here's a stab at it. I can't debug it (since I don't feel like creating a database).
First I create a type to hold the results. You could just use a Tuple, but this seems clearer:
public class DataActive
{
public string Data { get; set; }
public byte Active { get; set; }
}
I make your function return a collection of these - it's not obvious from your code that there is only one.
You'll also notice that I use SqlParameters to add firstValue and secondValue to your query. Look up SQL Injection (and Little Bobby Tables).
If you are using a recent version of C# (which I don't), there's a new syntax for using that requires less indenting. The using statements stick a call to Dispose in a finally statement at the end of the block. Also note that I'm disposing the SqlCommand and the DataReader
public static IEnumerable<DataActive> CheckData(string firstValue, string secondValue)
{
var results = new List<DataActive>();
const string query = #"select M.ident Mi,mmp.active Active from Iden.Iden M
Inner join PtM.MPt MMP on MMP.mPat =M.id
where M.ident = #firstValue and Mi.ident = #secondValue";
using (var connection = new SqlConnection(connString))
{
using (var cmd = new SqlCommand(query))
{
cmd.CommandTimeout = 0;
cmd.CommandType = CommandType.Text;
cmd.Connection = connection;
cmd.Parameters.Add("#firstValue", SqlDbType.NVarChar, 50).Value = firstValue;
cmd.Parameters.Add("#secondValue", SqlDbType.NVarChar, 50).Value = secondValue;
try
{
connection.Open();
using (var reader = cmd.ExecuteReader())
{
var dataOrdinal = reader.GetOrdinal("Mi");
var activeOrdinal = reader.GetOrdinal("Active");
if (reader.HasRows)
{
while (reader.Read())
{
results.Add(new DataActive
{
Data = reader.GetString(dataOrdinal),
Active = reader.GetByte(activeOrdinal),
});
}
}
}
}
catch (Exception ex)
{
_log.Error($"Exception:{ex.Message}");
}
}
}
return results;
}
If your TINY_INT Active represents a boolean value, figure out what the rule is, and do a conversion after you get the value using reader.GetByte.
One final note, it's often better to log ex.ToString() rather than ex.Message. You get the message and the stack that way.
I have no clue why I get an exception. It says that the reader got closed before I try to access it. Why is that so?
Here is the code:
//Load Projects from SQL Server (nothing else)
public SPpowerPlantList loadProjectsFromServer(DateTime timestamp, string note, string sqlServer, string database)
{
SqlConnection sqlConnection = new SqlConnection(String.Format(#"Integrated Security=SSPI;server={0};Initial Catalog={1};", sqlServer, database));
sqlConnection.Open();
string selectstring = "SELECT * FROM [dbo].[tblSPpowerPlant]"; //(WHERE note {0} = " + note + " AND timestamp {1} = " + timestamp;
SqlCommand sqlSelectCommand = new SqlCommand(selectstring, sqlConnection);
sqlSelectCommand.CommandType = CommandType.Text;
sqlSelectCommand.CommandText = selectstring;
SqlDataReader reader;
SPpowerPlantList powerPlantList = new SPpowerPlantList();
reader = sqlSelectCommand.ExecuteReader();
//this line trowhs the exeption
while (reader.Read())
{
foreach (SPpowerPlant powerPlant in powerPlantList)
{
powerPlant.ID = reader.GetInt32(0);
powerPlant.projectName = reader.GetString(1).ToString();
powerPlant.location = reader.GetString(2);
powerPlant.shortName = reader.GetString(3);
powerPlant.numberOfWtgs = reader.GetInt32(4);
powerPlant.mwWtg = reader.GetDouble(5);
powerPlant.mwTotal = reader.GetDouble(6);
powerPlant.projectShareWeb = reader.GetDouble(7);
powerPlant.mwWeb = reader.GetDouble(8);
powerPlant.phase = reader.GetString(9);
powerPlant.phaseNumber = reader.GetString(10);
powerPlant.phaseDescription = reader.GetString(11);
powerPlant.projectProgress = reader.GetDouble(12);
powerPlant.mwDeveloped = reader.GetDouble(13);
powerPlant.projectManager = reader.GetString(14);
powerPlant.spaceUrl = reader.GetString(15);
powerPlant.country = reader.GetString(16);
powerPlant.technology = reader.GetString(17);
powerPlant.state = reader.GetString(18);
powerPlant.allPermits = reader.GetDateTime(19);
powerPlant.cod = reader.GetDateTime(20);
powerPlant.stateSince = reader.GetDateTime(21);
powerPlant.spID = reader.GetInt32(22);
powerPlant.currency = reader.GetString(23);
powerPlant.possibleWtgTypes = reader.GetString(24);
powerPlant.hubHeight = reader.GetString(25);
powerPlant.visibility = reader.GetString(26);
powerPlant.templateName = reader.GetString(27);
powerPlantList.Add(powerPlant);
}
reader.Dispose();
sqlConnection.Close();
}
return powerPlantList;
}
Here is the exception (google translate):
Invalid attempt to Read access because the data reader has been closed.
I tried it with google but had no luck. So any help would be great. Thanks for your time.
BTW Sorry for my english not my native language but I work on it.
the code lines
reader.Dispose();
sqlConnection.Close();
are inside the while(reader.read()) loop.
Also, you better use using instead of calling Dispose() yourself.
public SPpowerPlantList loadProjectsFromServer(DateTime timestamp, string note, string sqlServer, string database)
{
using(var sqlConnection = new SqlConnection(String.Format(#"Integrated Security=SSPI;server={0};Initial Catalog={1};", sqlServer, database)))
{
sqlConnection.Open();
var selectstring = "SELECT * FROM [dbo].[tblSPpowerPlant]"; //(WHERE note {0} = " + note + " AND timestamp {1} = " + timestamp;
var sqlSelectCommand = new SqlCommand(selectstring, sqlConnection);
sqlSelectCommand.CommandType = CommandType.Text;
sqlSelectCommand.CommandText = selectstring;
SPpowerPlantList powerPlantList = new SPpowerPlantList();
using(var reader = sqlSelectCommand.ExecuteReader())
{
while (reader.Read())
{
foreach (SPpowerPlant powerPlant in powerPlantList)
{
powerPlant.ID = reader.GetInt32(0);
powerPlant.projectName = reader.GetString(1).ToString();
powerPlant.location = reader.GetString(2);
powerPlant.shortName = reader.GetString(3);
powerPlant.numberOfWtgs = reader.GetInt32(4);
powerPlant.mwWtg = reader.GetDouble(5);
powerPlant.mwTotal = reader.GetDouble(6);
powerPlant.projectShareWeb = reader.GetDouble(7);
powerPlant.mwWeb = reader.GetDouble(8);
powerPlant.phase = reader.GetString(9);
powerPlant.phaseNumber = reader.GetString(10);
powerPlant.phaseDescription = reader.GetString(11);
powerPlant.projectProgress = reader.GetDouble(12);
powerPlant.mwDeveloped = reader.GetDouble(13);
powerPlant.projectManager = reader.GetString(14);
powerPlant.spaceUrl = reader.GetString(15);
powerPlant.country = reader.GetString(16);
powerPlant.technology = reader.GetString(17);
powerPlant.state = reader.GetString(18);
powerPlant.allPermits = reader.GetDateTime(19);
powerPlant.cod = reader.GetDateTime(20);
powerPlant.stateSince = reader.GetDateTime(21);
powerPlant.spID = reader.GetInt32(22);
powerPlant.currency = reader.GetString(23);
powerPlant.possibleWtgTypes = reader.GetString(24);
powerPlant.hubHeight = reader.GetString(25);
powerPlant.visibility = reader.GetString(26);
powerPlant.templateName = reader.GetString(27);
powerPlantList.Add(powerPlant);
}
}
}
}
return powerPlantList;
}
If you remove that foreach part you can see the problem.
You check if the reader is open
you iterate over the powerplant list, by the way this is reassigning each powerPlant to the same record in the reader
You close and dispose of the reader
Now you check if it is open again at the top of the while which throws the exception
I believe you want to create a new list of SPpowerPlant objects from your reader. You should change your code to the following which does that and releases the reader. Note that you should wrap all your Disposable objects in using statements like with the reader below.
using(var reader = sqlSelectCommand.ExecuteReader()) // closes and disposes reader once it is out of scope
{
while (reader.Read())
{
var powerPlant = new SPpowerPlant();
powerPlant.templateName = reader.GetString(27);
//// rest of calls to populate your item
SPpowerPlantList.Add(powerPlant);
}
}
This is my code:
db.Open();
string updateString = "SELECT TOP 1 RTRIM(kol) kol, RTRIM(adres) adres, RTRIM(numwave) numwave FROM sorters WHERE kodprod=#kodprod AND sorter_kod=#sorter AND moved_ok IS NULL ORDER BY CAST(kol as int)";
try
{
SqlCommand command = new SqlCommand(updateString, db);
//command.Parameters.AddWithValue("#numdoc", NumDoc);
command.Parameters.AddWithValue("#kodprod", KodProd.Id);
command.Parameters.AddWithValue("#sorter", SorterKod);
SqlDataReader reader = command.ExecuteReader();
reader.Read();//here error
Kol = reader["kol"].ToString();
Adres = reader["adres"].ToString();
NumWave = reader["numwave"].ToString();
NumDoc = reader["numdoc"].ToString();
reader.Close();
}
catch (Exception ex)
{ }
Why do I get this error when I run my code?:
Invalid attempt to read when no data is present
You can check whether the DataReader is ready to fetch the rows
if(reader.HasRows)
{
//do the coding here
}
I believe the error will in fact occur on the next line, viz when you access the reader via the index [] operator. What you need to do is check the result of reader.Read() before accessing it:
if (reader.Read())
{
Kol = reader["kol"].ToString();
Adres = reader["adres"].ToString();
NumWave = reader["numwave"].ToString();
NumDoc = reader["numdoc"].ToString();
}
Since you are only returning a maximum of one row (TOP 1) there will either be zero or one rows.
you should do a while loop to check reader contain data. You can also use IF if you are sure the query return only one row. If more than one row you should use While. In your case IF also do the job because you are only taking TOP1
string updateString = "SELECT TOP 1 RTRIM(kol) kol, RTRIM(adres) adres,
RTRIM(numwave) numwave FROM sorters WHERE
kodprod=#kodprod AND sorter_kod=#sorter
AND moved_ok IS NULL ORDER BY CAST(kol as int)";
try
{
SqlCommand command = new SqlCommand(updateString, db);
//command.Parameters.AddWithValue("#numdoc", NumDoc);
command.Parameters.AddWithValue("#kodprod", KodProd.Id);
command.Parameters.AddWithValue("#sorter", SorterKod);
SqlDataReader reader = command.ExecuteReader();
while(reader.Read())
{
Kol = reader["kol"].ToString();
Adres = reader["adres"].ToString();
NumWave = reader["numwave"].ToString();
NumDoc = reader["numdoc"].ToString();
}
reader.Close();
}
Use reader.HasRows
string updateString = "SELECT TOP 1 RTRIM(kol) kol, RTRIM(adres) adres, RTRIM(numwave) numwave FROM sorters WHERE kodprod=#kodprod AND sorter_kod=#sorter AND moved_ok IS NULL ORDER BY CAST(kol as int)";
try
{
SqlCommand command = new SqlCommand(updateString, db);
//command.Parameters.AddWithValue("#numdoc", NumDoc);
command.Parameters.AddWithValue("#kodprod", KodProd.Id);
command.Parameters.AddWithValue("#sorter", SorterKod); SqlDataReader
reader = command.ExecuteReader();
if(reader.HasRows)
while(reader.Read())//here error
{
Kol = reader["kol"].ToString();
Adres = reader["adres"].ToString();
NumWave = reader["numwave"].ToString();
NumDoc = reader["numdoc"].ToString();
}
reader.Close();
}
catch{}
EDIT: sorry for the bad formatting, posting code from the Android app is a mess.
EDIT: See Microsoft example here
I can not pass one value from one class to another, when i try, the value pass to 0 instead the value from the first class.
I have this: an method that will check if the person is in the database, and the variable IDautor will gain the id is on the database, it will enter in the if clauses then the array id2 in the position 1 will save the value from IDautor... I pretend to use that value in the class Artigo, but the value came always 0 and i don't no why
Class Autor
public bool Login(TextBox txtUser, TextBox txtPassword)
{
string utl, pass;
try
{
utl = txtUser.Text;
pass = txtPassword.Text;
_Sql = "Select Count(IDAutor) From Autor Where uUser = #uUser and Pass = #Pass";
SqlCommand cmd = new SqlCommand(_Sql, Conn);
cmd.Parameters.Add("#uUser", SqlDbType.VarChar).Value = utl;
cmd.Parameters.Add("#Pass", SqlDbType.VarChar).Value = pass;
Conn.Open();
IDautor = (int)cmd.ExecuteScalar();
if (IDautor > 0)
{
MessageBox.Show("Bem Vindo");
Conn.Close();
id2[1] = IDautor;
return true;
}
else
{
MessageBox.Show("Tera que tentar de novo");
Conn.Close();
return false;
}
}
catch(Exception ex)
{
MessageBox.Show("ERRO Message: "+ ex);
Conn.Close();
return false;
}
}
public int[] id2
{
get { return this.id2; }
}
and in trying to save the value in array id2 and use that value in another class
Class Artigo
public string AddArtigo(string newArtigo)
{
if (newArtigo == null)
{
return "Nao selecionou o PDF desejado. Tente de novo";
}
if (newArtigo != null)
{
using (FileStream st = new FileStream(newArtigo, FileMode.Open, FileAccess.Read))
{
SqlConnection Conn = new SqlConnection(#"Data Source=.\SQLEXPRESS;AttachDbFilename=C:\Users\Convidado1\Desktop\AplicaƧao C#\AplicaƧao\ITArtiConf\ITArtiConf\Database1.mdf;Integrated Security=True;User Instance=True");
Autor au = new Autor();
byte[] buffer = new byte[st.Length];
st.Read(buffer, 0, (int)st.Length);
st.Close();
Conn.Open();
SqlCommand cmd = Conn.CreateCommand();
cmd.CommandText = "insert into Artigo (idAutor) values('" + au.id2[1] + "')";
cmd.ExecuteNonQuery();
Conn.Close();
SqlCommand cmd1 = new SqlCommand("UPDATE SomeTable SET Artigo=#Artigo WHERE idAutor =" + au.id2[1], Conn);
cmd1.Parameters.AddWithValue("#Artigo", buffer);
Conn.Open();
int i = cmd1.ExecuteNonQuery();
Conn.Close();
}
return "Guardado";
}
return "Error";
}
the au.id2[1] become 0 instead the value on the other class.
Autor au = new Autor();
This line of code creates new Author object, which has all properties set into their default values. You don't call anything more on that object before trying to get id value, so it's value is 0.
You should consider making that property static, what will makes it's value persistent.
The best way would be not to use Autor au = new Autor(); but rather to change the constructor of the Artigo to accept an Autor and save it or some properties as members of Artigo or to change the signature of AddArtigo to accept an Autor.
So, either:
Autor au = new Autor();
au.Login(user, pass); // this should really accept strings and not TextBoxes...
Artigo art = new Artigo(au); // this saves id2[1] as a member somewhere
art.AddArtigo(newArtigo); // why does the Artigo class have an AddArtigo method?
or
Autor au = new Autor();
au.Login(user, pass);
Artigo art = new Artigo();
art.AddArtigo(newArtigo, au);
Either way, there are multiple little issues with your solution (from having an array id2, to a Login method accepting TextBoxes and an Artigo that adds itself, most likely that code would be better suited as part of the Artigo constructor).
Pass Author object to another class.
using this Author object u can access value.
Author _author = new Author();
int value = _author.id[1];
I'm using c# in a ASP.Net web application.I have the following query:
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["chestionar"].ConnectionString);
con.Open();
SqlCommand cmd = new SqlCommand("select * from personal,Intrebari where personal.cod_numeric_personal=#cnp AND Intrebari.id_intrebare=14 AND Intrebari.id_intrebare=15 ", con);
cmd.Parameters.AddWithValue("#cnp", Session["sesiune_cnp"]);
SqlDataReader rdr;
rdr = cmd.ExecuteReader();
while (rdr.Read())
{
lbl1.Text = rdr["Nume"].ToString();
intrebare6.Text = rdr["Intrebari"].ToString();
intrebare7.Text = rdr["Intrebari"].ToString();
}
I want those two values for id_intrebare=14 and 15 to assign it to those 2 labels.How can i refer to those?
In order to read stuff from the reader you need to include it in the select statement for you sql, it is better to select it explicitly rather than use select *.
but you are not currently going to get any results returned because id_intrebare cannot be both 14 and 15
you then need to read id_intreabare ratherr than Intreabari.
Try this, notice the try catch block, I also changed your SQL query.
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["chestionar"].ConnectionString);
string qry="select * from personal,Intrebari where personal.cod_numeric_personal=#cnp AND Intrebari.id_intrebare IN (14,15);
SqlCommand cmd = new SqlCommand(qry, con);
cmd.Parameters.AddWithValue("#cnp", Session["sesiune_cnp"]);
try
{
con.Open();
SqlDataReader rdr= cmd.ExecuteReader();
if(rdr.HasRows)
{
while (rdr.Read())
{
lbl1.Text = rdr["Nume"].ToString();
intrebare6.Text = rdr["Intrebari"].ToString();
intrebare7.Text = rdr["Intrebari"].ToString();
}
}
}
catch(SQLException ex)
{
lblStatus.Text="An error occured"+ex.Message;
throw ex;
}
finally
{
con.Close();
con.Dispose();
}
If you want to assign texts to different numbered lables in a loop, you can refer to the control id with FindControl of the current page
int numeOrdinal = reader.GetOrdinal("Nume");
int intrebariOrdinal = reader.GetOrdinal("Intrebari");
int i = 1;
while (rdr.Read()) {
// Nume (Romanian) = Name
page.FindControl("lbl" + i).Text = reader.IsDBNull(numeOrdinal)
? ""
: rdr.GetString(numeOrdinal);
// Intrebari (Romanian) = Question
page.FindControl("intrebari" + i + 5).Text = reader.IsDBNull(intrebariOrdinal)
? ""
: rdr.GetString(intrebariOrdinal);
i++;
}
Try using cmd.ExecuteScalar it will return the first reuslt it finds so you have to define your conditions well. Also it returns object type so you will have to cast the result