将 varchar 列转换为 datetime2 而不影响列数据?

时间:2021-06-15 06:39:31

标签: php sql sql-server ms-access

我需要更改列 datatype 而不影响该列中的数据。我有下面的表结构:

CREATE TABLE [dbo].[PROJECT_LOG](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [UNIT] [int] NULL,
    [NAME] [nvarchar](100) NULL,
    [STATUS] [numeric](1, 0) NULL,
    [LOG] [nvarchar](200) NULL,
    [LAST_UPDATE] [nvarchar](100) NULL
) ON [PRIMARY]
GO

现在,我有大约 200 条记录如下: enter image description here

我想将列 LAST_UPDATE(当前 mm/dd/yyyy 格式)更改为 datetime2。有人能帮我解决这个问题吗?

我尝试使用与下面建议的人相同的转换查询并回答here

-- Add new column.
ALTER TABLE [dbo].[PROJECT_LOG] ADD LAST_UPDATE_TIME  DATETIME;

-- Convert value.
UPDATE [dbo].[PROJECT_LOG]
   SET LAST_UPDATE_TIME = CONVERT(nvarchar, 
REPLACE(LEFT(LAST_UPDATE, 11), '/', ' ') + ' ' + RIGHT(LAST_UPDATE, 8), 101);

执行查询时抛出错误: enter image description here

2 个答案:

答案 0 :(得分:2)

换表

方法:

  1. 添加具有正确类型的替代项的列(推荐日期而不是 datetime2(7)
  2. 使用 Convert( date, LAST_UPDATE, 101 ) 更新此列
  3. 删除原来的列
  4. 将新列重命名为原始列的名称

重要说明:检查此表的所有导入脚本以修复用于设置 LAST_UPDATE 的函数。

替代

  1. 添加名称为 LAST_UPDATE_DATE 类型日期的列作为派生列
  2. 派生列公式:AS Convert( date, LAST_UPDATE, 101 ) [PERSISTED]
  3. 根据需要和导入的值保留两个值

重要说明:如果您获得美国以外的任何其他日期格式,则此公式会中断,因为它明确预期为 101 美国格式。

视为疯狂的替代品

在此表的顶部构建一个执行转换的视图。在 SQL Server 2008 中,没有 TRY_CAST 函数可以优雅地失败。

将视图用于下游工作。

为什么要约会?

键入日期需要 3 个字节,非常适合仅用于日期的值。

datetime2(0) 占用 6 个字节,默认 datetime2(7) 占用 8 个字节。

参考文献:

投射和转换 https://docs.microsoft.com/en-us/sql/t-sql/functions/cast-and-convert-transact-sql?view=sql-server-ver15

日期时间 2 https://docs.microsoft.com/en-us/sql/t-sql/data-types/datetime2-transact-sql?view=sql-server-ver15

Try_Cast https://docs.microsoft.com/en-us/sql/t-sql/functions/try-cast-transact-sql?view=sql-server-ver15

答案 1 :(得分:0)

由于您使用的是 2008 版,因此 try_cast 将无济于事。

一种安全的方法是使用循环实现更新,并在循环中使用 try catch 块逐行遍历整个表,如果在转换时发生任何失败,您可以在 catch 块中进行处理您可以通过查询将值更新为 NULL 以识别转换是否失败。