SQL Timestamp to datetime on C# - c#

I have the following column on my SQL table:
RECORDTIMESTAMP
0x000000000005B2A4
0x000000000005B2A5
0x000000000005B2A6
And I need to return this values on my C# program. This atributte is declared like this:
public DateTime? RecordTimeStamp{ get; set; }
And my method to get is this one:
RecordTimeStamp = DateTime.Parse(row["RecordTimeStamp"].ToString()),
The error message is the following:
"The string was not recognized as a valid DateTime. There is an unknown word starting at index 0.",
I also tried to declare the atribbute as string but it didn't worked also.
Any Ideas on this?

A common misconeption here: Timestamp is not actual a time.
It was a miss-naming. That is why it was renamed to ROWVERSION half a dozen versions ago. Timestamp was only still used as Alias, with a clear "deprecated" marker. From
https://learn.microsoft.com/en-us/sql/t-sql/data-types/rowversion-transact-sql:
timestamp is the synonym for the rowversion data type and is subject to the behavior of data type synonyms. In DDL statements, use rowversion instead of timestamp wherever possible. For more information, see Data Type Synonyms (Transact-SQL).
The Transact-SQL timestamp data type is different from the timestamp data type defined in the ISO standard.
Note
The timestamp syntax is deprecated. This feature will be removed in a future version of Microsoft SQL Server. Avoid using this feature in new development work, and plan to modify applications that currently use this feature.

That looks like a rowversion column (which has historically been called a "timestamp" column, despite it not being a stamp of the time). A rowversion is not a time - it is just an opaque monotonically incrementing integer that means nothing other than it lets you spot that a change has happened. Timestamps are often used for optimistic concurrency checking, but have no actual meaning. Depending on the size, a long, or a byte[] or a string might be fine for storage.

Related

DateTime2 conversion randomly removes space between date and time

I have a small console application which is to import a CSV file into a database. It is in .NET CORE 3.1. The CSV file gets imported without any issues. The issue arises with trying to save the data to the table. The error being received is "String or binary data would be truncated. The statement has been terminated." This is received during the context.SaveChanges() call. To determine exactly what the error is, loaded up Profiler to see the offending statement. The offending piece of code was related to a field that holds a date and time. To start from the beginning and lead up to the issue.
The imported data is in a column and is represented as follows:
"20200404121655500"
"20200404121755500"
The import model property is defined as follows:
public string Date_And_Time { get; set; }
The data model property is defined as follows:
[Column(TypeName = "DATETIME2(7)")]
public DateTime? Date_And_Time { get; set; }
The conversion used to get the imported string to the data model field is as follows:
if (DateTime.TryParseExact(Date_And_Time.Trim()
.PadRight(21, '0')
.Substring(0, 21), "yyyyMMddHHmmssFFFFFFF", CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime newDateTime))
{ model.Date_And_Time = newDateTime; }
else { model.Date_And_Time = null; }
While debugging when the 2 different dates are processed then are set in the model.Date_And_Time as expected. The object expands producing all the correct information (year, day, hour, etc.). Prior to executing SaveChanges, inspecting the objects shows they both have correct DateTime objects. However upon executing that command throws the above SQL exception. When inspecting the merge command created by EF the dates are differently formatted. They are as follows:
'2020-04-0412:16:55.5000000' and '2020-04-04 12:17:55.5000000'
The first does not have a space between the date and time where as the second has a space. The first is what is causing the exception. When doing the SaveChanges there are on average 20 records being saved and some have the space and some do not there is no pattern that I can find. I have tried using the exact same date time and that also has some with and some without space.
After some trial and errors I switched from DateTime to DateTimeOffset. This was done on the property of the data model propriety, the type attribute of the same property and the TryParseException. No other changes and it ran with no exceptions. Needed to do another migration due to the change in attribute causing the table field tire change.
The only 3rd party package used was to import the CSV for and that went successfully.
The parametrized merge statement was seen in the profiler sorry I didn't City it better finding the answer.
I have no idea why the model with a C# data type of DateTime would produce a string although the parameter itself was designated as DateTime2 the value being passed in was in string format.
I don't understand what the difference is between the 2 data types and how they are handled that would cause this issue. I appreciate the comments and attempting to help.

Datetime format is 'mm-dd-yyyy' when getting while using SqlDataAdapter but if I run the same query in ms sql then its 'yyyy-mm-dd'

I know the question is a bit confusing. Please let me elaborate.
Suppose
I have a table student master which has a column DOB
I have inserted a record and in DOB I have inserted '1991-01-01'
running select statement from sql server is returning date in the same format as it is inserted '1991-01-01' but when I am running the same query from C# using SqlDataAdapter then its returning date as '01-01-1991'
Can anyone explain why it is happening and is there any way to fetch the date in same format as it is inserted.
Query
Is it possible to get the DateTime using SqlDataAdapter as it was inserted?
P.S: column data type is Datetime
let's separate the wheat from the chaff :)
if for your needs meaningful is data type (datetime in this case), then formatting does not matter at all. All layers which will exchange or process the data will use data type information for that.
But
if the meaningful part is formatting, i.e. string representation of the data, then you need to consider the appropriate settings of UI tools you use to display your data. SSMS, for example, uses regional settings for that. If you need to visualize data in the identical manner, so you need the identical strings, you should take care of formatting by your self or in another words, you need to convert your datetime data to string in the same way in all places where you need it.
In T-SQL, for example, you could use CAST and CONVERT functions for formatting your data in a format you need.
If you can't match up the "Cultures" between the SQL Server and the machine you're building the application on (and, in fact, you cannot rely on that really if you're application is going to be deployed to other machines!), then the cheap and quick way round it is to run your date returns through a parse function such as this:
private string FncFormatDate(string date)
{
DateTime formattedDate;
if (DateTime.TryParse(date, out formattedDate))
{
return formattedDate.ToString("yyyy-MM-dd");
}
else
{
return "Invalid date";
}
}
I hope this answers your question.

Store values in separate, C# type-specific columns or all in one column?

I'm building a C# project configuration system that will store configuration values in a SQL Server db.
I was originally going to set the table up as such:
KeyId int
FieldName varchar
DataType varchar
StringValue varchar
IntValue int
DecimalValue decimal
...
Values would be stored and retrieved with the value in the DataType column determining which Value column to use, but I really don't like that design. So I thought I'd go this route:
KeyId int
FieldName varchar
DataType varchar
Value varbinary
Here the value in DataType would still determine the type of Value brought back, but it would all be in one column and I wouldn't have to write a ton of overloads to accommodate the different types like I would have with the previous solution. I would just pull the Value in as a byte array and use DataType to perform whatever conversion(s) necessary to get my Value.
Is the varbinary approach going to cause any performance issues or is it just bad practice to drop all these different types of data into a varbinary? I've been searching around for about an hour and I can't get to a definitive answer.
Also, if there is a more preferred method anyone can think of to reach the same conclusion, I'm all ears (or eyes).
You could serialize your settings as JSON and just store that as a string. Then you have all the settings within one row and your clients can deserialize as needed. This is also a safe way to add additional settings at any time without any modifications to your database.
We are using the second solution and it works well. Remember, that the disk access is in orders of magnitude greater, than the ex. casting operation (it's milliseconds vs. nanoseconds, see ref), so do not look for bottleneck here.
The solution can be to implement polymorphic association (1, 2). But I dont think there is a need for that, or that you should do this. The second solution is close to non-Sql db - you can dump as a value anything, might be as well entire html markup for a page. It should be the caller responsability to know what to do wit the data.
Also, see threads on how to store settings in DB: 1, 2 and 3 for critique.

How to retrieve Timestamp value from SQL Server using DataReader

How to retrieve Timestamp value(eg:0x000000048E18B9D8 ) from SQL Server using DataReader? I'm getting an IndexOutOfRangeException when doing like this
DateTime date = reader.GetDateTime(reader.GetOrdinal("Timestamp"));
Can anyone help on this?
Also I want to know how to pass timestamp parameter to stored procedure using .Net code
IndexOutOfRangeException thrown on reader.Getordinal() suggests that a column called Timestamp doesn't exist. Check your column names again, and replace with the actual value. By default, it will be called timestamp, but only if you haven't specified a column name.
You could also try string ts = reader["timestamp"].toString(), and make sure it returns something.
According to MSDN, a TIMESTAMP data type is "8 bytes...[and]... just an incrementing number and does not preserve a date or a time. To record a date or time, use a datetime data type."
Therefore, reader.GetInt64() is probably close, if you really need this value, but byte[] myTimestamp = reader["timestamp"] is probably better.
As far as passing it back to your stored procedure, you can create a new parameter with SqlDbType.Timestamp. The value will be a byte array, or, if you have it stored as a string, you could try something like:
cmd.Parameters.Add("#TimeStampParam", SqlDbType.Timestamp).Value = System.Text.Encoding.ASCII.GetBytes(myTimestampStr);`
(NB: I haven't tested this, but it should be close enough).
Note that TIMESTAMP is deprecated, and ROWVERSION is not the preferred syntax.

print-out database on c# which has type 'TIMESTAMP'

I'm using a query in C#. I'm printing out data from a database.
Its number of columns is about 200 and the first column's type is TIMESTAMP.
Other types don't have a problem being printed out. Only TIMESTAMP does.
Someone said I can use TIMESTAMP to get TO_CHAR(COLUMN_NAME, 'YYYYHHDD')
I want to show all of database. But if I want, I should type all of column.
This way newly created columns aren't shown.
I want to use query like this, but it doesn`t work:
SELECT TO_CHAR(TIME, 'HHMMSS'), * FROM DATAS
Please help me with this query.
The following works for me:
SELECT CONVERT(numeric(20,0), stamp + 0) FROM ...
This is where "stamp" is timestamp column.
Assuming you are using SQL Server, you have to read the timestamp value as a byte array and convert it to string. The SQL Server Data Type Mappings on MSDN show that Timestamp maps to Byte[] and can be accessed by the GetSqlBinary or GetBytes methods.
The mapping also shows that timestamp is actually a row version number that changes automatically each time a row is modified. It has nothing to do with time. It's just an incrementing 8 byte number. This number has no meaning for end-users and there is probably no point in showing it anywhere.
If you still want to display it, you can convert the timestamp bytes to an Int64 type using the BitConverter.ToInt64 method.

Categories

Resources