From 13c3e4c3ec8e5934701d9d30858ecf52522fd76f Mon Sep 17 00:00:00 2001 From: yuetsh <517252939@qq.com> Date: Fri, 23 Oct 2026 15:13:28 +0800 Subject: [PATCH] =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=BA=93=EF=BC=9A=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E5=8C=96=E7=9A=84=E6=97=A5=E6=9C=9F=E5=AD=97=E7=AC=A6?= =?UTF-8?q?=E4=B8=B2=E6=AF=94=E8=BE=83=E6=97=B6=E4=B9=9F=E8=BD=AC=E6=8D=A2?= =?UTF-8?q?=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 教材项目 8 用参数传 "2024/1/23 23:59:59"(日期和时间之间两个空格)做 BETWEEN, 比较时用 tsql_cmp 把形如日期的字符串转成标准格式;日期和时间之间允许多个空格 Co-Authored-By: Claude Opus 5.5 --- runtime/Sim.Data/Engine/Functions.cs | 1 + runtime/Sim.Data/Engine/Translator.cs | 8 ++++++++ runtime/Sim.Data/Engine/Values.cs | 7 +++++-- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/runtime/Sim.Data/Engine/Functions.cs b/runtime/Sim.Data/Engine/Functions.cs index fc3096b..da4f8cc 100644 --- a/runtime/Sim.Data/Engine/Functions.cs +++ b/runtime/Sim.Data/Engine/Functions.cs @@ -44,6 +44,7 @@ internal static class Functions c.CreateFunction("tsql_ceiling", x => x is null ? null : Math.Ceiling(ToDouble(x)), isDeterministic: true); c.CreateFunction("tsql_power", (x, y) => x is null || y is null ? null : Math.Pow(ToDouble(x), ToDouble(y)), isDeterministic: true); c.CreateFunction("tsql_sqrt", x => x is null ? null : Math.Sqrt(ToDouble(x)), isDeterministic: true); + c.CreateFunction("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()); } diff --git a/runtime/Sim.Data/Engine/Translator.cs b/runtime/Sim.Data/Engine/Translator.cs index 5192095..8c062de 100644 --- a/runtime/Sim.Data/Engine/Translator.cs +++ b/runtime/Sim.Data/Engine/Translator.cs @@ -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); } } diff --git a/runtime/Sim.Data/Engine/Values.cs b/runtime/Sim.Data/Engine/Values.cs index fad7992..440aa8a 100644 --- a/runtime/Sim.Data/Engine/Values.cs +++ b/runtime/Sim.Data/Engine/Values.cs @@ -17,13 +17,16 @@ internal static class Values }; /// 形如日期的字符串字面量(比较时转成标准格式,例如 BETWEEN '2024/1/16 9:05:03' AND ...) - 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+)?)?)?$"); + + /// 日期和时间之间多余的空格(教材拼出的 "2024/1/23 23:59:59") + private static readonly Regex Spaces = new(@"\s+"); public static bool LooksLikeDate(string text) => DateLike.IsMatch(text.Trim()); /// 按 SQL Server 接受的写法解析日期(包括中文 Windows 上 DateTime.ToString() 的 2024/1/16 9:05:03) 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