TooManyRowsAffectedException with encrypted triggers

10 浏览
0 Comments

TooManyRowsAffectedException with encrypted triggers

我正在使用nHibernate来更新一个表中的2列,该表上有3个加密触发器。这些触发器不是我拥有的,我无法对它们进行更改,所以很遗憾我不能在它们内部设置SET NOCOUNT ON。

有没有其他方法来解决在提交时抛出的TooManyRowsAffectedException异常呢?

更新1

到目前为止,我唯一解决这个问题的方法是绕过.Save例程,使用以下代码:

var query = session.CreateSQLQuery("update Orders set Notes = :Notes, Status = :Status where OrderId = :Order");
query.SetString("Notes", orderHeader.Notes);
query.SetString("Status", orderHeader.OrderStatus);
query.SetInt32("Order", orderHeader.OrderHeaderId);
query.ExecuteUpdate();

感觉有些不太正规,而且不容易扩展,但至少不会崩溃。

0
0 Comments

问题原因:当我们使用加密触发器时,可能会遇到TooManyRowsAffectedException异常。这是因为加密触发器会导致返回的结果集变得不可用,从而触发异常。

解决方法:设置"Disallow Results from Triggers"选项为1可以解决该问题。注意,该选项在将来的Microsoft SQL Server版本中将不再可用,但在不可用之后,它将表现得就像设置为1一样。因此,现在将其设置为1可以修复问题,并且还可以获得与将来版本相同的行为。

代码示例:

-- 设置"Disallow Results from Triggers"选项为1
EXEC sp_configure 'Disallow Results from Triggers', 1;
RECONFIGURE;

请注意,这只是一个临时解决方法,因为将来的SQL Server版本中将不再支持该选项。因此,在使用加密触发器时,我们可能需要寻找其他替代方案来避免出现TooManyRowsAffectedException异常。

0
0 Comments

问题的原因是由于NHibernate的默认行为,在使用加密触发器时,可能会导致TooManyRowsAffectedException异常。解决方法是通过创建自己的IBatcherFactory实现,然后重写AddToBatch方法,从提供的IExpectation对象中移除对VerifyOutcomeNonBatched方法的调用。

对于Sybase数据库,实现如下:

public class NonVerifyingBatcherFactory : IBatcherFactory
{
    public virtual IBatcher CreateBatcher(ConnectionManager connectionManager, IInterceptor interceptor)
    {
        return new NonBatchingBatcherWithoutVerification(connectionManager, interceptor);
    }
}
public class NonBatchingBatcherWithoutVerification : NonBatchingBatcher
{
    public NonBatchingBatcherWithoutVerification(ConnectionManager connectionManager, IInterceptor interceptor) : base(connectionManager, interceptor)
    {}
    public override void AddToBatch(IExpectation expectation)
    {
        IDbCommand cmd = CurrentCommand;
        ExecuteNonQuery(cmd);
    }
}

对于SQL Server数据库,实现如下:

public class NonBatchingBatcherWithoutVerification : SqlClientBatchingBatcher
{
    public NonBatchingBatcherWithoutVerification(ConnectionManager connectionManager, IInterceptor interceptor) : base(connectionManager, interceptor)
    {}
    protected override void DoExecuteBatch(IDbCommand ps)
    {
        log.DebugFormat("Executing batch");
        CheckReaders();
        Prepare(currentBatch.BatchCommand);
        if (Factory.Settings.SqlStatementLogger.IsDebugEnabled)
        {
            Factory.Settings.SqlStatementLogger.LogBatchCommand(currentBatchCommandsLog.ToString());
            currentBatchCommandsLog = new StringBuilder().AppendLine("Batch commands:");
        }
        int rowsAffected = currentBatch.ExecuteNonQuery();
        currentBatch.Dispose();
        totalExpectedRowsAffected = 0;
        currentBatch = new SqlClientSqlCommandSet();
    }
}

然后,将新的类注入到NHibernate中,有两种方法可以实现:

1. 在adonet.factory_class配置属性中提供自己的IBatcherFactory实现的名称。

2. 创建一个实现IEmbeddedBatcherFactoryProvider接口的自定义驱动程序。

对于Sybase数据库,创建自定义驱动程序如下:

public class DriverWithCustomBatcherFactory : SybaseAdoNet12ClientDriver, IEmbeddedBatcherFactoryProvider
{
    public Type BatcherFactoryClass
    {
        get { return typeof(NonVerifyingBatcherFactory); }
    }
    //...other driver code for our project...
}

然后,在配置文件中使用自定义驱动程序:

var sf = Fluently.Configure()
    .Database(SybaseConfiguration.SybaseDialect.ConnectionString(_connectionString))
    .Mappings(m => m.FluentMappings.AddFromAssemblyOf<MyEntity>())
    .BuildSessionFactory();

最后,将adonet.batch_size属性设置为1,以确保使用新的批处理类。

对于SQL Server数据库,需要复制整个SqlClientBatchingBatcher类,并将相关字段设置为可访问,然后进行相应的修改即可。

以上是解决TooManyRowsAffectedException with encrypted triggers问题的方法。

0
0 Comments

这篇文章讨论了一个名为"TooManyRowsAffectedException with encrypted triggers"的问题,以及它的出现原因和解决方法。

问题的出现原因是在使用具有加密触发器的数据库时,可能会出现TooManyRowsAffectedException异常。这通常是因为加密触发器在处理数据时导致了过多的行受到影响。

解决此问题的方法之一是尝试解密存储过程。如果能够成功解密存储过程,可能可以解决该问题。然而,这并不总是可行的,因为有些情况下可能无法更改代码或禁用触发器。

另一种解决方法是使用SQL Server提供的"disallow results from triggers Option"。这个选项可以用于SQL Server 2005和SQL Server 2008,但在以后的版本中将被移除。不过,不确定这个选项是否会抑制行数的消息。

总之,破解加密并不是一个可行的解决方法,因此需要尝试其他的解决方法来解决"TooManyRowsAffectedException with encrypted triggers"问题。

0