SQL中varchar(7)列转datetime列的插入实现问题
问题描述
我有存储在varchar(7)类型列LogMonth中的数据,需要转换为datetime类型的LogDate列。已经通过SQL拆分出月、年并将日设为1,但用CONCAT拼接插入时出现语法错误,求可行实现方法。
表结构及测试数据
CREATE TABLE LogData( LogMonth [varchar](7) NOT NULL, LogDate [datetime] NULL ); INSERT INTO LogData ([LogMonth]) VALUES ('01/2023'); INSERT INTO LogData ([LogMonth]) VALUES ('02/2023'); INSERT INTO LogData ([LogMonth]) VALUES ('03/2023');
已使用的拆分语句
SELECT REVERSE(PARSENAME(REPLACE(REVERSE(LogMonth), '/', '.'), 1)) AS [Month], REVERSE(PARSENAME(REPLACE(REVERSE(LogMonth), '/', '.'), 2)) AS [Year], [Day] = 1 FROM LogData
报错的插入语句
INSERT INTO LogData (LogDate) SELECT CONCAT( REVERSE(PARSENAME(REPLACE(REVERSE(LogMonth), '/', '.'), 1)) AS [Month], REVERSE(PARSENAME(REPLACE(REVERSE(LogMonth), '/', '.'), 2)) AS [Year], [Day] = 1 )
可行实现方法
错误原因分析
你在使用CONCAT时犯了两个错误:
- 在
CONCAT的参数里添加了列别名(AS [Month]),这是语法错误,CONCAT只接受表达式作为参数,不能加别名; - 拼接的内容没有形成合法的日期字符串,无法直接转换为
datetime类型。
下面提供几种简单可行的解决方案:
方法1:直接拼接日期后缀后转换(最简方案)
你的LogMonth格式是MM/yyyy,直接在后面拼接/01就得到了MM/dd/yyyy格式的合法日期字符串,SQL Server可以直接识别转换:
UPDATE LogData SET LogDate = CAST(LogMonth + '/01' AS DATETIME)
方法2:用DATEFROMPARTS构造日期(最安全方案)
如果坚持使用拆分后的年、月、日,推荐用DATEFROMPARTS函数(SQL Server 2012及以上版本支持),它直接接受年、月、日的整数参数,返回标准datetime类型,完全避免字符串转换的格式问题:
UPDATE LogData SET LogDate = DATEFROMPARTS( -- 转换为年份整数 CAST(REVERSE(PARSENAME(REPLACE(REVERSE(LogMonth), '/', '.'), 2)) AS INT), -- 转换为月份整数 CAST(REVERSE(PARSENAME(REPLACE(REVERSE(LogMonth), '/', '.'), 1)) AS INT), -- 固定日期为1 1 )
方法3:修复CONCAT写法
如果一定要用CONCAT,需要去掉参数里的别名,拼接成合法的日期格式后再转换:
UPDATE LogData SET LogDate = CAST( CONCAT( -- 月份 REVERSE(PARSENAME(REPLACE(REVERSE(LogMonth), '/', '.'), 1)), '/01/', -- 年份 REVERSE(PARSENAME(REPLACE(REVERSE(LogMonth), '/', '.'), 2)) ) AS DATETIME )
验证结果
执行任一方法后,查询表数据:
SELECT LogMonth, LogDate FROM LogData
会得到如下结果:
| LogMonth | LogDate |
|---|---|
| 01/2023 | 2023-01-01 00:00:00.000 |
| 02/2023 | 2023-02-01 00:00:00.000 |
| 03/2023 | 2023-03-01 00:00:00.000 |
内容的提问来源于stack exchange,提问作者Jefferson
相关产品推荐
相关产品推荐

