How to get double value with SqlDataReader - c#

I'm trying read data from sql database. When I run the code, it gives an error when it comes to where it should read data.
"System.InvalidCastException: Specified cast is not valid."
I get an error. I researched my mistake but couldn't find the solution that works for me. While the query text I wrote works in ssms, it does not work in code.
private void pbx_frame_MouseUp(object sender, MouseEventArgs e) //
{
//take cropped image to picture box of crooped images
try
{
string[] resim = lbx_raw_image.SelectedItem.ToString().Replace(':','.').Split('.');
string sorgu_sql = "Data Source=DESKTOP-OON7EET\\SQLEXPRESS;Initial Catalog=Target;Integrated Security=True;"; //sql bağlantısı kuruldu
//string query = "SELECT * FROM MP_Data$ WHERE time= '19.53.06'"; //'" + lbx_raw_image.SelectedItem.ToString() + "'"; //time=19.53.06 tek bir veriyi çağrır. muhtemelen yorum haline getirilen kısım olacaktı.
string query = "SELECT * FROM MP_DATA_15_mayıs_2019$ WHERE time='" + lbx_raw_image.SelectedItem.ToString() + "'"; //12.50.23
DB_islem db = new DB_islem(sorgu_sql, query); //
pic_info_from_MP = db.Raw_Image(pic_info_from_MP);
public Target Raw_Image(Target pic_info)
{
sql.Open();
sql_read = sql_command.ExecuteReader();
//while (sql_read.Read())
if (sql_read.Read())
{
pic_info.lat = sql_read.GetDouble(0);
pic_info.lon = sql_read.GetDouble(1);
pic_info.alt = sql_read.GetDouble(2);
pic_info.yaw = sql_read.GetDouble(3);
}
sql.Close();
return pic_info;
}
SOLUTİON:
ALTER TABLE table1(name of table) ALTER COLUMN clmn1(name of column) float(datatype);
I determined datatype for each column using the above query. helped me to call the required data.

The reason I asked for the table definition is because there are particular column types on the DB side that map to particular data types on the C# side. The screenshot posted is not enough to realistically determine the column types. The lat and long aren't real, otherwise they'd be truncated but other than that we can't really say
Broadly speaking:
If you've used real column type, call GetFloat(..)
If you've used float column type, call GetDouble(..)
If you've used decimal(or numeric) column type, call GetDecimal(..)
GetXxx will not convert for you because it does an unboxing cast. If your reader has a decimal in column 0 you can only call GetDecimal on it. You cannot call GetDouble and expect you really-a-decimal to be converted to a double, for the same reason as this doesn't work:
object o = 0.1m; //decimal boxed inside object
double d = (double)o;
Unboxing casts and converting casts are different things. If you want your decimal-in-an-object as a double you have to cast twice, once to unbox and once to convert:
object o = 0.1m; //decimalboxed inside object
double d = (double)(decimal)o;
Similarly if your thing inside reader column 0 is a decimal and you want a double you must get it as a decimal, because that's what it really is, and then convert it:
var dbl = (double)reader.GetDecimal(0);
Simple rule:
Pull it out according to what it really is, then convert it
As to what you have, we don't know; your yaw could be a real and cannot be GetDouble'd (has to be GetFloat'd). Your alt is probably a decimal (do you really need altitude to the tenth of a picometer/pico-ft?) and cannot be GetDouble'd (has to be GetDecimal'd) .. but you have all the necessary info to solve this one yourself.
If all else fails and the above just went completely over your head "try changing GetDouble to GetDecimal for the line that doesn't work. And if that doesn't work, try changing it to GetFloat. And if that doesn't work, supply the table definition and we'll tell you what it should be"
Update: youve indicated they're all varchar. Personally I would convert them to float or real - open SSMS, Design the table, change the column type to eg float and save the table. Then they can be GetDouble'd

First of all you should execute your queries ONLY with parameters.
Secondly, we don't know your table schema - please show it.
But most probably there is problem in how you store this value. GetDouble doesn't do any conversions, so your data should already be saved as double.
What's more, there can be problem with globalization. What you should do is:
using System.Globalization;
//...
double result = double.NaN;
if(!sql_read.IsDbNull(0))
{
string s = sql_read.GetString(0);
result = Convert.ToDouble(s, CultureInfo.InvariantCulture);
}

Related

How to transform a different notation floating point number to double?

I'm currently trying to convert a few numbers from a DB2 Server into double values in C#.
The getting of the data from the DB2 Server is not a Problem, and I get the data into a DataTable quite easily. The Problem then Comes when I try to convert the objects into double values, as the Notation is different (, instead of . as example).
Thus the code:
foreach (DataRow row in DataTable myResultTable)
{
double myValue = String.IsNullOrEmpty(row["myValue"].ToString())? 0 : (double)row["myValue"]; // myValue has 1234,56 as Content.
}
Fails with an exception that the value can't be converted.
The datatype of the field myValue in the db2 is Decimal with a length of 16.
As I didn't find anything, I thought about converting it to string, formating it there and then transform that into a double but that seems quite....complicated to me for something that should be easy (and complicated always means prone to Errors because of something unexpected).
So my question is: Is there any easy way to do this Transformation?
Edit:
As it was asked a GetType on row["myValue"] results in: {Name = "Decimal" FullName = "System.Decimal"}.
The real solution is to cast to decimal not to double:
var value = row["myValue"] is DBNull ? 0m : (decimal)row["myValue"];

How to read a decimal value of order 0.000e-6 from a SqlDataReader in C# double variable

I am trying to read some decimal values from my DB. These values are the order of 10-6. I am trying to read it into a double variable in C# using code like this: sqltype in database is "float". sample value to be read is "1.99999999495049E-06" –
Double [] rmseValues = null;
while (dataReader.Read())
{
// This shows my datatype is float (sql)
string temp = dataReader.GetDataTypeName(0);
// This returns a value of "0"
string temp1 = dataReader.GetOrdinal("RmseAll").ToString();
// This throws exception of invalid typecast
rmseValues[0] = dataReader.GetFloat(0);
}
Try to use GetDouble(0) instead of GetFloat(0)
I think you will also need to edit that line :
Double [] rmseValues = null;
In fact your are trying to put values inside a null object as solution you need to initialize your rmseValues array or just use a List of double
Double[] rmseValues = new Double[10];
Use GetInt64(0) instead of GetFloat(0)
In order not be dependent on RDBMS actual background type (say, NUMBER(10, 3) or alike) and its representation as .Net Type (e.g. Single) do a conversion:
// rmseValues[0] should be Double
rmseValues[0] = Convert.ToDouble(dataReader.GetValue(0));

Why use Parse to turn a string into an int?

I have made a little calculator:
private void button1_Click(object sender, EventArgs e)
{
int input1 = int.Parse(textBox1.Text);
int input2 = int.Parse(textBox2.Text);
int Result = input1 + input2;
textBox3.Text = Result.ToString();
}
Why can't I just do textBox3.Text = Result; when I already told them that the result is int type in the line before?
When I need to explain data types, I often use the analogy with shapes.
A data type is a shape, that forms the behaviour of the variable of the specified type. When a variable of a given type is created it holds the description of the type and a value. Variables with the same shape can be connected together with the help of operators (for example +).
Two variables from a different type (shape) can not be connected directly together - they need a converter / wrapper.
A converter makes for example from the shape triangle a circle or a wrapper masks the triangle as a circle.
Back to your example. TextBox controls can hold only the data type string, meaning they are incompatible with the shape of an int. You already have converted the content of the string to an int using int input1 = int.Parse(textBox1.Text);.
That is why you can not simply assign the Result variable to the Text property - their shapes are different, so you need to convert the int back to string using the ToString() method. You could also write textBox3.Text = (input1 + input2).ToString();.
The shape analogy can be used to understand parameters passing - as long you know the signature of a method int add(int a, int b), you know exactly what you need to put when you are calling a method (two int's) and what kind of type to expect as a result (an int). For example String result = add(1,2); will not work because the signature is not as expected, result should be of type int in order to work (int result = add(1,2);) or the call to add(1,2) should be converted to string (string result = add(1,2).ToString();).
Same goes with classes and objects - a class is a custom data type, so a custom shape. As long two instances of a class (objects) have the same shape they can be connected or assigned to each other.
This is a very simplified explanation (but still it helped my trainee in the past) so take your time and have a look at the C# MSDN documentation for a thorough explanation of data types.
Why can't I just do textBox3.Text = Result; when I already told them
that the result is int type in the line before?
Even though you 'told' that the result would be of type int, the compiler needs to know how to interpret/transform the string into an int.
int.Parse is one way of doing just that.
Sounds like you may want to start here with C# Data Types. As for your question. TextBox.Text is of type string. Check out MSDN articles for the different controls that you're using and their properties, such as this MSDN Article on TextBox.Text
textBox3.Text is a type of string while Result is a type of int and in your code you are assigning int value to a string which is wrong. You need to transform ones type to the other.

Error Converting data type 'Numeric' to Decimal (help!)

Good Day Everyone,
As of now im stuck with this error
Error Converting data type 'Numeric' to Decimal
this is my code
AddManualItems AddReconItem = new AddManualItems();
UserAccess user = new UserAccess();
AddReconItem.BranchCode = BranchCodeTextBox.Text;
AddReconItem.ForLoanMonth = YearDropDownList.SelectedValue + "/" + MonthDropDownList.SelectedValue;
AddReconItem.ItemWeight = Convert.ToDecimal(WeightTextBox.Text);
AddReconItem.PrincipalAmount = Convert.ToDecimal(PrincipalTexAmTextBox.Text);
AddReconItem.PawnTicket = PwnTicketTextBox.Text;
AddReconItem.ItemStorageGroup = Convert.ToInt16(StorageNameDropDownList.SelectedValue);
AddReconItem.ReconID = Convert.ToInt16(ReconTypeDropDownList.SelectedValue);
user.UserID = Session["UserID"].ToString();
string a = servs.AddItemRecon(user, AddReconItem); // this is where the error appears in debug mode
the code inside of the ADDitemRecon(User,AddReconItem) is this
using (SqlConnection reportsConn = new SqlConnection(sqlConnWriter))
{
reportsConn.Open();
SqlCommand AddReconItem = new SqlCommand();
AddReconItem.Connection = reportsConn;
AddReconItem.CommandType = CommandType.StoredProcedure;
AddReconItem.CommandText = "Updater.usp_AddReconcileItems";
AddReconItem.Parameters.AddWithValue("#ITEMWEIGHT", Convert.ToDecimal( items.ItemWeight));
AddReconItem.Parameters.AddWithValue("#ITEMPRINCIPALAMT", Convert.ToDecimal(items.PrincipalAmount));
AddReconItem.Parameters.AddWithValue("#FORLOANMONTH", Convert.ToDateTime(items.ForLoanMonth));
AddReconItem.Parameters.AddWithValue("#STORAGEGROUPID", items.ItemStorageGroup);
AddReconItem.Parameters.AddWithValue("#BRANCHCODE", items.BranchCode);
AddReconItem.Parameters.AddWithValue("RECONID", items.ReconID);
AddReconItem.Parameters.AddWithValue("#PAWNTIX",items.PawnTicket);
AddReconItem.Parameters.AddWithValue("#CREATEDBY", user.UserID.ToString());
AddReconItem.ExecuteNonQuery();
}
my property for ItemWeight is
private decimal itemWeight;
public decimal ItemWeight
{
get { return itemWeight; }
set { itemWeight = value; }
}
i bet the error is in the item weight because when i input in the item weight
12345.12 it works fine, but when i input 1234 instead of treating it as 1234.00 it treats it as 1234 only making it numeric..
any help? i do not know if my conversions are wrong
By the way my field in database is
fld_ItemWeight (decimal (38,6), not null
EDIT**
Is there any bugs known in Decimal?? im using VS 2005 as of now.
Found The answer! my stored Procedure is wrong i have decimal(9,6) in my stored procedured making it accept 3 digits or less !changed it to (18,2)\
Although the original poster has found his solution, for the benefit of other people, I thought I would post what caused it for me.
System.Data.SqlClient.SqlException : Error converting data type numeric to decimal.
Sadly the message doesn't say which parameter it is having the problem with. So I changed all of the parameters that I was passing through to have a value of 0 (which is a suitable value for most SQL types, you may need to use other values), this made the error go away. I could then put them back to normal, one by one, and each time, I re-tested. That's how I worked out which parameter had the problem.
It turned out that for one of the parameters the value that I had in my code (a C# decimal) was too large to go in the decimal(7,2) stored procedure parameter.
I don't know what the proper solution for this issue , But i have one idea. Like
Change your ItemWeight property DataType decimal to string
decimal xxxyyy = Convert.ToDecimal(WeightTextBox.Text);
if(!xxxyyy .ToString().Contains(".00))
{
AddReconItem.ItemWeight=xxxyyy.ToString() +".00";
}
else
{
AddReconItem.ItemWeight=xxxyyy.ToString() ;
}
Edit :
Try this another way for use math.Round()
AddReconItem.ItemWeight = Convert.ToDecimal(WeightTextBox.Text);
AddReconItem.ItemWeight=Math.Round(AddReconItem.ItemWeight,2);
Try to round your value in set.
private decimal itemWeight;
public decimal ItemWeight
{
get { return itemWeight; }
set { itemWeight = Math.Round(value,yourPrecisionHere); }
}
Change Sql column to Decimal(18,2), Same in store procedure and take SqlDbType.Decimal at ado.net end
My problem was that the column had the right precision and scale(16,2) but the variable I was using as a parameter in the procedure hadn't(14,2).
So, when trying to insert something like 99999999999999 using the procedure, I was getting the error Error converting data type numeric to numeric.
when you are calling a procedure and it has a parameter with a decimal datatype then you can pass only in fractions. For more details please refer Error converting data type numeric to decimal

C# object and string conversion

I have following section of code in my program:
object val;
val = arr[1].Trim(); // in my case i am getting value here is 1.00
now when I am assigning value to a datarow I am getting error
Expected int64 value.
datarow[Convert.ToString(drow["col"]).Trim().ToUpper()] = val;
I am not facing any issue when getting value other that 1.00.
What could be the exact problem? How can I solve it?
Suggestions and solutions are welcome
If that column in your datatable is expecting an Int64 you need to convert val (which is a string) to an Int64:
var val = arr[1].Trim(); // String at this point
long longVal = 0;
if(!long.TryParse(val,out longVal){
throw new InvalidOperationException("value wasnt an Int64!");
}
datarow[Convert.ToString(drow["col"]).Trim().ToUpper()] = longVal
arr[1] seems to be string, and applying .Trim() keeps it as a string, even if it's "1.00". If you need an integer, you need to parse it. However, it can't be parsed to an intteger, because it's actually a double.
As a proof of whether I'm right or not, you can try (Int64)double.Parse(val) and that should work. However, it's up to you to decide whether that's not an issue for your program. There's two possible issues:
val might not be parse-able to double, in which case you will get an exception
val might be a double, but not one that can be represented as an int (too large, or lose precision ex. "1.8" would become 1)
Hope this helps

Categories