Sql CDate使DateAdd公式失败
我希望我能被原谅,因为我只是通过问一个原因,而不是一个解决方案来轻微违反规则 我有以下代码:Sql CDate使DateAdd公式失败,sql,ms-access,Sql,Ms Access,我希望我能被原谅,因为我只是通过问一个原因,而不是一个解决方案来轻微违反规则 我有以下代码: INSERT INTO destinationTable (RecordMonth, ...) SELECT t1.Expr1, ... FROM ( SELECT CDate(Format("01-" & Right([t1].[Year-Month],2) & "-" & Left([t1].[Year-Month],4),"dd/mm
INSERT INTO destinationTable (RecordMonth, ...)
SELECT t1.Expr1, ...
FROM
(
SELECT
CDate(Format("01-" & Right([t1].[Year-Month],2) & "-" & Left([t1].[Year-Month],4),"dd/mm/yyyy")) AS Expr1,
/* ...other fields with no bearing... */
FROM tcsvMonthData AS t1
)
WHERE t1.Expr1 >= DateAdd("m",-6,(SELECT MAX(Expr1) FROM t1))
t1
中的[年-月]
是一个varchar类型字段
此脚本失败,Access将显示以下错误消息:“条件表达式中的数据类型不匹配。”
如果删除CDate
块,脚本将正常工作。很高兴找到了答案,但我不明白为什么会出现错误CDate
将字段约束为日期类型。在format
之后,该字段应该已经是日期类型了,因此CDate
是多余的,但它应该不会有什么害处(至少在我的头脑中不会)。另外,据我所知,DateAdd
不像说,Year
,它不会将输入字段转换为字符串,它应该保持一个日期类型。这是怎么回事
编辑:
Year-Month
描述记录发生的月份,如下所示:2017-11
。它是一个varchar类型,目标是将其作为dd/mm/yyyy格式的适当日期时间字段,其中每个月由该月的第一天表示。因此,5月是2018年5月1日等等。我在sql server中找到了一个解决方案,请使用cdate代替ms access的cast
select cast(format(cast('01-' + left('07/23/2018',2) + '-' + right('07/23/2018',4) as date),'dd/MM/yyyy') as date) AS Expr1
更改列的静态日期。我已经很久没有使用Access了,但我认为问题不在于使用CDate(),而在于在内部字符串上使用Format()。Format()需要对日期进行操作,但您给它一个字符串。因为格式化失败,所以周围的CDate()也失败了 您需要在Format()之前使用CDate(),如下所示:
Format(CDate ("01-" & Right([t1].[Year-Month],2) & "-" & Left([t1].[Year-Month],4),"dd/mm/yyyy")) AS Expr1,
您可能需要做一些调整,以使其运行,但基本的想法应该是可行的
下面被拒绝的答案之所以有效,是因为Cast-As-Date(在功能上等同于CDate)在Format()之前和之后都使用,所以Format()被传递了一个日期。该示例中的第二个强制转换是多余的 你把这件事搞得太复杂了。CDate是您所需要的全部:
CDate([t1].[Year-Month]) AS Expr1
编辑:
要接受空值,请过滤掉这些值,或使用CVDate传递空值:
或使用Nz提供默认值:
这对MS Access有何帮助?我非常感谢您费尽周折找到了一个适用于Sql Server的解决方案,但是我这里的问题不是“如何修复它?”而是“它为什么会失败?”。我提出这个问题的原因是为了更好地了解Access的工作原理,以便将来避免类似的问题。格式化后,字段应该已经是日期类型了。。不。格式返回一个字符串。我试过了,但老实说,这似乎适得其反。如果我将
CDate
放入Format
中,则最终结果是一个字符串类型字段,随后的DateAdd
也会失败。作为一个小提示,我认为你的括号放错地方了CDate
应该在“dd/mm/yyyyy”之前关闭,对吗?是的,Format()以指定格式获取日期并返回字符串。在Access中,日期存储为时间码,人类无法读取。因此,在原始示例中,将字符串日期转换为时间代码,然后使用Format()将其转换回具有不同格式的字符串。如果您只是想存储日期,那么可以完全跳过Format()。真的!另一个简化整个过程的函数是DateValue
,但它们都以某种方式失败。您建议的解决方案会引发以下错误消息“无效使用null”。我会检查一下,我在试验这里提出的解决方案时没有造成其他混乱,但我开始怀疑问题实际上在DateAdd
函数cdate中没有“失败”,但它不接受空值作为输入。宾果Year-Month
不应该为空,所以我甚至没有考虑过它,但本周确实有一行字段为空。这很可能也是所有其他尝试失败的原因。谢谢
CVDate([t1].[Year-Month]) AS Expr1
Nz(CVDate([t1].[Year-Month]), Date()) AS Expr1