我有一个按钮事件,在达到一定数量的用户后必须自行禁用。
我们将当前访问的用户计数存储在db中,我正在尝试创建一个存储过程,在调用时,将自动增加该表上的用户计数。
我将创建一个单独的程序来减去。
在我看来,我需要获取当前值,添加一个,然后将其保存在表中,将我带到此代码:
CREATE PROCEDURE procDrRefBooksAddUser
-- Add the parameters for the stored procedure here
@fileId int = NULL,
@count int = 0,
@newCount int OUTPUT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
SELECT UserCount FROM tblDrRefBooks WHERE DrRefBookFileID = @fileId
SET @count = UserCount
SET @newCount = @count + 1
-- Insert statements for procedure here
UPDATE tblDrRefBooks SET tblDrRefBooks.UserCount = @newCount WHERE DrRefBookFileID = @fileId
END
不幸的是,我无法做到正确,想出了以下错误:
Msg 207, Level 16, State 1, Procedure procDrRefBooksAddUser, Line 17
Invalid column name 'UserCount'
有人可以告诉我哪里出错了。
编辑:答案更新(最后)
我的SQL是:
ALTER PROCEDURE [dbo].[procDrRefBooksAddUser]
-- Add the parameters for the stored procedure here
@fileId int = NULL,
@newCount int OUTPUT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
-- SET NOCOUNT ON;
UPDATE tblDrRefBooks
SET @newCount = UserCount = UserCount + 1
WHERE DrRefBookFileID = @fileId
SELECT @newCount AS iden
END
背后的代码是:
using (SqlConnection db = DataConn.SqlConnection())
{
db.Open();
SqlTransaction transaction = db.BeginTransaction();
try
{
lbltest.Text = "Starting...";
using (SqlCommand acommand =
new SqlCommand(
"EXEC procDrRefBooksAddUser @fileID, @count",
db, transaction) { CommandType = CommandType.Text })
{
acommand.Parameters.Add(new SqlParameter("@fileID", SqlDbType.Int)).Value = Int32.Parse(location.Value);
acommand.Parameters.Add(new SqlParameter("@count", SqlDbType.Int) { Direction = ParameterDirection.Output });
using (SqlDataReader rdr = acommand.ExecuteReader())
{
btnLoad.Text = "Here: " + rdr["iden"];
}
}
transaction.Commit();
}
catch (Exception ea)
{
transaction.Rollback();
lbltest.Text = ("Insertion Error: " + ea.Message);
}
}
但是我收到了这个错误:Insertion Error: Invalid attempt to read when no data is present.
答案 0 :(得分:2)
SET @count = UserCount
不正确。您无法访问之前SELECT
语句中的列。
你可以在一个原子语句中完成所有操作。这会使列递增,并使用UserCount的新值设置输出参数。
UPDATE tblDrRefBooks
SET @newCount = UserCount = UserCount + 1
WHERE DrRefBookFileID = @fileId
这可以避免竞争条件在单独的操作中读取和写入值。
答案 1 :(得分:1)
对于参考案例,它应该是这样的
SELECT @Count = UserCount FROM tblDrRefBooks WHERE DrRefBookFileID = @fileId
@newCount = @Count + 1
但你可以避免这种情况而不是
UPDATE tblDrRefBooks SET UserCount = UserCount + 1
WHERE
DrRefBookFileID = @fileId AND
UserCount < @MaxUserCount
注意我添加了AND UserCount < @MaxUserCount
。由于页面快速刷新[竞争条件],您的存储过程可能无法捕获所有计数。你可能有一个旧的@Count值。
答案 2 :(得分:1)
在您的程序中使用以下代码:
SELECT @ count = UserCount FROM tblDrRefBooks WHERE DrRefBookFileID = @fileId
答案 3 :(得分:0)
无需使用临时变量和使用select查询。 试试这个..
UPDATE tblDrRefBooks
SET tblDrRefBooks.UserCount = UserCount +1
WHERE DrRefBookFileID = @fileId