hey guys m having this wierd exception of cast though my datatypes are correct in db:
string sql =
string.Format(
#"select aim_network_id,aim_network_name,oxinetwork_id,pack_id,pack_name,p_face_value,pm_prefix from Operator where aim_network_id='{0}'",
gridbackOffice["aim_network_id", gridbackOffice.CurrentCell.RowIndex].Value);
OleDbCommand getSelectedGridDatecmd = new OleDbCommand(sql, conn);
OleDbDataReader reader = getSelectedGridDatecmd.ExecuteReader();
while (reader.Read())
{
txtAimNetworkID.Text = reader.GetString(0);
txtAimNetworkName.Text = reader.GetString(1);
txtPARNetworkID.Text = reader.GetString(2);
txtPARFaceValue.Text = reader["p_face_value"].ToString();
//in above line if i'm doing this `reader.GetString(5)` then i'm getting specified cast exception and that to randomly i.e some time it works fine and suddenly sometime gives this exception
txtPARPackID.Text = reader.GetString(3);
txtPARPackName.Text = reader.GetString(4);
txtPARPMPrefix.Text = reader["pm_prefix"].ToString();
}
I'm little bit confused if m using this reader["p_face_value"].ToString() then my code is running very smoothly but whats the issue with using this reader.GetString(5) , according to me both method return string, nebody had faced this error b4 ?
....Error is at 4th and 7th line in while loop.
Exception:Specified cast is not valid (InvalidCastException unhandled)
According to MSDN, OleDbDataReader.GetString() does not perform any conversions before attempting to cast to a string - therefore the data retrieved must already be a string.
If there is a chance that the value in that column could be null, the docs suggest that you should check if the value is null first:
if ( !reader.IsDBNull(5) ) {
txtPARFaceValue.Text = reader.GetString(5);
}
Calling reader["p_face_value"] on a null value returns DBNull - and when you call ToString() on DBNull, you get an empty string.
From MSDN:
No conversions are performed;
therefore the data retrieved must
already be a string.
If the column is not a string type, you'll need to use the .ToString() method to convert it.
What is the datatype of p_face_value in your database?
Based on the error description given it seems that this is not a string type, so when you call:
reader.GetString(5)
the code errors out as it cannot convert whatever type it is to a string. The .ToString() method will work as this does not use a cast.
You should use GetString only when the column is a string-equivalent type in the database (like varchar), in your case "p_face_value" seems to be a numeric type, therefore it cannot simply convert it to a string.
The way you're doing it right now is the right way.
Related
I have a sqlite table with "very small values" in one column. Like 0.00000363455000.
When I run a query in "DB Browser for SQlite" the values are shown correct:
Screenshot DB Browser for SQlite 1
In my c# application the small values are always 0.
using (SQLiteConnection connection = new SQLiteConnection(
"Data Source='" + dmaDataSource + "'"))
{
SQLiteCommand command = new SQLiteCommand(sqlQuery, connection);
connection.Open();
SQLiteDataReader reader = command.ExecuteReader();
if (reader.HasRows)
{
response = new DmaResponse();
while (reader.Read())
{
Type t0 = reader.GetFieldType(0); // is decimal
Type t1 = reader.GetFieldType(1); // is decimal
string f0 = reader.GetName(0);
string f1 = reader.GetName(1);
response.price_per_ton = (decimal)reader[0];
string test = reader[1].ToString(); // "0"
response.price_per_mm3 = (decimal)reader[1]; // 0.00000363455000 becomes 0
}
}
}
Any Ideas?
After some more tests:
Both fields are type of NUMERIC:
which is decimal in c#.
I tried the GetDecimal method before I created this post.
response.price_per_ton = reader.GetDecimal(0);
string test = reader[1].ToString();
response.price_per_mm3 = reader.GetDecimal(1);
GetDecimal(0) works, GetDecimal(1) throwed an exception:
{"Input string was not in a correct format."}
Then I used DB Browser to change the decimal separator in "my" row form , to .
Now, reader.GetDecimal(1) doesn't throw an exception anymore, but gives back 0.
Based on the documentation of sqlite, the fundamental data types are:
64-bit signed integer
64-bit IEEE floating point number
string
BLOB
NULL
In your case, it would be a 64-bit IEEE floating point number.
The Microsoft.Data.Sqlite.Core library (note that I am assuming you are using this), uses decimal.Parse on the result of GetString if you use GetDecimal on the reader.
This means that the field is retrieved as a string, causing an auto-convert of the value from numeric to text, and then a conversion back to a number with decimal.Parse. This has lots of ways that it could go wrong.
If you use GetDouble, the native method sqlite_column_double is used in the driver, and there will be no conversions (and I expect therefore no invalid formats).
A double is less precise than a decimal, so you'd probably want to convert the double to decimal before doing calculations with it.
For the smallest possible margin of error, store the decimals as a string in the database, that way you avoid any auto-convert (but will use more bytes to store the same data).
I'm getting closer to it:
ServerVersion = "3.37.0"
Column[1] is type of System.Decimal and the expected value is 0.00000363455000.
reader[1].ToString() returns "0"
(decimal) reader[1] returns 0
reader.GetDecimal(1) throws an exception:
Input string was not in a correct format.
reader.GetString(1) returns "0,00000363455000" (German decimal separator)
which I can cast to decimal.
Now I have my expected value but I don't know why.
As of now I am encountering this kind of bug
Error converting data type float to decimal.
or
Error converting data type Numeric to decimal
This is my code
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.Add("#varible",SqlDbType.Decimal
AddReconItem.Parameters.AddWithValue("#ITEMWEIGHT", Math.Round(Convert.ToDouble(WeightTextBox.Text+".00"), 2));
AddReconItem.Parameters.AddWithValue("#ITEMPRINCIPALAMT", Math.Round(Convert.ToDouble(PrincipalTexAmTextBox.Text + ".00"), 2));
AddReconItem.Parameters.AddWithValue("#FORLOANMONTH", Convert.ToDateTime(YearDropDownList.SelectedValue + "/" + MonthDropDownList.SelectedValue));
AddReconItem.Parameters.AddWithValue("#STORAGEGROUPID", StorageNameDropDownList.SelectedValue);
AddReconItem.Parameters.AddWithValue("#BRANCHCODE",BranchCodeTextBox.Text);
AddReconItem.Parameters.AddWithValue("RECONID", ReconTypeDropDownList.SelectedValue);
AddReconItem.Parameters.AddWithValue("#PAWNTIX",PwnTicketTextBox.Text);
AddReconItem.Parameters.AddWithValue("#CREATEDBY", Session["UserID"].ToString());
AddReconItem.ExecuteNonQuery();
}
When I input, 123 for principalamt and itemweight it accepts the answer and treats it as a decimal, but when I input 1234 for itemweight and still 123 for Principalamt it shows that error, if I remove the conversion and change it to Convert.ToDecimal it shows Error converting data type Numeric to decimal if I use it as text it shows Error converting data type varchar to decimal
Is this a bug or something? I can't seem to find a way I tried many options but none of them have been working
My database columns are below:
I really hope you can help me understand this phenomenon
EDIT
This is the first time I saw a program accepting 123 as a valid input while 1234 is not, my database Decimal (38,6) is very large enough to accommodate this input that's why I'm looking for the answer or known bugs that can solve this problem, thank you.
I'd suggest using Decimal.TryParse instead of Convert for your principalamt value and then maybe debugging and inspecting how the value gets converted to a valid Decimal for your Money column. For example something like;
bool valid;
var dbl = Convert.ToDouble("1234.00");
valid = Double.TryParse("1234.00", out dbl);
var dcml = Convert.ToDecimal("1234.00");
valid = Decimal.TryParse("1234.00", out dcml);
I'm not sure if you should be using Double as a data type when trying to store the resultant value in a Decimal field. Double represents floating type numbers and I think you should be using the Decimal data type for your Money column as mentioned in this answer.
For ItemWeight, with a data type of decimal(38,6), you'll end up with 6 decimal places regardless of your rounding I think. Try the following in SQL Server and make sure the parameter type for #ITEMPRINCIPALAMT is DECIMAL as well (similar to my example below).
DECLARE #Var decimal(38,6) = 1234.00
DECLARE #Tbl AS TABLE
(
Test decimal(38,6)
)
INSERT INTO #Tbl (Test) Values (#Var)
SELECT * FROM #Tbl
Im importing a csv to my sql server table using the following code
SqlCommand nonqueryCommand = myConnection.CreateCommand();
nonqueryCommand.CommandText =
"INSERT INTO MYTABLE VALUES(#num1, #num2,#num3,#num4)";
nonqueryCommand.Parameters.Add("#num1",SqlDbType.Decimal);
nonqueryCommand.Parameters.Add("#num2", SqlDbType.Decimal);
nonqueryCommand.Parameters.Add("#num3", SqlDbType.Decimal);
nonqueryCommand.Parameters.Add("#num4", SqlDbType.Decimal);
nonqueryCommand.Parameters["#num1"].Value = crntRecord[0];
nonqueryCommand.Parameters["#num2"].Value = crntRecord[1];
nonqueryCommand.Parameters["#num3"].Value =crntRecord[3];
nonqueryCommand.Parameters["#num4"].Value = crntRecord[4];
nonqueryCommand.ExecuteNonQuery();
where the parameter 3 and 4 are of type decimal(9,6) in the DDL when i execute the code at ExecuteNonQuery i get the following exception
Failed to convert parameter value from a String to a Decimal.
please help me find out the problem tnx.
EDIT
the value in the crntRecord[3] looks like
Assuming that crntRecord is an array of strings, you need to parse the strings to a decimal first.
Ex:
nonqueryCommand.Parameters["#num3"].Value = decimal.Parse(crntRecord[3].ToString());
Note that this will throw an exception if crntRecord[3] is not parseable to a decimal; if that's a situation that could occur, look into decimal.TryParse() instead.
Edited to use safer parsing methods
Your strings have surrounding quotes that you need to strip off. Try
decimal num3;
bool isDecimal = decimal.TryParse(crntRecord[3].Trim(new []{'\"'}), out num3);
if(isDecimal)
nonqueryCommand.Parameters["#num3"].Value = num3;
I would recommend using this method for all of your decimals, which would mean putting this logic in a reusable function would be a rise refactoring.
try with
nonqueryCommand.Parameters["#num1"].Value = Convert.ToDecimal(crntRecord[0]));
nonqueryCommand.Parameters["#num2"].Value = Convert.ToDecimal(crntRecord[1]);
nonqueryCommand.Parameters["#num3"].Value =Convert.ToDecimal(crntRecord[3]);
nonqueryCommand.Parameters["#num4"].Value = Convert.ToDecimal(crntRecord[4]);
Use
nonqueryCommand.Parameters.AddWithValue("#num1", crntRecord[0]);
Im trying to convert the Id field to send it to the DB but in the DB the type is bigInt:
var ID_Inscricao = (Label)row.FindControl("Label1");
How do I convert this to a type that is compatible with bigInt? I have tried cast and convert but neither worked.
You need to convert the value in the label's Text property to an integer of some sort:
string labelText = ((Label)row.FindControl("Label1")).Text;
var ID_Inscricao = Convert.ToInt64(labelText);
Beware that this could throw an exception if the text value is not a number.
You will have to take the Text property and convert that. You can't cast a control to a value.
Hint: Use the appropriate TryParse.
This may help you,
var ID_Inscricao = (Label)row.FindControl("Label1");
var ID_Inscricao_val = parseInt(ID_Inscricao.innerHTML);
using "Replace" on the string clientNameStr causes an "Object Reference Not Found" error.
// Get client name
clientName = currentUser.GetValue("ClientName");
string clientNameStr = (string)clientName;
string clientURLStr = string.Empty;
clientURLStr = clientNameStr.Replace(' ', '-');
// clientURLStr = "ST9215-Stanic-Parts-Ltd";
If I substitute in the commented out string (and comment out the existing one) it works fine, so it must be something to do with the replace function, but what? Have tried it with both " and ' quote marks, to the same result.
Any help would be greatly appreciated.
Thanks, Oli.
That basically shows that currentUser.GetValue("ClientName") is returning a null reference1.
We can't tell what currentUser.GetValue("ClientName") does, but there are two options:
It's correctly returning null, and you should handle that
It shouldn't return null, and you need to fix it (possibly to throw an exception if it encounters this situation)
1 It's possible that it's returning a non-null reference and using a user-defined conversion to string in the next line which returns null - but unlikely. We can't tell for sure because we don't know the type of the clientName .
Probably clientName (and thus clientNameStr) is null. You cannot call methods on the null object, even if you know that it should be a string.
It's possible that currentUser.GetValue("ClientName") is returning null, thus throwing an error when trying to execute the Replace.
Better coding would be
clientName = currentUser.GetValue("ClientName");
string clientNameStr = clientName ?? "";
string clientURLStr = clientNameStr.Replace(' ', '-');