我有一个类,我将其转换为数据表,因此我可以将其作为TVP传递给存储过程。
该类仅包含基本类型,例如int
,string
,DateTime
和Guid
。转换为数据表后,我按如下方式调用存储过程:
var ids = connection.Query<int>("create_records", new { records }, commandType: CommandType.StoredProcedure);
使用SQL Server Profiler进行监控时,我可以看到SQL已正确创建,并且我可以在T-SQL中成功执行相同的SQL。
但是,从代码执行存储过程时,我收到以下错误:
XML解析:第1行,第2112字符,无效的名称字符。
例外是:
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)
at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, 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 asyncWrite)
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 Dapper.SqlMapper.ExecuteReaderWithFlagsFallback(IDbCommand cmd, Boolean wasClosed, CommandBehavior behavior)
at Dapper.SqlMapper.<QueryImpl>d__125`1.MoveNext()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at Dapper.SqlMapper.Query[T](IDbConnection cnn, String sql, Object param, IDbTransaction transaction, Boolean buffered, Nullable`1 commandTimeout, Nullable`1 commandType)
存储过程将TVP记录插入到几个不同的表中,最后执行以下操作:
SELECT id FROM @insertedRecords;
其中@insertedRecords
是一个只有1列(int)的表类型,并且填充了MERGE
语句中插入记录的id&#39; s。使用代码传递的相同数据从T-SQL
内执行存储过程工作正常,并按预期插入记录。
更新
进一步调试后,问题在于与表关联的审计触发器。修改后的触发器的摘录是:
declare @xml xml;
set @xml = (SELECT '' as 'id/old', ISNULL(i.[id], '') as 'id/new'
FROM inserted AS i FOR XML PATH('inserts'));
insert into _temp select @xml;
注意:选择包括所有表格的列,而不仅仅是一列。 &#39; _temp&#39;只是一个包含一列(xml
)的表。
从代码插入记录时触发器失败的原始问题仍然存在。
是否有另一种方法可以在不使用FOR XML
或至少禁用解析的情况下以xml格式输出列?