Issue with Datetime in SQL Server 2008 - database

I am importing some data from excel to db, the issue is I want to set the specific default value like 00/00/0000 to datetime column when there is no date available from the Excel file.
The getdate() sets the date to current one, but I want to set to a specific date, is it possible to achieve something like this.

Sure you can set a default value - but be aware: DATETIME has a valid range from 1/1/1753 through 12/31/9999 - so setting it to 0/0/0000 will NOT be a valid DATETIME value!
If you need such a value - use either DATETIME2 in SQL Server 2008 (range is from 1/1/0001 through 12/31/9999) - or use DATE (without any time - same range as DATETIME2)
Or: just make your DATETIME/DATETIME2/DATE column nullable and insert NULL when no date is present - that would be the cleanest solution.

When you use bcp or BULK INSERT or SQLBulkCopy, then you have the option of keeping NULLs.
If you don't, then you get the default for the column.
See "Keeping Nulls or Using Default Values During Bulk Import" on MSDN
If you can't (say because you get empty string not NULL) then you can use a a staging table first, then load the data from that with a combination of NULLID, ISNULL and CASE. Or use a trigger, but this will slow you down more so than doing the load in 2 steps

I'm not sure how you are performing your import, but if you wish to check whether a value is NULL and set it to a defined value then you can use the SQL IsNull(a,b) where a is the value to check and b is the value to return.
insert into [dbo].[tblSomeTable]
set [someField] = IsNull(#thisValueMayBeNull, thisValueIfNull)
Probably not a good example but should point you in the right direction.
Or once your data has been imported you could run an update script to replace all NULL dates with a fixed value;
Or you could set the date field in the database to NOT NULL and give it a defaut value.

Related

SQL Server convert datetimeoffset to timestamp

I have a datetimeoffset column DateEntry in my SQL Server table. When I want to convert it to a timestamp format with this query :
SELECT CAST(Table1.[DateEntry] AS timestamp)
FROM Table1
I get the following error :
Error : 529- Explicit conversion from data type datetimeoffset to
timestamp is not allowed.
TIMESTAMP in SQL Server has absolutely nothing to do with a date and time, therefore you cannot convert an existing date&time into a TIMESTAMP.
TIMESTAMP or more recently called ROWVERSION is really just a binary counter that SQL Server updates internally whenever row has been modified. You cannot set a TIMESTAMP column yourself, you can just read it out. It is used almost exclusively for optimistic concurrency checks - checking to see whether a row has been modified since it's been read, before updating it.
According to MSDN:
The timestamp data type is just an incrementing number and does not
preserve a date or a time. To record a date or time, use a datetime
data type.
If your are absolutely sure, you can use indirect conversion:
DECLARE #dto datetimeoffset = '2016-01-01 12:30:56.45678'
SELECT CONVERT(timestamp, CONVERT(varbinary(12), #dto))
See also #marc_s's answer.
Try the following script if this this is what you are trying your side
SELECT CAST(CAST(Table1.[DateEntry] AS datetime) as timestamp) FROM Table1

SQL Server 2008R2 alter GETDATE result as a default value

Is there a way to alter the outcome of getdate() while still using it as a default value? E.g. being able to plus or minus x number of hours.
The situation:
a German hosted server (GMT+2) with some end users in Australia (GMT+10). One column is using the default getdate() value therefore is inserting German time. Some code is generating a DateTime based on Australia time so there are 8 hours difference.
The objective:
For several good reasons the aim is to handle this on the database and not touch application code. I would like to add 8 hours onto the German getdate() default database value....... or handle this some other way on the database
you can use default value using DATEADD() function to add 8 hours to the date:
create table dbo.foo
(
dateColumn datetime default (dateadd(hour,8,getdate()))
)
I don't see any such option and it is little dangerous too. You can create a function with the same name GETDATE in your database, but that would require you to prefix with dbo(or schema name) while calling the function.
So, you may need to write your own function and make use of GETUTCDATE() and add delta according to timezone.

MVC 3 date created and modified have default values and triggers in SQL Server 2008 R2, but still want value

I have generated classes (DbContext) modelling my db (SQL Server 2008 R2), and in most of my tables I have the standard ModifiedDate and CreatedDate (No Nulls). Each of these has a default of getdate() in SQLServer, and I have a trigger to update ModifiedDate on any updates.
The generated views included the ModifiedDate and CreatedDate fields, which I don't want (the user shouldn't see these), so I've taken these out, but when adding a new entry using the generated Create view, I get the error "The conversion of a datetime2 data type to a datetime data type resulted in an out-of-range value".
I then added some default values, and it did add the record, but naturally it added my entered values, and not the SQL getdate() values, which I'd prefer (I want it to show the server time). Checking the object (db.SaveChanges()) the fields have a value of {1/01/0001 12:00:00 AM}.
How can I use these models without entering dates??? I've searched but haven't found my answer... ;-(
This is a common problem in both Entity Framework and Linq to SQL:
In Linq-To-SQL the model doesn't know about the default values, and so attempts to assign them as "null" - which in this case isn't acceptable. To fix this, open the DBML file and set the "Auto Generated Value" option to "true" for the fields in question.
In Entity Framework it's a little different: you set the "StoreGeneratedPattern" on the field to either "Identity" or "Computed". Here's the description:
http://msdn.microsoft.com/en-us/library/system.data.metadata.edm.storegeneratedpattern.aspx
EF will do this automatically for Identity type fields, but not for default value/not null fields. You may want to set your CreatedDate as "Identity" (updated only on insert) and your ModifiedDate as "Computed" (updated on insert and update).
The byproduct of this is that you then will not be able to set the fields via Linq at all - but that's fine in your use case, I think.

Data migration from MySQL to HSQL

I was working on migrating data from MYSQL to HSQL.
In MYSQL data file, there are plenty of records where date values are set as '0000-00-00' and HSQL database throws below error:
"data exception: invalid datetime format / Error Code: -3407 / State:
22007"
for all such records.
I would like to know what could be optimum solution for this problem?
Thanks in advance
HSQLDB follows the SQL Standard and allows valid dates only. A date such as '0001-01-01' would be a good candidate for the default value.
Regardless of the method used for data inserts, the '0000-00-00' strings should be corrected before insert. One way of doing this is to use a default value for the target column with DEFAULT DATE'0001-01-01' and replace the string in the INSERT statement with the keyword DEFAULT. For example:
CREATE TABLE MYTABLE ( C1 INT, C2 DATE DEFAULT DATE'0001-01-01')
INSERT INTO MYTABLE VALUES 1, DEFAULT
INSERT INTO MYTABLE VALUES 3, '2010-08-14'

How to alter a DateTime field when it is updated?

Is there a database level function (trigger or something) that I can use to alter a DateTime field when new data is inserted? The issue is that a service I am integrating with happens to send out all of its times (in this case the time some info was received on their end) in GMT.
I need to automatically change this to reflect the time in the timezone the db server is in. For example, if they send me 2:34 PM, but I am in NYC, I would want it to be entered in the db as 9:34 AM. This would also have to account for differences in Daylight Savings between GMT and wherever the server is, which seems like a nightmare. Any suggestions?
Also, I am using SQL Server 2005 if that helps.
EDIT:
Let me clarify one thing. The dates going into this column are retrieved in batches every so often (5, 10, 15 minutes), so I think the only way to go is to alter the time once it has been received, not to add a TimeModified field or something. Is that even feasible?
You could create
a default value for the DateTime which gets set when you insert a new record
CREATE TABLE dbo.YourTable
( ........,
LastModifiedOn DATETIME
CONSTRAINT DF_YourTable_LastModifiedOn DEFAULT (GETDATE())
)
a AFTER UPDATE TRIGGER which sets the DateTime field to the new value whenever you've updated your row
CREATE TRIGGER trgAfterUpdate
ON dbo.YourTable
AFTER UPDATE
AS BEGIN
UPDATE dbo.YourTable
SET LastModifiedOn = GETDATE()
FROM INSERTED i
WHERE i.Table1ID = YourTable.Table1ID
END
With the default value and the trigger, your datetime field LastModifiedOn should always be up to date and showing the last modification date/time.
Marc
Another option here would be to use a calendar table where you map a UTC date and time to the local date and time value.
Disadvantages here are a loss in some of the granularity. If seconds are important I would not implement this; you can look at the size of the calendar record and compare it to the size of storing a datetime for every record in your transactional table. Obviously the smaller the volume the less beneficial this solution will be. Also, if you don't build in automatic and unattended repopulating future records in the solution the table will "run out" of records, and you will have left a time bomb for whoever comes in after you (maybe yourself too).
Advantages though are that you will be able to perform any queries on this table much more quickly (because it is an integer). Also if you ever decide that your NYC server needs to move to Sacramento, you can update the "localDateTime" and leave the UTC time in tact.
Table structure (granularity will be up to your needs):
ID int
utc_month int
utc_day int
utc_year int
utc_hour int
utc_minute int
local_month int
local_day int
local_year int
local_hour int
local_minute int
Yet another option (again depending on volume) is to deploy a managed assembly.
(see this site for instructions, you do have to make a server configuration change. How to implement a managed udf or sp)
Here is the C# that I put in my udf
public static SqlDateTime udf_ConvertUTCDateTime(SqlDateTime utcDateTime)
{
DateTime dt = utcDateTime.Value;
utcDateTime = dt.ToLocalTime();
return utcDateTime;
}
The following code will return you the converted UTC datetime. Just use that value in your insert or trigger.
Declare #D datetime
set #D = GetUTCDate()
select #D
select dbo.udf_ConvertUTCDateTime(#D)
Create a field of the type Timestamp - that will get updated whenever any data is modified in that row. Alas, it's literally a relative timestamp, so it can only be used for versioning. More information can be found here:
http://msdn.microsoft.com/en-us/library/ms182776(SQL.90).aspx
following example should do the job. Add ModifiedOn or similar DateTime field to your db table.
insert into foo (field1, field2, ...., ModifiedOn)
values (value1, value2,...., GetDate())
or for update
update Foo
set field1 = value1,
field2 = value2,
.
.
.
.,
ModifiedOn = GetDate()
Where ....

Resources