如何创建/修改含默认值为未来日期datetimeoffset列的表?
这个问题我之前在项目里也踩过坑!你遇到的默认值变成0001-01-01 00:00:00.0000000的情况,是因为TODATETIMEOFFSET函数的用法在这里有个容易忽略的细节——当你传入的字符串没有明确匹配datetimeoffset的格式要求时,SQL Server会解析失败,最终 fallback 到datetimeoffset类型的最小值。
问题原因
你的原语句里,TODATETIMEOFFSET('2020-01-01 00:00:00.000', '+00:00')看起来没问题,但SQL Server对字符串转datetimeoffset的格式有严格要求,尤其是当你指定了精度为(7)时,字符串的精度位数需要匹配,否则会出现解析异常,导致默认值失效。
正确的解决方案
方案1:直接使用datetimeoffset字面量(最简便)
直接写出符合datetimeoffset(7)格式的字面量,不用函数,SQL Server能直接识别并正确设置默认值:
ALTER TABLE xTable Add xDate [datetimeoffset](7) NOT NULL DEFAULT ('2020-01-01 00:00:00.0000000 +00:00')
注意这里的时间字符串要包含7位小数(对应你定义的datetimeoffset(7)),并且明确带上+00:00的偏移量。
方案2:用CAST/CONVERT明确转换类型
如果你更习惯用函数转换,可以通过CAST或CONVERT先把字符串转换成正确的datetimeoffset类型,避免解析错误:
-- 用CAST结合AT TIME ZONE ALTER TABLE xTable Add xDate [datetimeoffset](7) NOT NULL DEFAULT (CAST('2020-01-01 00:00:00.000' AS datetimeoffset(7)) AT TIME ZONE 'UTC') -- 或者直接用CONVERT指定格式 ALTER TABLE xTable Add xDate [datetimeoffset](7) NOT NULL DEFAULT (CONVERT(datetimeoffset(7), '2020-01-01 00:00:00.000 +00:00'))
方案3:使用DATEFROMPARTS构造时间(更灵活)
如果需要动态构造默认时间,也可以用DATEFROMPARTS结合时间偏移来生成:
ALTER TABLE xTable Add xDate [datetimeoffset](7) NOT NULL DEFAULT (DATEFROMPARTS(2020, 1, 1) AT TIME ZONE 'UTC')
验证方法
执行完ALTER语句后,插入一条不指定xDate字段的记录:
INSERT INTO xTable (其他字段) VALUES ('测试值')
然后查询这条记录的xDate字段,应该会显示2020-01-01 00:00:00.0000000 +00:00,说明默认值设置成功了。
内容的提问来源于stack exchange,提问作者Vivek kumar

