3

1000個までのテーブルを持つSQLServerデータベースがあります。ほとんどのテーブルにはdatetime、異なる名前の列があります。現在、そこに格納されている値は、コードがサーバーからの現在の日付で挿入したため、オフセット付きです。

目標は、すべての日時レコードをUTC時間で取得することです。

今、私は2つのことをしたいと思います。

  1. これらの3つの関数のいくつかを使用して(SYSDATETIME, SYSDATETIMEOFFSET, SYSUTCDATETIME)オフセットを取得できます。次のステップは、すべての日時レコードを検索して更新することです。これを手伝ってくれませんか。

  2. 一部の日時列にはデフォルト値がありますGETTIME。それをで更新したいSYSUTCDATETIME。どのようにアイデアはありますか?

datetimeoffsetPS: MSSQL Server 2005ではタイプがサポートされていないため、列のタイプをに変更したくありません。

編集:についてのコメントが非常に多く、質問のトピックが別の方向にシフトしたため、列タイプではなく、datetimeについて考えることをお勧めします。問題はまだ同じです。多くのテーブルを更新し、列のデフォルト値を変更します。datetimeint

よろしくmynkow

4

1 に答える 1

5

サーバー上のすべてのユーザーデータベースを更新する動的SQL。最初のクエリは[結果]タブに出力されます。2番目のクエリは[メッセージ]タブに出力されます。

SET NOCOUNT ON;
GO

---------------------------------------------
-- #1 Dynamic SQL to update DATETIME values with UTC offset
DECLARE @t TABLE(TABLE_CATALOG VARCHAR(128), TABLE_SCHEMA VARCHAR(128), TABLE_NAME VARCHAR(128), COLUMN_NAME VARCHAR(128));

INSERT @t
EXEC sp_msforeachdb 'select db = "?"
, s.name
, t.name
, c.name
FROM [?].sys.tables t
JOIN [?].sys.columns c ON c.object_id = t.object_id
JOIN [?].sys.types y ON y.user_type_id = c.user_type_id
JOIN [?].sys.schemas s ON s.schema_id = t.schema_id
WHERE t.[type] = ''U''
AND y.name = ''DATETIME''
AND "?" NOT IN (''master'', ''tempdb'', ''model'', ''msdb'')';

DECLARE @Offset INT;
SET @Offset = - DATEPART(TZOFFSET, SYSDATETIMEOFFSET());

SELECT [SQL] = 'UPDATE ['+ C.TABLE_CATALOG +'].[' + C.TABLE_SCHEMA + '].[' + C.TABLE_NAME + '] SET [' + C.COLUMN_NAME + '] = DATEADD(MINUTE,' + CAST(@Offset AS VARCHAR(5)) + ',[' + C.COLUMN_NAME + ']);' 
FROM @t C;
GO

---------------------------------------------
-- #2 Dynamic SQL to change DATETIME column defaults to SYSUTCDATETIME
DECLARE @t TABLE([SQL] VARCHAR(MAX));
DECLARE @SQL VARCHAR(MAX);

INSERT @t   
EXEC sp_msforeachdb 'SELECT [SQL] = ''---------------------------------------------'' + CHAR(13) + CHAR(10)
    + ''-- [?].[''+s.name+''].[''+t.name+''].['' + c.name + '']'' + CHAR(13) + CHAR(10)
    + ''ALTER TABLE [?].[''+s.name+''].[''+t.name+'']'' + CHAR(13) + CHAR(10)
    + ''DROP CONSTRAINT [''+d.name + '']'' + CHAR(13) + CHAR(10)
    + ''GO'' + CHAR(13) + CHAR(10)
    + ''ALTER TABLE [?].[''+s.name+''].[''+t.name+''] ADD CONSTRAINT'' + CHAR(13) + CHAR(10)
    + ''[''+d.name+''] DEFAULT (SYSUTCDATETIME()) FOR [''+c.name + '']'' + CHAR(13) + CHAR(10)
    + ''GO'' + CHAR(13) + CHAR(10) + CHAR(13) + CHAR(10)
    FROM [?].sys.default_constraints d
    JOIN [?].sys.columns c  ON  c.default_object_id = d.object_id
    JOIN [?].sys.types y ON y.user_type_id = c.user_type_id
    JOIN [?].sys.tables t ON t.object_id = d.parent_object_id AND t.[type] = ''U''
    JOIN [?].sys.schemas s ON s.schema_id = t.schema_id
    WHERE y.name = ''datetime''
    AND "?" NOT IN (''master'', ''tempdb'', ''model'', ''msdb'')';

DECLARE C CURSOR FOR 
SELECT * FROM @t

OPEN C
FETCH NEXT FROM C INTO @SQL;
WHILE @@FETCH_STATUS = 0 BEGIN
    PRINT @SQL;
    FETCH NEXT FROM C INTO @SQL;
END

CLOSE C;
DEALLOCATE C;
GO
于 2012-09-16T19:50:06.670 に答える