很难相信,但我似乎无法找到一个直接的答案:当语句生成异常且仅时,如何获取包含参数值的 SQL 语句当它生成异常时。我知道如何记录生成的每个 SQL 的语句+参数,但这太多了。但是,当出现 System.Data.SqlClient.SqlException 时,它仅提供 SQL,而不提供参数值。我怎样才能在我有权访问该数据的地方捕获它以便我可以记录它?
最佳答案
根据对各种问题(不仅仅是我的)的大量答复,我拼凑了一些可以解决问题的东西。我认为它对其他人也很有用,所以我在这里包含了很多内容:
基本思想是
- 让 NH 记录所有查询,打印精美并带有参数值原位
- 抛出除异常之前的日志之外的所有日志。
我使用Log4Net,设置如下:
<?xml version="1.0"?>
<log4net>
<appender name="RockAndRoll" type="Util.PrettySqlRollingFileAppender, Util">
<file type="log4net.Util.PatternString" >
<conversionPattern value="%env{Temp}\\%property{LogDir}\\MyApp.log" />
</file>
<DatePattern value="MM-dd-yyyy" />
<appendToFile value="true" />
<immediateFlush value="true" />
<rollingStyle value="Composite" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="100MB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %-5level %logger - %message%newline" />
</layout>
</appender>
<appender name="ErrorBufferingAppender" type="log4net.Appender.BufferingForwardingAppender">
<bufferSize value="2" />
<lossy value="true" />
<evaluator type="log4net.Core.LevelEvaluator">
<threshold value="ERROR" />
</evaluator>
<appender-ref ref="RockAndRoll" />
<Fix value="0" />
</appender>
<logger name="NHibernate.SQL">
<additivity>false</additivity>
<appender-ref ref="ErrorBufferingAppender" />
<level value="debug" />
</logger>
<logger name="error-buffer">
<additivity>false</additivity>
<appender-ref ref="ErrorBufferingAppender" />
<level value="debug" />
</logger>
<root>
<level value="info" />
<appender-ref ref="RockAndRoll" />
</root>
</log4net>
NHibernate.SQL
记录器将所有查询记录到 ErrorBufferingAppender
,该查询不断地抛出它们并仅将最后一个查询保存在其缓冲区中。当我捕获异常时,我将错误级别的一行记录到记录器 error-buffer
中,后者将其传递给 ErrorBufferingAppender
,因为它处于错误级别 - 将其推送,与最后一个查询一起,发送到 RockAndRoll
,我的 RollingFileAppender
。
我实现了一个名为 PrettySqlRollingFileAppender
的 RollingFileAppender 子类(如果有人感兴趣,我很乐意提供),它从查询末尾获取参数并替换它们在查询本身内部,使其更具可读性。
关于nhibernate - 如何获取带有异常参数值的 SQL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42888947/