高流量SQL表间歇性空输出参数

发布于 2024-11-29 05:00:41 字数 1390 浏览 3 评论 0原文

我的存储过程的输出参数间歇性出现空值。我想知道这是否与存储过程中的 NOLOCK 有关。大部分时间都有效,但偶尔会失败。特别是在高负载下。大多数时候它会返回您期望的“y”或“n”。

 SqlConnection con = getCon();
 SqlCommand cmd = new SqlCommand("loginRecord", con);
 cmd.CommandType = CommandType.StoredProcedure;
 cmd.Parameters.Add(new SqlParameter("@username", username));
 cmd.Parameters.Add(new System.Data.SqlClient.SqlParameter("@exists", System.Data.SqlDbType.VarChar, 3, System.Data.ParameterDirection.Output, false, ((System.Byte)(0)), ((System.Byte)(0)), "", System.Data.DataRowVersion.Current, null));

 try
 {
     con.Open();
     cmd.ExecuteNonQuery();
 }
 catch (Exception ex)
 {
     Util.sendErrorEmail(ex.ToString());
}
finally
{
   con.Close();
}

 //The following line is the one that throws an "Object reference not set to an instance of an bject." exception
 string userExists = cmd.Parameters["@exists"].Value.ToString();

这是存储过程:

ALTER PROCEDURE [dbo].[loginRecord]
(
    @username nvarchar(100),
    @exists char(1) OUTPUT
)

AS
IF EXISTS(select username from Users WITH (NOLOCK) where username = @username)
    BEGIN
        set @exists='y'
    END
ELSE
    BEGIN
        set @exists='n'

        --insert user account--
        insert into Users (username, datejoined)
        values (@username, getdate())
    END
insert into Logins (username, logged)
values (@username, getdate())

GO

I'm getting an intermittent null value for an output parameter for a stored procedure I have. I'm wondering if it has to do with the NOLOCK inside the stored procedure. It works most of the time, it's intermittently failing. Especially under high load. Most of the time it returns the "y" or "n" you would expect.

 SqlConnection con = getCon();
 SqlCommand cmd = new SqlCommand("loginRecord", con);
 cmd.CommandType = CommandType.StoredProcedure;
 cmd.Parameters.Add(new SqlParameter("@username", username));
 cmd.Parameters.Add(new System.Data.SqlClient.SqlParameter("@exists", System.Data.SqlDbType.VarChar, 3, System.Data.ParameterDirection.Output, false, ((System.Byte)(0)), ((System.Byte)(0)), "", System.Data.DataRowVersion.Current, null));

 try
 {
     con.Open();
     cmd.ExecuteNonQuery();
 }
 catch (Exception ex)
 {
     Util.sendErrorEmail(ex.ToString());
}
finally
{
   con.Close();
}

 //The following line is the one that throws an "Object reference not set to an instance of an bject." exception
 string userExists = cmd.Parameters["@exists"].Value.ToString();

Here is the stored procedure:

ALTER PROCEDURE [dbo].[loginRecord]
(
    @username nvarchar(100),
    @exists char(1) OUTPUT
)

AS
IF EXISTS(select username from Users WITH (NOLOCK) where username = @username)
    BEGIN
        set @exists='y'
    END
ELSE
    BEGIN
        set @exists='n'

        --insert user account--
        insert into Users (username, datejoined)
        values (@username, getdate())
    END
insert into Logins (username, logged)
values (@username, getdate())

GO

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

故笙诉离歌 2024-12-06 05:00:41

我的猜测是在为 @exists 赋值之前发生了异常。我会将捕获更改为:

Catch(Exception ex)
{
Util.sendErrorEmail(例如.ToString());
返回;
}

My guess is that an exception is occurring before @exists is assigned a value. I'd change my catch to be:

Catch(Exception ex)
{
Util.sendErrorEmail(ex.ToString());
return;
}

遗心遗梦遗幸福 2024-12-06 05:00:41

我认为这与存储过程的实现无关。
如果您故意从存储过程中为 @exists 变量返回 null,则在 C# 中“cmd.Parameters["@exists"].Value”将不会为 null。
相反,它将是“System.DBNull”,它是一个有效的对象,您可以调用方法。

这不是问题的直接答案,但它会帮助您缩小范围。

I think it has nothing to do with stored procedure implementation.
Event if you deliberately return null for @exists variable from stored procedure, "cmd.Parameters["@exists"].Value" will not be null in C#.
Instead it will be 'System.DBNull' which is a valid object, you can call methods on.

This is not an direct answer to the question but it will help you narrow it down.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文