ColumnSize of numeric is not same original (c#)(dBase) - c#

I want to get a database schema (dBase), so I use "oledb" to get data from a dbase file for using getchemaTable to get the schema of data, but the "ColumnSize" of the numeric data type excludes "19". As the original data, such as "object_id" Type: nummeric column size: 12, but it returns the output to "19".
I want to show the results to the exact same. but..
I don't know what to do next.
public static DataSet getStructureDBF(string dir, string input)
{
OleDbConnection objConn = new OleDbConnection(#"Provider=VFPOLEDB.1;Data Source=" + dir + ";Persist Security Info=False;");
objConn.Open();
OleDbCommand objCmd = new OleDbCommand("Select * from " + input, objConn);
OleDbDataReader objDataReader = objCmd.ExecuteReader();
DataTable schemaTable = objDataReader.GetSchemaTable();
DataSet dsnew = new DataSet();
dsnew.Tables.Add(schemaTable);
return dsnew;
}

For all data types, dBASE field definitions store field length and precision. The latter is only relevant for numeric types, and the former is the maximum number width in digits, because that is how dBASE stores numbers: actual strings of digits.
See dbf file format specification
Edit
Note that data types Numeric and Float are stored as strings of digits. Number types in more recent versions of dBASE are stored as binary values.
Also see DBF reader implementation notes

Related

Decimal after two digit should contain 0 at second place should not be omitted

i am trying to round off value to two decimal places. but the issue is 0 at second is not appearing , it only shows decimal after one place.
i have fetched data from oracle db as 180.700 but while fetching it from db it shows only 180.7 in datatable after binding
using (OracleConnection con = new OracleConnection(constr_ipdmdm))
{
using (OracleCommand cmd = new OracleCommand(query))
{
using (OracleDataAdapter sda = new OracleDataAdapter())
{
cmd.Connection = con;
sda.SelectCommand = cmd;
using (DataTable dt = new DataTable())
{
sda.Fill(dt);
}
}
}
}
while rounding it off to two decimal places it shows only one value after decimal i.e 180.7
Math.Round(Convert.ToDecimal(dt_spec.Rows[2]["YS"]), 2)
how can we show as 180.700 while binding it in datatable
and how can we round it two two decimal place i.e 180.70
Any idea would be appreciated.
You can get oracle to round and format it
TO_CHAR(numbercolumn, 'FM999990D00')
This converts to a string in oracle so your c# app will receive a string. If you need to work with it numerically in c# you could have oracle round it instead
ROUND(numbercol, 2)
But depending on what you're doing it may be best to leave the precise decimals on and do all your work with it then format it at the end of the work
calculatedResult.ToString("0.00")
$"{calculatedResult:0.00}"
string.Format("{0:0.00}", calculatedResult)
You don't need to Math.Round it first. Formatting 1.2355 as "0.00" becomes "1.24"
If you're using this datatable of yours in something like a windows forms DataGridView then it's the job of the grid to format the data, not on you to change it to a string. Look at something like
TheDgv.Columns[TheColumnIndex].DefaultCellStyle.Format = "0.00";
And make sure the data in the datatable column is numeric, not a string
Preface: I know nothing about C#. I do have a logic suggestion though! Consider interpreting/casting the number as a string/chararray, and concatenating a bunch of zeros to the end of the string. Then, cast back to floating point, and do the roundoff. There should be another zero there.
I'm not very familiar with the functions being used, but this logic has worked in the past in other languages.

SqlCommand with parameters accepting different data formats

Imagine this code:
string value = "1.23";
string query = "UPDATE MYTABLE SET COL1=#p1";
SqlCommand cmd = new SqlCommand(query, connection);
cmd.Parameters.AddWithValue("#p1", value);
cmd.ExecuteNonQuery();
On my database it will work with value="1.23" if COL1 is decimal type column. But it will fail if value is "1,23" (comma instead of a dot as a decimal point). The error is
Error converting data type nvarchar to numeric
I'd like it to work in both cases with "value" being a string variable.
Unfortunately I cannot just replace comma for the dot as this code is going to be more universal, dealing both with numeric and varchar columns
Is there any way that an query accepts a parameter with number written as a string both with dot and a comma and correctly puts it in into table?
Thanks for any help
If the value isn't semantically a string, you shouldn't send it as a string. The type of the parameter value is important, and influences how it is transmitted and can lead to culture issues (comma vs dot, etc).
If the value is semantically a decimal, then use something like:
string value = "1.23";
var typedValue = decimal.Parse(value); // possible specifying a culture-info
//...
cmd.Parameters.AddWithValue("#p1", typedValue);
Then it should work reliably.
Unrelated, but you can make ADO.NET a lot easier with tools like "Dapper":
connection.Execute("UPDATE MYTABLE SET COL1=#typedValue", new { typedValue });

comma vs point in double with an access database

In my C# program, I use a strongly typed dataset with an access database. In one table of the DB, I use a double. With some cultures, access uses a comma instead of a point for a double value. I can read the value without a problem (IE if access uses a comma: "10,25" is read as a "10.25" double value). But when I want to insert a new value, I get an exception if access uses a comma and one of the values is a decimal (IE "10" is insert, "10.25" throw the exception). The exception is thrown when I update the DB, not when I create a new row in the dataset.
As I use a dataset, I thought that these problems were automatically handled by .Net.
How can I manage comma/point (I think I must get the culture of the user, then force the dataset to use it. But how?)?
PS : I can't change the computer culture, so I need to manage all cultures by code.
Note that doubles do not contain commas or points. They store the number in a binary representation internally using a mantissa and an exponent. The comma vs point issue only comes into play if you have a string representation of the double (most likely a sql string).
Do not write:
// Here the double is in a string
string sql = "INSERT INTO mytable (id, value) VALUES (1, 10.25)";
using (OleDbCommand cmd = new OleDbCommand(sql, conn)) {
cmd.CommandType = CommandType.Text;
conn.Open();
cmd.ExecuteNonQuery();
}
Instead use command parameters:
// Here the double is never converted to a string
string sql = "INSERT INTO mytable (id, value) VALUES (?, ?)";
using (OleDbCommand cmd = new OleDbCommand(sql, conn)) {
cmd.CommandType = CommandType.Text;
cmd.Parameters.AddWithValue("?", 1);
cmd.Parameters.AddWithValue("?", 10.25);
conn.Open();
cmd.ExecuteNonQuery();
}
Of course, in the C# code the double is written in a textual representation. However, when compiled and at runtime the double exists in its pure binary form, not remembering the character of the decimal separator used in the code.

Datatable auto convert "0.000095" to "9.5E-05"

I am filling my Dataset from excel sheet which contains data like this "0.000095". Datatable returned by dataset has all the columns of type string. But for some reasons I want the exact data that is in excel sheet instead of auto convert it to "9.5E-05".
string connstring = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + FileName + ";Extended Properties='Excel 8.0;HDR=NO;IMEX=1';";
OleDbDataAdapter adapter;
DataSet ds = new DataSet();
adapter = new OleDbDataAdapter("Select * from [Sheet1$]", connstring);
adapter.Fill(ds);
I want the exact data that is in excel sheet instead of auto convert it to "9.5E-05".
That IS The exact data. Missed math in school?
What you want is the same REPRESENTATION (as a string).
Hanle that in the UI. Numbers in C# have no format - they are a value, and the VALUE is identical. To have the same format, handle the same format in the UI.
And if you ask abou the debugger - no way. The debugger shows values with a standard formatting.
Converting back from the exponential format to decimal format
Decimal.Parse("9.5E-05”, System.Globalization.NumberStyles.Float)

string getting truncated when saved into database

I have a database datatype defined as Text:
text columns are variable-length columns that can hold up to 2,147,483,647 (231 - 1) bytes of printable characters.
What does that means exactly? How many string characters will I be able to save into the Text column?
Basically, I try to save a c# string object into that column where
myString.ToString().Length == 39418
but when I pull it back from the database
myString.ToString().Length == 32768
-----------EDITED---------------
guys this is very confusing.
The Text column is defined as 2,147,483,647 bytes which is 2GB
The string i'm trying to save is ?System.Text.ASCIIEncoding.Unicode.GetByteCount(param.Value.ToString()) 78836 bytes i.e. 0.0000734217 gigabytes
So that confirms that what I am trying to save IS NOT too big for the Text datatype column? i.e. I'm saving 0.0000734217 GB into a column capable of handling 2GB
I'm using Sybase. Saving like this:
OdbcParameter param = new OdbcParameter();
param.DbType = DbType.String;
param.Size = int.MaxValue;
param.Value = myBigString
parameters.Add(param);
OdbcHelper.ExecuteNonQuery(connectionString, sql, parameters);
And retreiving like this
DataSet ds = new DataSet();
OdbcConnection conn = new OdbcConnection(connectionString);
OdbcDataAdapter adp = new OdbcDataAdapter(command, conn);
conn.Open();
adp.Fill(ds);....
Also when I try this I can still see the data is truncated so it doesn't look like a problem when retreiving the data
var obj = OdbcHelper.ExecuteScalar(connectionString, "select myBigString FROM ...");
As I mentioned in my comment, do not use TEXT as it is deprecated. Use VARCHAR or NVARCHAR for Unicode data. This will allow you to store up to 2GB of data.
http://msdn.microsoft.com/en-us/library/ms186939.aspx
Variable-length Unicode string data. n defines the string length and
can be a value from 1 through 4,000. max indicates that the maximum
storage size is 2^31-1 bytes (2 GB). The storage size, in bytes, is
two times the actual length of data entered + 2 bytes. The ISO
synonyms for nvarchar are national char varying and national character
varying.
2,147,483,647 bytes is approximately 1.862GB and the maximum capacity for that column. I assume the data you're attempting to store is too large for the column, hence the data being truncated.
use the nvarchar(MAX) type for that column
In my connection string I needed to add textsize=2147483647

Categories