views:

700

answers:

1

I've got a database full of datetime2 columns than needs to be moved to a SQL 2005 database. So, I need to convert all these datetime2(7) columns to datetime.

How can I go about doing this?

Right now I've managed to select the table name and column name for all columns with the datetime2 datatype like this:

SELECT t.name, c.name, i.DATA_TYPE
FROM sys.tables AS t
JOIN sys.columns c ON t.object_id = c.object_id
JOIN information_schema.columns i ON i.TABLE_NAME = t.name AND i.COLUMN_NAME = c.name
WHERE i.data_type = 'datetime2'

I just don't know how to do the rest.

+2  A: 

... then you iterate over your results with the CURSOR and dynamically run the DDL like:

ALTER TABLE myTable ALTER COLUMN myColumn datetime [NOT] NULL

so that you get something similar to this (not tested):

Edit: added null-ability check as well:

DECLARE @SQL AS NVARCHAR(1024)
DECLARE @TBL AS NVARCHAR(255)
DECLARE @COL AS NVARCHAR(255)
DECLARE @NUL AS BIT
DECLARE CUR CURSOR FAST_FORWARD FOR
    SELECT  t.name, c.name, c.is_nullable
    FROM    sys.tables AS t
    JOIN    sys.columns c ON t.object_id = c.object_id
    JOIN    information_schema.columns i ON i.TABLE_NAME = t.name AND i.COLUMN_NAME = c.name
    WHERE   i.data_type = 'datetime2'
    ORDER BY t.name, c.name

OPEN CUR
FETCH NEXT FROM CUR INTO @TBL, @COL, @NUL
WHILE @@FETCH_STATUS = 0
BEGIN
    SELECT @SQL = 'ALTER TABLE ' + @TBL + ' ALTER COLUMN ' + @COL + ' datetime' + (CASE WHEN @NUL=1 THEN '' ELSE ' NOT' END) + ' NULL;'
    EXEC sp_executesql @SQL
    FETCH NEXT FROM CUR INTO @TBL, @COL, @NUL
END

CLOSE CUR;
DEALLOCATE CUR;
van
Sorry, I really don't know much SQL. Can expand on that?
David Murdoch
added code to the answer. basically you need to change the type of the column, right? you can do it using ALTER TABLE ... ALTER COLUMN ... syntax. With the help of cursor you can just execute for all columns you found in a kind-of loop. You might add check for column nullability as noted by Lucasz and add NOT NULL to the statement.
van
modified: added check for nullability (not tested). cheers
van
Thanks for your help! I think it might work. But I've also got another problem because many of these columns have constraints/triggers. I get an error stating that "the object 'DF_CreatedDate' is dependent on column 'CreatedDate'.
David Murdoch
in this case you might generate another dynamic SQL and execute it just before the ALTER COLUMN... : ALTER TABLE xxx NOCHECK CONSTRAINT DR_CreatedDate... or something similar. but for cases like this you might want to see what is the code for this constraint and if it is something like DEFAULT (GETDATE()), then you might first delete it, then change datatype, then add it back.
van