数据库:参数化的日期字符串比较时也转换格式
- 教材项目 8 用参数传 "2024/1/23 23:59:59"(日期和时间之间两个空格)做 BETWEEN, 比较时用 tsql_cmp 把形如日期的字符串转成标准格式;日期和时间之间允许多个空格 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
19d6872d80
commit
13c3e4c3ec
3 files changed
+14
-2
No files matched your search
@@ -44,6 +44,7 @@ internal static class Functions
|
||||
c.CreateFunction<object?, object?>("tsql_ceiling", x => x is null ? null : Math.Ceiling(ToDouble(x)), isDeterministic: true);
|
||||
c.CreateFunction<object?, object?, object?>("tsql_power", (x, y) => x is null || y is null ? null : Math.Pow(ToDouble(x), ToDouble(y)), isDeterministic: true);
|
||||
c.CreateFunction<object?, object?>("tsql_sqrt", x => x is null ? null : Math.Sqrt(ToDouble(x)), isDeterministic: true);
|
||||
c.CreateFunction<object?, object?>("tsql_cmp", v => v is string s && Values.LooksLikeDate(s) ? Values.NormalizeDateLiteral(s) : v, isDeterministic: true);
|
||||
c.CreateFunction("tsql_newid", () => Guid.NewGuid().ToString().ToUpperInvariant());
|
||||
c.CreateFunction("tsql_rand", () => Random.Shared.NextDouble());
|
||||
}
|
||||
|
||||
@@ -911,6 +911,14 @@ internal sealed class Translator
|
||||
_sql.Append(Values.Quote(Values.NormalizeDateLiteral(s.Value)));
|
||||
return;
|
||||
}
|
||||
// 参数的值执行时才知道:是日期样子的字符串时同样转成标准格式(教材 BETWEEN @time_start AND @time_end 传的是字符串)
|
||||
if (expression is VariableReference)
|
||||
{
|
||||
_sql.Append("tsql_cmp(");
|
||||
Expression(expression);
|
||||
_sql.Append(')');
|
||||
return;
|
||||
}
|
||||
Expression(expression);
|
||||
}
|
||||
}
|
||||
@@ -17,13 +17,16 @@ internal static class Values
|
||||
};
|
||||
|
||||
/// <summary>形如日期的字符串字面量(比较时转成标准格式,例如 BETWEEN '2024/1/16 9:05:03' AND ...)</summary>
|
||||
private static readonly Regex DateLike = new(@"^\d{4}[-/.]\d{1,2}[-/.]\d{1,2}([ T]\d{1,2}:\d{1,2}(:\d{1,2}(\.\d+)?)?)?$");
|
||||
private static readonly Regex DateLike = new(@"^\d{4}[-/.]\d{1,2}[-/.]\d{1,2}((\s+|T)\d{1,2}:\d{1,2}(:\d{1,2}(\.\d+)?)?)?$");
|
||||
|
||||
/// <summary>日期和时间之间多余的空格(教材拼出的 "2024/1/23 23:59:59")</summary>
|
||||
private static readonly Regex Spaces = new(@"\s+");
|
||||
|
||||
public static bool LooksLikeDate(string text) => DateLike.IsMatch(text.Trim());
|
||||
|
||||
/// <summary>按 SQL Server 接受的写法解析日期(包括中文 Windows 上 DateTime.ToString() 的 2024/1/16 9:05:03)</summary>
|
||||
public static bool TryParseDateTime(string text, out DateTime value) =>
|
||||
DateTime.TryParseExact(text.Trim(), DateFormats, CultureInfo.InvariantCulture, DateTimeStyles.AllowWhiteSpaces, out value);
|
||||
DateTime.TryParseExact(Spaces.Replace(text.Trim(), " "), DateFormats, CultureInfo.InvariantCulture, DateTimeStyles.AllowWhiteSpaces, out value);
|
||||
|
||||
public static string FormatDateTime(DateTime value) =>
|
||||
value.Millisecond == 0 && value.Ticks % TimeSpan.TicksPerMillisecond == 0
|
||||
|
||||
Reference in new issue
Block a user