嗯....我的建议是在错误到达 SQL 之前捕获它。您没有指定您的 DBMS(SQL Server、MySQL 等),所以我将专注于 ColdFusion 解决方案。我希望这些建议之一能为您指明正确的道路。
选项:
- 您链接到的有关 Coldfusion 日期验证的文章提到了 isValid 函数作为推荐的解决方案。按照建议,考虑将其与 USDATE 验证类型一起使用。
- 如果您在 API 方法中使用 CFC 或至少 cffunctions,那么您可以使用 cfargument type="date" 来帮助确保日期有效(尽管我的感觉是与 isDate 具有相同的宽松行为)
- 在您的 cfquery 标记内,您应该将 cfqueryparam 用于您传递的所有参数,尤其是那些直接从用户传递的参数(无论是表单发布还是 API 调用)。您应该使用 cfqueryparam cfsqltype=CF_SQL_DATE
使用上述任何一种方法(或所有方法),您应该将您的冷融合代码包装在一个 try/catch 结构中,并且更容易处理错误。
根据您的 DBMS,您可能也可以在那里访问 Try/catch 结构。
**** 更新:
在阅读了您对国际转换问题的评论后,我有两种方法可供选择:
请记住,我没有测试任何代码或任何东西......
首先,也许国际功能可以帮助你。
http://livedocs.adobe.com/coldfusion/8/htmldocs/help.html?content=functions_in-k_37.html
使用 Setlocale 将位置设置为英语(澳大利亚),然后使用 LSParseDateTime 以 yyyy-mm-dd 格式读取,然后使用 dateformat 使用 mm/dd/yyyy 或它期望的任何日期格式将其写入 mySQL。不过,我在处理这些 LS 函数方面没有太多经验。
第二个选项,使用您提供的正则表达式来确保输入具有正确的结构,然后使用 createDate 使用解析的 mm dd 和 yyyy 元素创建美国格式的日期。使用 isValid 验证 usdate。
这是第二个选项的盲目编码尝试。请记住,我没有测试过这段代码。我大量使用列表函数 listGetAt 将输入的日期时间拆分为单独的日期和时间字符串,然后使用 listGetAt 解析出各个日期部分。
<cfscript>
isosampledate = "2013-06-05 14:07:33";
passesValidation = false;
expectedDatePattern = "\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2}";
try {
if (refind(expectedDatePattern,isosampledate)) {
datePortion = listGetAt(isosampledate,1," ");
timePortion = listGetAt(isosampledate,2," ");
yearPart = listGetAt(datePortion,1,"-");
monthPart = listGetAt(datePortion,2,"-");
dayPart = listGetAt(datePortion,3,"-");
hoursPart = listGetAt(timePortion,1,":");
minutesPart = listGetAt(timePortion,2,":");
secondsPart = listGetAt(timePortion,3,":");
thisUSDate = createDateTime(yearPart,monthPart,dayPart,hoursPart,minutesPart,secondsPart)
if (isValid("usdate",thisUSDate) {
passesValidation = true;
sqlDate = CreateODBCDateTime(thisUSDate);
}
}
} catch (e:any) {
passesValidation = false;
}
</cfscript>
我很确定如果输入的值不是有效日期,那么这些日期函数中至少有一个会抛出异常,该异常会被 catch 块拾取。
希望这可以帮助。我要去睡觉了。