使用表值参数调用存储过程会返回错误

时间:2017-01-03 10:39:02

标签: c# sql-server triggers

我有一个类,我将其转换为数据表,因此我可以将其作为TVP传递给存储过程。

该类仅包含基本类型,例如intstringDateTimeGuid。转换为数据表后,我按如下方式调用存储过程:

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格式输出列?

0 个答案:

没有答案