How to get number value with Decimal from DataReader - c#

According to the SQL queries below, I need to get a number value 2083.10, but when try to use the code to get int value from dbreader, it will be only 2083. the demical were gone.
string SQLCash = #"SELECT sum(t2.Cash-Change) AS Cash
FROM dbFBHdr t1, dbFBCollection t2
WHERE t1.Branch = t2.Branch
AND t1.CashNo = t2.CashNo
AND t1.CashDate >= '" + PDC.DateFrom + "' " +
"AND t1.CashDate <= '" + PDC.DateTo + "' " +
"AND t1.Status = 'CLOSED'";
FbCommand cmdCASH = new FbCommand(SQLCash, FbCon);
cmdCASH.ExecuteNonQuery();
FbDataReader readerCASH = cmdCASH.ExecuteReader();
while (readerCASH.Read() == true)
{
if (readerCASH["Cash"].ToString() == "")
{
PDC.CASH = "0";
}
else
{
PDC.CASH += String.Format("{0:n}",readerCASH["Cash"]);
PDC.TOCASH = readerCASH.GetInt32(readerCASH.GetOrdinal("Cash"));
}
}
And This is the code which I use it to get Int value from SQL
PDC.TOCASH = readerCASH.GetInt32(readerCASH.GetOrdinal("Cash"));

Since you need to Gets the value as a Decimal object, You need to use SqlDataReader.GetDecimal(Int32) method instead:
readerCASH.GetDecimal(readerCASH.GetOrdinal("Cash"));
Because the GetInt32 method will get the value as a 32-bit signed integer. Also you need to change the TOCASH's type to decimal. Also you should always use parameterized queries to avoid SQL Injection. Something like this:
AND t1.CashDate >= #DateFrom
yourCommand.Parameters.AddWithValue("#DateFrom", PDC.DateFrom);
//And other parameters also
Although specify the type directly and use the Value property is better than AddWithValue. See this https://blogs.msmvps.com/jcoehoorn/blog/2014/05/12/can-we-stop-using-addwithvalue-already/

Don't use GetInt32 if you want to get value as decimal, use GetDecimal
PDC.TOCASH = readerCASH.GetDecimal(readerCASH.GetOrdinal("Cash"));

You are formatting it to be without commas so it will be return as it is integer
PDC.CASH += String.Format("{0:n2}",readerCASH["Cash"]);
n2 means 2 digits after comma also i suggest you to use {0:c2} if you are working with currency

If you not sure to which .Net type will be mapped initial RDBMS one (e.g. Number(16, 4) -> ? will it be Single, Double or Decimal?) you can try converting:
decimal result = Convert.ToDecimal(readerCASH["Cash"]);

Related

Trying to check if int value is indeed an int

I'm trying to check a passed variable to ensure that it is indeed of type Int. However, I keep having an error appear that tells me that the variable "year" cannot be converted from an int to a string. I'm stuck because I'm not trying to convert it over so I'm confused as to what I'm missing.
[HttpGet("[action]")]
[Authorize]
public ListResult ProblemsYTD(int year = "")
{
var sql = "SELECT DatePart(yyyy, CLL.Call_Log_Date) as [ProblemsYear], CLL.Service as [Service], Sum((DATEDIFF(dd, CLL.Call_Log_Date, GetDate()))) as [DaysOpen] " +
"FROM VMWareSM_Test.dbo.RV_CALL as CLL " +
"Where CLL.IPK_Stream_Ref = '19' And DatePart(yyyy, CLL.Call_Log_Date)";
int myInt;
if (!int.TryParse(year, out myInt))
{
year = "%" + year + "%";
sql += " = #year";
}
sql += " Group by CLL.Service, DatePart(yyyy, CLL.Call_Log_Date) "+
"Order by CLL.Service DESC; ";
SqlParameter[] sqlParams =
{
new SqlParameter
{
ParameterName = "#year",
Value = year,
DbType = DbType.Int32,
Direction = ParameterDirection.Input
}
};
Let's start from your use of the variable year. It is used as part of a where condition where also a DatePart function call is involved. Now DataPart returns an integer so you need an integer for your checks, not a string.
At this point your declaration of the method should be simple an integer without a default value or you could use a default value of zero.
You cannot use an empty string as default value for an integer. C# doesn't allow this free implicit conversions between types like an Option Strictless VB.NET
So the call should be simply
public ListResult ProblemsYTD(int year = 0)
at this point all the code that checks if the caller has passed an integer is useless because the caller cannot pass any other kind of type or value. Just integers or types that can be cast to an integer without loosing information (byte, short but not long) You declare the method to receive an integer and the compiler blocks any different type with a compilation error.
However you could add a check for a reasonable value for your year variable.
For example you could limit the upper and lower values with something like this
if (year >= 2000 && year <= DateTime.Today.Year)
{
sql += " = #year";
}
Note that you cannot concatenate a "%" symbol to an integer for the same reason that you cannot assign an empty string to an integer.
Your function should be declared like this
public ListResult ProblemsYTD(string year = "")
{
...
}
also year = "%" + year + "%";
make no since the % is used in LIKE statements
should be something like this :
if (int.TryParse(year, out myInt))
{
sql += " = #" + year;
}
else
{
throw new Exception("Year is not in correct format");
}
This line looks fishy:
public ListResult ProblemsYTD(int year = "")
You're providing an empty string ("") as the default value for year. I think you mean to have the parameter be a string when it is passed in.
public ListResult ProblemsYTD(string year = "")
I'm trying to check a passed variable to ensure that it is indeed of type Int.
Most likely you just need to use a Route Constraint
Example Route:
routes.MapRoute(
"Product",
"Product/{productId}",
new {controller="Product", action="Details"}
);
Controller:
public class ProductController : Controller
{
public ActionResult Details(int productId)
{
return View();
}
}
with the following producing an error:
/Product/blah
/Product/apple
You can add a route constraint to only route to the controller/action if it is an int:
routes.MapRoute(
"Product",
"Product/{productId}",
new {controller="Product", action="Details"},
new {productId = #"\d+" }
);
This means that your controller is not in charge of type checking (it probably shouldn't anyway) and you can create a another route to catch non-ints and display a different view accordingly.
int year = ""
You cannot set an integer variable to a string value.

Textbox format not accepting to type numbers with points

I am using this code to type the currency amounts in a textbox with comma seperators and points. While typing numbers should display like this format(1,258,891.50). My code is working bt I can't type points. Its accepting only full numbers. Below is my code....
if (textBox5.Text == "")
return;
int n = textBox5.SelectionStart;
decimal text = Convert.ToDecimal(textBox5.Text);
textBox5.Text = String.Format("{0:#,###0}", text);
textBox5.SelectionStart = n + 1;
If your CurrentCulture has already , as a NumberGroupSeparator and . as a NumberDecimalSeparator, you can use The ("N") format specifier as N2 like;
textBox5.Text = text.ToString("N2");
If it is not, you can Clone your CurrentCulture, set these values to your properties and use that culture as a second parameter in ToString method.
var clone = (CultureInfo)CultureInfo.CurrentCulture.Clone();
clone.NumberFormat.NumberGroupSeparator = ",";
clone.NumberFormat.NumberDecimalSeparator = ".";
textBox5.Text = text.ToString("N2", clone); // 1,258,891.50
Your string format "{0:#,###0}" is not specifying any decimal places, so it is converting it without any decimal places. (Also the 0 at the end is actually doing nothing.)
Try this instead:
textBox5.Text = String.Format("{0:#,###.##}", text);
If for some reason you really do want to force a 0 at the end, try this:
textBox5.Text = String.Format("{0:#,###.#\\0}", text);
textBox5.Text = string.Format("{0:#,##0.00}", double.Parse(textBox5.Text));

How do I minimize decimal place to 0?

Currently, I'm retrieving data from a SharePoint Site, and I'm able to do so, however, I want limit the decimal place to 0.
if (item["ows_Amount_x0020__x0028_LC_x0029_"] != null)
{
str.AppendLine("<td bgcolor='#FFFFFF';align='right';> " + item["ows_Amount_x0020__x0028_LC_x0029_"].ToString() + "</td>");
}
Use a standard number format string in the ToString() method of Decimal (or Double, or whatever the actual datatype is of your item):
Convert.ToDecimal(item["ows_Amount_x0020__x0028_LC_x0029_"]).ToString("N0");
The "N0" here means "Number" at 0 decimal places. If you don't want commas added, use "F0" instead.
Number format reference: MSDN
Well, it depends on the type of: item["ows_Amount_x0020__x0028_LC_x0029_"]
Assuming it is always an amount that happens to be a string such as: 56.78
Then you can use:
if (item["ows_Amount_x0020__x0028_LC_x0029_"] != null)
{
decimal temp = 0;
if (decimal.TryParse(item["ows_Amount_x0020__x0028_LC_x0029_"], out temp))
str.AppendLine(" " + (long) temp + "");
else
str.AppendLine(" " + item["ows_Amount_x0020__x0028_LC_x0029_"].ToString() + "");
}
Try this
Convert.ToDecimal(item["ows_Amount_x0020__x0028_LC_x0029_"]).ToString("N1") //1 decimal place
OR
Convert.ToDecimal(item["ows_Amount_x0020__x0028_LC_x0029_"]).ToString("N0") //No decimal
OR
String.Format("{0:N1}", item["ows_Amount_x0020__x0028_LC_x0029_"]);

How can I resolve this error an c#

I want to insert data into a database table:
myCommand.CommandText = "INSERT INTO Selectionner (IdPrestation,
IdPhrase, DegreUrgence,RisqueConcerne,rowguid,Cotation) " +
"VALUES ('" +new Guid(emp.IdPrestation) +
"', '" +new Guid(emp.IdPhrase)+ "', '" +
emp.DegreUrgence + "','" + emp.RisqueConcerne + "','" +
new Guid(emp.rowguid) + "','" + emp.Cotation + "')";
But this returns an error:
Guid should contain 32 digits with 4 dashes
(xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).
How can I resolve this error ?
One or many of your
emp.IdPrestation //Or
emp.IdPhrase //Or
emp.rowguid //Check them before creating
is/are not a GUID. That is why it is throwing an error.
EDIT: starts
How to use Guid.TryParse() which returns true if the parse operation was successful; otherwise, false.
//How to parse safely
Guid IdPrestation;
Guid IdPhrase;
Guid rowguid;
if(Guid.TryParse(emp.IdPrestation, out IdPrestation) &&
Guid.TryParse(emp.IdPhrase, out IdPhrase) &&
Guid.TryParse(emp.rowguid, out rowguid) )
{
//all variables have been parse successfully
//Execute the sql query as follows using parameters
}
EDIT: ends
Also, passing parameters as direct string with inline sql is an unsafe bad practice. Instead use a parameterised query.
myCommand.CommandText = "INSERT INTO yourTableName (c1, c2, ...)
VALUES (#p1, #p2,...)";
myCommand.Parameters.Add(new SqlParameter("p1", valueforCol1));
myCommand.Parameters.Add(new SqlParameter("p2", valueforCol2));
...
Try to use a parameterised query as a first improvement.
Then, try to use Guid.Parse(string s) instead of new Guid(string s). That way, i expect that an exception will be raised for the strings that are not compliant.
The constructor might be a little to permissive, and in this case you would want to fail-fast so that you know what field is giving you trouble.
You cannot create GUID simply from a string ,the string needs to be guid compliant
Guid originalGuid = Guid.NewGuid();
originalGuid.ToString("B") gets converted to {81a130d2-502f-4cf1-a376-63edeb000e9f}
Similarly
"N" - xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx (32 digits)
"D" - xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx (32 digits separated by hyphens)
"B" - {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} (same as "D" with addition of braces)
"P" - (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx) (same as "D" with addition of parentheses)
"X" - {0x00000000,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x00.0x00}}
The guid itself has no format. It is just a value. Note, that you can create guids using NewGuid or using the guid's constructor. Using NewGuid, you have no control over the value of the guid. Using the guid's constructor, you can control the value. Using the constructor is useful if you already have a string representation of a guid (maybe you read it from a database) or if you want to make it easier to interpret a guid during development. You can also use the Parse, ParseExact, TryParse, and TryParseExact methods.
So, you can create guids like this:
Guid g1 = Guid.NewGuid(); //Get a Guid without any control over the contents
Guid g2 = new Guid(new string('A',32)); //Get a Guid where all digits == 'A'
Guid g3 = Guid.Parse(g1.ToString());
Guid g4 = Guid.ParseExact(g1.ToString("D"),"D");
Guid g5;
bool b1 = Guid.TryParse(g1.ToString(), out g5);
Guid g6;
bool b2 = Guid.TryParseExact(g1.ToString("D"),"D", out g6);

C# SQL Aggregate ExecuteScalar Return Query

An SQL aggregate function counting number of name enteries in DB.
string cnnStr = ConfigurationManager.ConnectionStrings["LGFConnectionString"].ConnectionString;
string mySQL = "SELECT COUNT(*) FROM " + which.table + " WHERE " + which.column + " = ?pram;";
string value = null;
using (MySqlConnection cnn = new MySqlConnection(cnnStr))
{
using (MySqlCommand cmd = new MySqlCommand(mySQL, cnn))
{
MySqlParameter param = new MySqlParameter("?pram", MySqlDbType.VarChar, 128);
param.Value = which.text;
cmd.Parameters.Add(param);
cnn.Open();
value = cmd.ExecuteScalar() as string;
value = cmd.ExecuteScalar().ToString();
cnn.Close();
}
}
Notice that I have called cmd.ExecuteScalar twice. Interesting part is that the query returns different results.
value = cmd.ExecuteScalar() as string;
doesn't return the correct value. It returns null for both if name is present or missing in the name column.
value = cmd.ExecuteScalar().ToString();
returns correctly. This returns "1" if present and "0" if missing.
In searching the web, I haven't found an understandable explanation.
I have read that if name is missing from name column, then cmd.ExecuteScalar will return null.
What is the difference between:
value = cmd.ExecuteScalar() as string;
value = cmd.ExecuteScalar().ToString();
Thank you,
deDogs
as in docs
The as operator is used to perform conversions between compatible types.
The as operator is like a cast except that it yields null on conversion failure instead of raising an exception
// if cmd.ExecuteScalar() is string then return string
// if not then return null
// this will return null, because cmd.ExecuteScalar() won't return string
// for your code it should return Int32
value = cmd.ExecuteScalar() as string;
ToString() in docs
ToString is the major formatting method in the .NET Framework. It
converts an object to its string representation so that it is suitable
for display. (For information about formatting support in the .NET
Framework, see Formatting Types.)
// return a string that represents the current object
// will return correct value because it casts Int32 value to string value
value = cmd.ExecuteScalar().ToString();
The 'as' keyword will return null if the objects type does not match what you are attempting to cast it to.
What is happening in your case is that the returned object is an int and when you call toString on this, it will give you a string representation of the integer. When you use as against it, it gives you a null.
You are doing two different things above. Let's change your code to the following:
decimal value = cmd.ExecuteScalar();
string str1 = value as string;
string str2 = value.ToString();
str1 will be null because decimal cannot be cast to a string.
str2 will be the value because you can call ToString() on a decimal.

Categories