ML.Net Model Builder训练时出现'SQL关键字Open附近语法错误'
问题复现环境
- 工具链:Visual Studio 2019,内置ML.NET Model Builder版本16.3.0.2056001
- 项目配置:.Net 5.0目标框架,由官方脚手架自动生成的标准空项目
- 复现流程:
- 新建项目后启动Model Builder向导,依次选择「添加 > 机器学习 > 连接到SQL Server」
- 完成数据库连接配置后,连通性测试正常,数据表预览可正确加载字段和内容
- 进入训练配置页面,点击「开始训练」后触发运行时错误
- 核心错误提示:
Incorrect syntax near the keyword 'Open' - 堆栈跟踪:
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction) at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose) at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady) at System.Data.SqlClient.SqlDataReader.TryConsumeMetaData() at System.Data.SqlClient.SqlDataReader.get_MetaData() at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString, Boolean isInternal, Boolean forDescribeParameterEncryption, Boolean shouldCacheForAlwaysEncrypted) at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, Boolean inRetry, SqlDataReader ds, Boolean describeParameterEncryptionRequest) at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry) at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method) at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method) at Microsoft.ML.Data.DatabaseLoader.Cursor.get_DataReader() at Microsoft.ML.Data.DatabaseLoader.Cursor.MoveNextCore() at Microsoft.ML.Data.RootCursorBase.MoveNext() at Microsoft.ML.AutoML.DatasetDimensionsUtil.CountRows(IDataView data, UInt64 maxRows) at Microsoft.ML.AutoML.ExperimentBase`2.Execute(IDataView trainData, ColumnInformation columnInformation, IEstimator`1 preFeaturizer, IProgress`1 progressHandler) at Microsoft.ML.ModelBuilder.AutoMLService.Experiments.AutoMLExperiment`3.<>c__DisplayClass21_0.<b__5>d.MoveNext() in //src/Microsoft.ML.ModelBuilder.AutoMLService/Experiments/AutoMLExperiment.cs:line 80 at System.Threading.Tasks.Task`1.InnerInvoke() at System.Threading.Tasks.Task.Execute() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.ML.ModelBuilder.AutoMLService.Experiments.AutoMLExperiment`3.<ExecuteExperimentAsync>d__21.MoveNext() in //src/Microsoft.ML.ModelBuilder.AutoMLService/Experiments/AutoMLExperiment.cs:line 107 --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.ML.ModelBuilder.AutoMLEngine.<RunAsync>d__26.MoveNext() in /_/src/Microsoft.ML.ModelBuilder.AutoMLService/AutoMLEngineService/AutoMLEngine.cs:line 150
- 已尝试的排查操作:在项目中手动添加
Microsoft.ML 1.5.4、Microsoft.ML.Experimental 0.17.4NuGet包,项目csproj配置如下:
<Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <TargetFramework>net5.0</TargetFramework> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.ML" Version="1.5.4" /> <PackageReference Include="Microsoft.ML.Experimental" Version="0.17.4" /> </ItemGroup> </Project>
报错本质
这是对应版本Model Builder的内置Bug,和你的数据库配置、项目代码完全无关:
- 16.3.0.2056001版本的Model Builder内置DatabaseLoader组件,生成SQL Server查询语句时存在硬编码错误:本来应该写
SELECT * FROM 你的表名,结果它在表名前面多拼了个Open关键字,生成的SQL完全不符合T-SQL语法规范,SQL Server执行到这段错误语句时,就会抛出“关键字Open附近有语法错误”的提示。 - 手动加NuGet包的操作完全没用:因为Model Builder训练流程调用的是扩展自身内置的ML.NET运行时,根本不会读取你项目里手动引用的ML.NET包版本,自然也覆盖不了组件本身的错误逻辑。
可直接用的解决方法
- 绕开自动生成SQL的逻辑:在Model Builder的SQL Server数据源配置页,不要直接选择现成的数据表,切换到「自定义SQL查询」选项,手动写符合规范的查询语句(比如
SELECT * FROM [你的架构名].[你的表名]),从根源上避开组件生成的错误SQL。 - 升级Model Builder扩展:在Visual Studio的扩展管理面板,把ML.NET Model Builder升级到16.8及以上版本,这个版本已经修复了DatabaseLoader的SQL拼接Bug,完全兼容.Net 5.0项目。
- 临时替代方案:如果暂时没法升级扩展,可以先把目标数据表导出为CSV格式文件,选择Model Builder的「本地文件数据源」导入数据完成全流程训练,等后续升级了扩展再切回直连数据库的模式。
内容的提问来源于stack exchange,提问作者Holland Risley
相关产品推荐
相关产品推荐

