InvalidCastException in returning most recently added column - c#

I want to return the last column of most recently inserted record from a database table. I keep getting this error:
A first chance exception of type 'System.InvalidCastException' occurred in SchoolManagement.exe
Additional information: Specified cast is not valid.
If there is a handler for this exception, the program may be safely continued
Code:
public int A()
{
string _connection = ConfigurationManager.ConnectionStrings["ApplicationServices"].ConnectionString;
string stmt = "SELECT TOP 1 RegistrationNumber FROM tblStudentBiodata ORDER BY RegistrationNumber DESC";
int count = 0;
using (SqlConnection thisConnection = new SqlConnection(_connection))
{
using(SqlCommand cmdCount = new SqlCommand(stmt, thisConnection))
{
thisConnection.Open();
count = (int)cmdCount.ExecuteScalar();
}
}
return count;
}

Your cast to int is throwing the exception:
count = (int)cmdCount.ExecuteScalar();
Your conversion is not safe, and you are certainly not getting back an integer from the ExecuteScalar method. In fact, the ExecuteScalar method will return the result wrapped (boxed) into an Object so be aware that the object could contain any type (e.g. float, decimal, int etc.).
Also make sure you are not casting from a null value, since that would be returned if there are no records in the table. So make sure to add a check if the object is null before attempting to cast.
Per my explanation, check the type of RegistrationNumber column in SQL server and make sure to cast to the correct type in your C# code.
Here is a list of the type mappings between SQL Server and C#:
http://msdn.microsoft.com/en-us/library/cc716729%28v=vs.110%29.aspx

As already pointed in another answer, below line is causing the exception and fir sure RegistrationNumber column is not INT type. I doubt it would be SQL CHAR or VARCHAR column.
count = (int)cmdCount.ExecuteScalar();
In this case, instead of doing a direct casting, try casting it indirectly using AS operator and declare your count variable as nullable Int like
int? count = 0;
count = cmdCount.ExecuteScalar() as int?;
Then check and use it
if (count != null)
{
//Do something with it
}

Related

Convert SQLite timestamp to DateTime in C#

I am trying to assign a property of an object the value of a column containing a timestamp in SQLite. Currently the property is of type DateTime, but I've tried string type with no change. I've tried using Convert.ToDateTime(rdr.GetString(5).ToString()) with no change.
Here's the exception I get:
System.InvalidCastException: Specified cast is not valid.
at System.Data.SQLite.SQLiteDataReader.VerifyType(Int32 i, DbType typ)
at System.Data.SQLite.SQLiteDataReader.GetDateTime(Int32 i)
at ConsoleHelpTicket.Data.FillQueue(SQLiteConnection conn, Queue`1 queue) in E:\...\Data.cs:line 142
Here's the property declaration:
public DateTime OpenDate { get; set; }
Here's the method where I try the assignment:
public static void FillQueue(SQLiteConnection conn, Queue<Ticket> queue)
{
try
{
var cmd = new SQLiteCommand($"select * from Tickets order by OpenDate desc;", conn);
using SQLiteDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
Ticket ticket = new Ticket();
ticket.Tid = rdr.GetInt32(0);
ticket.Title = rdr.GetString(2);
ticket.Description = rdr.GetString(3);
ticket.OpenDate = rdr.GetString(5); <---------- PROBLEM LINE
ticket.ClosedDate = rdr.GetString(6);
ticket.Open = rdr.GetBoolean(7);
ticket.Location = rdr.GetString(8);
System.Console.WriteLine($"Added TID: {rdr.GetInt32(0)} Title: {rdr.GetString(2)} to queue.");
queue.Enqueue(ticket);
}
}
So I figured out the problem(s).
I was using SQLite's TIMESTAMP as the default column value, and I was allowing that to be set for the column value on every insert. I edited C# insert line to insert DateTime.Now. Yes SQLite supports TimeStamp as a data type, but the documentation says it's really stored as a string. See the documentation
After much troubleshooting I realized I got my column numbers mixed up and I was trying to import parse a bool as time, which obviously will throw an exception. I'm rewriting my code now to be more dynamic to avoid this type of problem in the future.
Finally I ended up using this line ticket.OpenDate = DateTime.Parse(rdr.GetString(6)); to successfully assign the column value to a DateTime property. My thinking is that if SQLite is storing it as a string, I should retrieve it as a string and parse it to DateTime. I'm also storing the value as a native DateTime value from C# instead of relying on the TimeStamp value from SQLite. I haven't tested to see if I can parse a TimeStamp value though.

C# Adding TableAdapter Query #parameter as int and date?

I was creating a query for the Table Adapter that looked like this
SELECT COUNT(*) FROM Trip WHERE ShipCode = #ShipCode
AND Date < #TodayPlusWeek
The thing is this method will expect (string, string) as parameter where I need it to accept int for the (ShipCode) and Date for the (Date)
Any ideas how to do that?
Very much appreciated!
The first part will be to set up a pair of variables of the proper type to hold the correct values for the Sql Parameters:
int iShipCode;
DateTime dtTodayPlusWeek;
Once you have that, we are going to run a TryParse method on your current string variables to convert into our new variables. As I did not know the variable names within your method, I generic'd them to (strShipCode, strTodayPlusWeek). If the TryParse method fails, you can set up default values for the query; I used 0 and Today + 1 week.
if (!int.TryParse(strShipCode, out iShipCode)) {
iShipCode = 0;
}
if (!DateTime.TryParse(strTodayPlusWeek, out dtTodayPlusWeek)) {
dtTodayPlusWeek = DateTime.Now.AddDays(7);
}
Now that we have correct types for the data, we can add that to our existing query as parameters.
StringBuilder sbCmd = new StringBuilder();
sbCmd.Append("SELECT COUNT(*) ");
sbCmd.Append("FROM Trip ");
sbCmd.Append("WHERE (ShipCode = #ShipCode) ");
sbCmd.Append("AND Date < #TodayPlusWeek");
string txtCmd = sbCmd.ToString();
int iQryReturn;
using (SqlCommand cmd = new SqlCommand(txtCmd, conn)) {
cmd.CommandType = CommandType .Text;
cmd.Parameters.AddWithValue("#ShipCode", iShipCode;);
cmd.Parameters.AddWithValue("#TodayPlusWeek", dtTodayPlusWeek);
try {
conn.Open();
iQryReturn = (int)cmd.ExecuteScalar();
}
catch(Exception ex) {
iQryReturn = -1;
// Your Exception handling here
}
finally {
conn.Close();
// Your cleanup code if any
}
}
Not knowing what type of DB setup you have in use, I have written this in ADO for Sql Server. Ad there will only be value returned; the count(*), I have added an integer variable for a return. If there is an error, that value will be set to -1.
It is up to you on implementation and syntactical changes that may be needed for your particular application.

Take the ID of an Table after Select Query in c#

How can I take the ID as a variable from the Select query in c#.
I have written a query which has to select all IDs with a specific Devicetype.
sqlCommand = new SqlCommand("SELECT Id FROM T_Table1 WHERE DeviceType='" + dev + "'" + "", DbConnect());
int id = (int)sqlCommand.ExecuteScalar();
That's the exception:
An unhandled exception of type 'System.InvalidCastException' occurred in test.exe
Additional information: Specified cast is not valid.
First of all you have to check the database type of your 'id' column. If it is bigint, then use long instead of int.
And secondary you should not add the query string to the select statement. That enables hackers later to run a sql injection against your app or service.
Please use Parameters with the SqlCommand object.
string sql= "SELECT Id FROM T_Table1 WHERE DeviceType=#dev";
SqlCommand command = new SqlCommand(sql, DbConnect());
command.Parameters.Add("#dev", SqlDbType.Text);
command.Parameters["#dev"].Value = dev;
long id = (long)command.ExecuteScalar();
try this
int id =Convert.ToInt32(sqlCommand.ExecuteScalar());
You're calling Execute scalar which will return the first value of the first column of the returned datarow IIRC... So you are trying to take the integer value of null, which others have stated, cannot occur.
I would suggest using the ExecuteEnumerable flavor to return a set of Datarows containing your ID's from T_Table1
using (var myCommand = new SqlCommand())
{
var query = string.Format("SELECT ID FROM T_Table1 WHERE DeviceType='{0}'", dev);
var rows = myCommand.ExecuteEnumerable(query);
foreach (var row in rows)
{
// do whatever to each row
var id = row["ID"];
}
}
If the SELECT query finds no matching value in the database, then the return value of sqlCommand.ExecuteScalar() will be null, if I rembember correctly. And null value cannot be cast to int. You need to check the returned value first before doing the cast. Additionally, you might want to change the type to long instead of int, because an int cannot hold all possible bigint values.

Error Unable to cast object of type 'System.Int32' to type 'System.String'

I am using below function to get values from database.
The problem is when i select column of type int.
i get this error Unable to cast object of type 'System.Int32' to type 'System.String'.
in this line result.Add(dr.GetString(0));
Code
[WebMethod]
public static List<string> GetAutoCompleteData(string value, string filterBy)
{
string strConnString = ConfigurationManager.ConnectionStrings["ConnString"].ConnectionString;
using (SqlConnection con = new SqlConnection(strConnString))
{
con.Open();
string command = string.Format("select {0} from Users where {0} LIKE '%'+#SearchText+'%'", filterBy);
using (SqlCommand cmd = new SqlCommand(command, con))
{
cmd.Parameters.AddWithValue("#SearchText", value);
using (SqlDataReader dr = cmd.ExecuteReader())
{
List<string> result = new List<string>();
while (dr.Read())
{
result.Add(dr.GetString(0));
}
return result;
}
}
}
}
Users table structure
UserID type int
UserName type nvarchar(50)
Password type nvarchar(50)
when i select column of type int
According to the code, you're trying to select a column of type string:
dr.GetString(0)
If the column is an int, then get an int:
dr.GetInt32(0)
Which you can then convert to a string for your list:
result.Add(dr.GetInt32(0).ToString());
Specifically regarding the error, note the text in the documentation:
No conversions are performed; therefore, the data retrieved must already be a string.
Try result.Add(dr.GetValue(0).ToString());
To avoid the return of GetValue() being null, do this -
result.Add((sqlreader.IsDBNull(0) ? "" : dr.GetValue(0).ToString());
I faced the same type of error: 'System.Int32' to type 'System.String'
Here if you want to bind string value means
dr.GetString(1)
Either if you want to print int value means
dr.GetInt32(0)
and i got one more error :Specified cast is not valid.
if you want string means u need to put
dr.GetString(1)
initially i did dr.GetString(0) which shows Specified cast is not valid.
same thing if you need int value means you need to put dr.GetInt32(0) not dr.GetInt32(1)

Oracle sql setting integer

I set my table column as integer.
Now I am trying to read it in my c# code using getint32 and for some reason I get a cast error, and when I checked some more I saw that I am getting a decimal from my db. how can that be? Isn't the oracle integer equals to c# int?
using (OracleCommand cmd = new OracleCommand(#"select id,title from table"))
{
cmd.Connection = _conn;
OracleDataReader r = cmd.ExecuteReader();
while (r.Read())
{
Debug.WriteLine(reader.GetFieldType(0)); // <--decimal
//reader.GetDecimal(0);
reader.GetInt32(0); <---cast error
Debugger.Break();
}
r.Close();
}
the id column is set as integer, also tryed number. comfused :S
Have a read at this:
Which .NET data type is best for mapping the NUMBER Oracle data type in NHibernate?
Oracle number maps to .net decimal. Microsoft is aware of this issue.
You shouldn't do that.
An int (System.Int32) is not big enough to hold every possible decimal value. If your column type is decimal, use GetDecimal() method, if your column type is int, use GetInt32() method.
There is no implicitly conversation decimal to int at all.

Categories