如何使用NLog Configuration API将NULL写入数据库中的列?

tek*_*irl 8 c# sql-server asp.net-mvc stored-procedures nlog

我看过这个问题,但是因为它使用了NLog.config文件,所以我无法将答案转化为我需要的内容.NLog - 将NULL写入可选数据库列

我刚刚开始使用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);";
Run Code Online (Sandbox Code Playgroud)

然后向目标添加参数,例如

var param = new DatabaseParameterInfo();
param.Name = "@time_stamp";
param.Layout = "${date}";
target.Parameters.Add(param);
Run Code Online (Sandbox Code Playgroud)

所以这只会添加一个空字符串:

var param = new DatabaseParameterInfo();
param.Name = "@type";
param.Layout = "";
target.Parameters.Add(param);
Run Code Online (Sandbox Code Playgroud)

但这不起作用,因为需要布局:

var param = new DatabaseParameterInfo();
param.Name = "@time_stamp";
param.Layout = null;
target.Parameters.Add(param);
Run Code Online (Sandbox Code Playgroud)

我已经尝试执行存储过程,更改命令文本如下(并在之后添加上面的参数,包括空字符串而不是空值):

target.CommandText = "exec usp_InsertLog @time_stamp, @level, @logger, @message, @type, @target, @trace, @data, @inner";
Run Code Online (Sandbox Code Playgroud)

根据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''
Run Code Online (Sandbox Code Playgroud)

如果我可以让存储过程工作,那么我可以让它插入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
Run Code Online (Sandbox Code Playgroud)

有没有我错过的东西,或者更好的方法呢?

非常感谢!

Fer*_*ero 5

这是我在NLog上发布的一个解决方案- 将NULL写入可选数据库列,我希望它有用,因为我认为存储过程解决方案就像用大锤破解螺母一样.

您可以尝试使用NULLIF比较2个表达式的函数编写NULL,如果它们相等则返回NULL,否则返回第一个表达式(msdn NULLIF页面).

这样,NLog配置文件中的commandText看起来像:

INSERT INTO [dbo].[log] ([message], [optional]) 
VALUES (@message, NULLIF(@optional, ''))
Run Code Online (Sandbox Code Playgroud)


M.A*_*Ali 0

在sql server中你可以做这样的事情

\n\n
DECLARE @Var1 INT, @Var2 INT, @Var3 INT, @Var4 VARCHAR(10)\n       , @Var5 VARCHAR(5), @SubsituteVal_Int INT , @SubsituteVal_Char VARCHAR(10)\nSET @Var1 = 1;\nSET @Var3 = 3;               --<-- Didnt Assign any Values to @Var2 and @Var4\nSET @Var5 = 'Fifth';\nSET @SubsituteVal_Int = 100          --<-- Provided Substitute values if actual \nSET @SubsituteVal_Char = 'No Value';    -- values are null.\n
Run Code Online (Sandbox Code Playgroud)\n\n

/使用 COALESCE 函数提供实际值和替代值/

\n\n
DECLARE @t TABLE(Column1 INT, Column2 INT, Column3 INT, Column4 VARCHAR(10), Column5 VARCHAR(10))\nINSERT INTO @t\nVALUES (COALESCE(@Var1, @SubsituteVal_Int),COALESCE(@Var2, @SubsituteVal_Int)\n       ,COALESCE(@Var3, @SubsituteVal_Int),COALESCE(@Var4, @SubsituteVal_Char),COALESCE(@Var5, @SubsituteVal_Char))\nSELECT * FROM @t\n
Run Code Online (Sandbox Code Playgroud)\n\n

结果集

\n\n
\xe2\x95\x94\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xa6\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xa6\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xa6\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xa6\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x97\n\xe2\x95\x91 Column1 \xe2\x95\x91 Column2 \xe2\x95\x91 Column3 \xe2\x95\x91 Column4  \xe2\x95\x91 Column5 \xe2\x95\x91\n\xe2\x95\xa0\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xac\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xac\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xac\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xac\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xa3\n\xe2\x95\x91       1 \xe2\x95\x91     100 \xe2\x95\x91       3 \xe2\x95\x91 No Value \xe2\x95\x91 Fifth   \xe2\x95\x91\n\xe2\x95\x9a\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xa9\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xa9\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xa9\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xa9\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x9d\n
Run Code Online (Sandbox Code Playgroud)\n\n

你的过程

\n\n

对于你的程序,你可以做类似的事情

\n\n
BEGIN TRY\ninsert into Log(\n    time_stamp,\n    log_level,\n    logger,\n    [message],\n    exception_type,\n    target_site,\n    stack_trace,\n    data,\n    inner_exception) \nvalues(\n     COALESCE(@time_stamp, @Subsitute_Val1) \n    ,COALESCE(@level, @Subsitute_Val2)\n    ,COALESCE(@logger, @Subsitute_Val3)\n    .\n    .. so on.... ) \nEND TRY\n
Run Code Online (Sandbox Code Playgroud)\n