How to get NumericPrecision and Scale of a decimal from DataTable - c#

I need to get the exact type of a column in a DataTable in C#.
In a simliar article on SO i found part of a solution:
DataTable st = reader.GetSchemaTable();
foreach (DataRow row in st.Rows)
{
Console.Write(string.Format("ColumnName:{0} DataType:{1} Ordinal:{2} Precision:{3} Size:{4} Scale:{5}",
row["ColumnName"], row["DataTypeName"], row["ColumnOrdinal"],
row["NumericPrecision"], row["ColumnSize"], row["NumericScale"]));
}
This works for string and date so far.
But for decimal i always recieve nullfor precision and scale.
I need those values to create a new table in another database.
The DataType returned is Decimal.
In the MSDN documentation it says that NumericPrecision returns null if it is no numeric data type, but decimal is kind of numeric?
So how do i get the exact precision of decimal values from the DataSet? Or rather what am I doing wrong?
edit:
I am trying to create some new SQL database based on old .dbf files from a FoxPro application.
So i want to read the columns, and create them in SQL, therefore I need the exact type of the column.
I tried with the .dbf and a new sql database.
I created a table in both to know the exact type for sure, for both databases i get those null returns. There is only a problem with the decimal/numeric values, for string and DateTime i get the Size.
For the .dbf I use a OleDbConnection.
For the SQL I use a SqlConnection, I get null if I try it for each.

From my experience with MySQL, the decimal datatype is numeric, but it can hold any precision or scale. If the database you are trying to create doesn't have the decimal datatype, you may need to convert it to a different type of number and possibly guess what precision and scale you need.

Related

Insert empty DateTime from C# into FoxPro

I am trying to insert an empty DateTime into a FoxPro database using DbParameter in C#. Our application marries FoxPro data along with SQL Server and .NET models/data.
My current issue is that most of our DateTime types in C# are not nullable, nor should they be. However, most of our legacy data in FoxPro are empty dates (shown as ' / / : : '). I am trying to do an insert into the FoxPro table where I do a check to see if the .NET DateTime meets certain criteria, then inserts an empty date. This last part has proven to be a nightmare.
What I have tried so far:
.Parameters.Add(string.Empty, new DateTime())
The above understandably inserts 01/01/0001 but is not what we want.
.Parameters.Add(string.Empty, "{}")
.Parameters.Add(string.Empty, "{:://}")
.Parameters.Add(string.Empty, "{//}")
.Parameters.Add(string.Empty, "'{}'")
The above all result in
System.Data.OleDb.OleDbException: 'Data type mismatch'.
which makes sense because I'm trying to send a string to a field with DateTime type.
Does anyone know how to insert an empty DateTime into FoxPro?
If I'm understanding you correctly, you're not using a DbParameter, but rather an OleDbParameter, and you're adding them through the OleDbParameterCollection.Add method?
If so, consider that you are using the overload that is .Add(String, Object), and you could instead use the overload that is .Add(String, OleDbType):
.Parameters.Add(string.Empty, OleDbType.Date)
The default value of an OleDbParameter is null, so you don't need to do anything more for your empty dates.
Also, depending on how the column is defined in your FoxPro database schema, it may be appropriate to pass OleDbType.Date, OleDbType.DBDate, OleDbType.DBTime, or OleDbType.DBTimeStamp. The full list of OleDB types is documented here, but I'm not entirely certain how they align to FoxPro's data types.
I believe your second example is close, but you have the Date and Time portions reversed.
It should be .Parameters.Add(string.Empty, "{//::}")
The // represent the Date portion, and the :: the Time portion.
Not sure of your SQL-Insert statement for VFP, but you MAY need to adjust it and do TWO different inserts. One IF a date exists, another if it does not.
For the one that does NOT have a date, I would hard-enter the following (for example where the "?" are the parameter place-holders)
insert into yourTable ( fld1, fld2,..., YourDateField ) values ( ?, ?, ..., ctot('') )
the function CTOT() means character to datetime and an empty string will comply with expected VFP Date/time field.
Work for me.
Parameters.AddWithValue("CreateDate", new DateTime(1899,12,30,0,0,0));

inserting c# double values to sql server float field. (no fractional part)

I am trying to insert double values to my database via EF 5. I generated EF entity model from db. There is a price column in the table which is float, and naturally EF generated a double type for the mapper class.
I read some string values from a file and convert it to double and save it to db. When I debug I can see that values are converted correctly. For example string value "120,53" is converted to double like 120.53, just fine. But when I save my context it goes to db like "12053".
What can cause such a problem? Is there any setting in SQL Server has anything to do with this?
I believe the problem is in your Convert.ToDouble and the , being used instead of a decimal. Without supplying the culture for the number it's likely instead interpreting the , as a thousandths separator and ignoring it. Try passing in CultureInfo.CurrentCulture as the second argument (IFormatProvider) if the culture of your environment is one where the , is used as a decimal. Or, since it looks like you're replacing a decimal with the , - just don't replace it.

Computed Column Based on Other Columns

I have a Dataset with a Bunch of Columns used in a Report (DevExpress XtraReports) (DataSet being the DataSource). The Dataset has many columns, and i need to read a column (based on the row type), and decide which column value to read for the row, and apply formatting based on the row type.
Example:
DataSet
DataType IntValue RealValue StringValue DateValue
Int32 123
DateTime 1/1/2011 1:23 AM
String XYZ
...
If the Datatype is DateTime, i need to read the DateValue column value, etc
I know we can use DataSet Expressions on computed columns, but cant find a way to apply the required Expression, and Format Data for the Report.
Is there a suggested way to handle this in the Report or at DataSet Level (excepting the formatting part)?
I'm not sure why you are taking this approach. This dataset is filled from a SQL datasource or some sort of backend? if that is the case, why don't you just get the computed column in the right format from the SQL directly? Wouldn't be a performance overhead to loop through all records to try and compute the "right" column?
Since it is a report, wouldn't displaying the data be enough? if you really need to use the type, you can bring that from sql as well, so you end up only with two columsn, type and data. If you can elaborate a little bit more on what you are trying to do, it will be helpful.

SQL adding random Decimal points when getting a real from DB to a Double in C#

When I am Entering a double number from C# to the DB I use a real type in the DB. When I check the value it is exactly what I enter.
Now when I go to retreive the value from the DB and store it into a C# double, it adds random decimal values at then end. The number in the database is the correct value that I want, but the value in C# as a double is just random (sometimes higher sometimes lower then the actual value.)
ie
- Enter into the db 123.43 as a double to an sql real.
- View the value in the DB, it's exactly 123.43
- Get the value from the DB and store into a C# double, value in the double is now 123.4300000305176
I have tried changing the type to float, decimal, etc. in the DB but these types actually alter the value when I put it into the DB to the same format as the above.
Any help on whats going on or how to fix it?
You should probably be using Decimal type. See What represents a double in sql server? for further explanation.
Try using a Single if your DB type is real. Check here for data mappings http://msdn.microsoft.com/en-us/library/ms131092.aspx

Oracle & SQL Server Dataset comparison

I am trying to do a C# dataset caparison between two datasets from two different DB's. Dataset one is from Oracle and Dataset two is from SQL Server and I'm comparing these datasets after an ETL jobs runs to move data from Oracle to SQL Server to validate the results. Problem I'm having is that the data in SQL Server matches but the Dates are in a different format from source to destination and also decimal point rounding.
Has anyone got a good way to circumvent this problem. I was thinking about changing my queries from the source and destination tables that fill the Dataset to format the dates etc... so the comparison would be easier but I wanted to see was there any other way?
For the date formats set the NLS_DATE_FORMAT environment variable to the desired format. This assumes that you catch the data in a string. Oracle will format the date to the format you specified. For the decimal point rounding I don't get it. Those numbers should be the same. In case you get a decimal point and want a comma, use NLS_MUMERIC_CHARACTERS 'DG' to choose which character to use a Decimal point or Group separator.
For example '.,' selects a '.' for decimal point and a comma for group separator.
The environment variables can be set from the clients OS and also from within the Oracle session. To do this, issue alter session set nls_date_format = 'YYYYMMDDHH24MISS'; or whatever format suits you best.

Categories

Resources