varchar列中的补丁日期时间

时间:2012-02-28 19:24:29

标签: sql sql-server sql-server-2008 tsql

我有大约12个表我需要迭代并更新所有日期时间字段(这是一个varchar类型)检查它是否是一个日期,如果是这样,添加5小时来考虑utc调整或如果它是一个无效的日期只是设置它为空。下面是我提出的模板。只是想知道是否有其他方法可以做到这一点?

update Tables_1
set releasedate = CASE ISDATE(releasedate) 
                     WHEN 1 THEN DATEADD(HH, 5, releasedate) 
                     ELSE NULL 
                  END,
    returndate = CASE ISDATE(returndate)
                     WHEN 1 THEN DATEADD(HH, 5, returndate) 
                     ELSE NULL 
                 END

给出:sql server 2008,我知道已经将日期时间类型存储为varchar的列和表。

奖励请求添加其他支票。如果是日期且未指定时间,请将时间设置为5:00

1 个答案:

答案 0 :(得分:1)

如果它们都以date结尾,您可以动态构建它:

DECLARE @sql NVARCHAR(MAX) = N'';

SELECT @sql += ', ' + name = CASE ISDATE(' + name + ') WHEN 1 THEN 
      DATEADD(HOUR, 5, ' + name + ' ELSE NULL END'
FROM sys.columns 
WHERE name LIKE '%date' AND [object_id] = OBJECT_ID('dbo.Tables_1');

SELECT @sql = 'UPDATE dbo.Tables_1 SET ' + STUFF(@sql, 1, 1, N'');

PRINT @sql;
-- EXEC sp_executesql @sql;

现在,如果您想为12个表执行此操作,则可以在循环中执行此操作,例如

DECLARE @t SYSNAME, @sql NVARCHAR(MAX);

DECLARE c CURSOR LOCAL STATIC FORWARD_ONLY READ_ONLY
FOR 
  SELECT name FROM sys.tables 
  WHERE name IN ('Tables_1' --, other tables
);

OPEN c;

FETCH NEXT FROM c INTO @t;

WHILE @@FETCH_STATUS = 0
BEGIN
    SELECT @sql = ', ' + name = CASE ISDATE(' + name + ') WHEN 1 THEN 
          DATEADD(HOUR, 5, ' + name + ' ELSE NULL END'
    FROM sys.columns 
    WHERE name LIKE '%date' AND [object_id] = OBJECT_ID(@t);

    SELECT @sql = 'UPDATE ' + @t + ' SET ' + STUFF(@sql, 1, 1, N'');

    PRINT @sql;
    -- EXEC sp_executesql @sql;

    FETCH NEXT FROM c INTO @t;
END

CLOSE c;
DEALLOCATE c;