【发布时间】:2014-01-03 17:06:35
【问题描述】:
我看过这个问题,但由于它使用 NLog.config 文件,我不能不将答案翻译成我需要的。 NLog - Write NULL to optional database column
在有人建议我回答我提出的另一个问题之后,我才开始使用 NLog。由于我在类库中使用它,并且我不想将 NLog.config 文件放置在使用该库的每个应用程序中,因此我使用的是配置 API。
我想要做的是在我的日志表中将一些列设置为 NULL,当它们不需要/指定时。我可以让 NLog 写一个空字符串,但不能写一个 NULL。
我尝试配置 NLog 来执行存储过程,但它似乎不起作用。
目前我正在使用用户名、密码等设置数据库目标,以及以下命令文本:
target.CommandText = "insert into Log(time_stamp,log_level,logger,message,exception_type,target_site,stack_trace,data,inner_exception) values(@time_stamp, @level, @logger, @message, @type, @target, @trace, @data, @inner);";
然后给目标添加参数,例如
var param = new DatabaseParameterInfo();
param.Name = "@time_stamp";
param.Layout = "${date}";
target.Parameters.Add(param);
所以这将只添加一个空字符串:
var param = new DatabaseParameterInfo();
param.Name = "@type";
param.Layout = "";
target.Parameters.Add(param);
但这不起作用,因为需要布局:
var param = new DatabaseParameterInfo();
param.Name = "@time_stamp";
param.Layout = null;
target.Parameters.Add(param);
我曾尝试执行存储过程,将命令文本更改如下(然后添加上述参数,包括空字符串而不是空值):
target.CommandText = "exec usp_InsertLog @time_stamp, @level, @logger, @message, @type, @target, @trace, @data, @inner";
根据 SQL Server Profiler(为清楚起见,换行符)会生成此内容:
exec sp_executesql N'
exec usp_InsertLog @time_stamp, @level, @logger, @message, @type, @target, @trace, @data, @inner',
N'@time_stamp nvarchar(19),@level nvarchar(5),@logger nvarchar(62),@message nvarchar(8),@type nvarchar(4000),@target nvarchar(4000),@trace nvarchar(4000),@data nvarchar(4000),@inner nvarchar(4000)',
@time_stamp=N'01/03/2014 17:00:38',@level=N'Debug',@logger=N'Testbed, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null',@message=N'an error',@type=N'',@target=N'',@trace=N'',@data=N'',@inner=N''
如果我可以让存储过程工作,那么我可以让它插入 NULL 而不是空字符串,如果那是 NLog 传递的内容。
这里是目前的存储过程,不管值是否为空都不起作用:
ALTER PROCEDURE [dbo].[usp_InsertLog]
@time_stamp datetime,
@level nvarchar(100),
@logger nvarchar(100),
@message nvarchar(MAX),
@type nvarchar(150) = NULL,
@target nvarchar(100) = NULL,
@trace nvarchar(MAX) = NULL,
@data nvarchar(MAX) = NULL,
@inner nvarchar(MAX) = NULL
AS
SET NOCOUNT ON
BEGIN TRY
insert into Log(
time_stamp,
log_level,
logger,
[message],
exception_type,
target_site,
stack_trace,
data,
inner_exception)
values(
@time_stamp,
@level,
@logger,
@message,
@type,
@target,
@trace,
@data,
@inner)
END TRY
有什么我错过的,或者更好的方法吗?
非常感谢!
【问题讨论】:
-
该过程要求您发送带值的参数,如果参数没有值,则更改您的 SPROC 参数定义并提供默认值,例如 @timestamp DATETIME = GETDATE()
-
为什么需要布局?我从来没有用过,这是什么数据库?
-
我将创建一个返回 NULL 的自定义布局:
public class NullLayout : Layout { protected override string GetFormattedMessage(LogEventInfo logEvent) { return "NULL"; } }并在您的参数中使用它:param.Layout = new NullLayout(); -
我已要求将此功能添加到 NLog 中,并且正在对其进行调查,例如
param.Layout = null;将 NULL 插入数据库。对于我的特定场景,我现在决定记录到两个不同的表,所以现在不需要 NULL。
标签: c# sql-server asp.net-mvc stored-procedures nlog