提问人:Saman Khan1 提问时间:11/17/2023 最后编辑:Saman Khan1 更新时间:11/17/2023 访问量:90
如果用户尝试从多台计算机插入,则阻止插入 [已关闭]
Prevent insert if user trying to insert from multiple computers [closed]
问:
我有一张表,在为任何用户插入之前,我都会进行一些检查。我使用存储过程进行数据插入。有问题 如果用户使用两台计算机并尝试几乎同时插入(同时单击两台计算机中的“插入”按钮)。他们可以通过检查并插入无效数据。我怎样才能预防它们?
我尝试在插入语句之前在存储过程中进行检查,但仍然不起作用。
我还使用了交易块。
程序如下:
BEGIN TRAN
IF
(
(
SELECT SUM(Weight) FROM table
WHERE
MojavezCode = @certId AND
goodsTypeId = @goodType AND
isDeleted = 0 AND
DateSabt BETWEEN @StartDore AND @EndDore
)
> @sahmiye
)
BEGIN
RAISERROR ('---',15,18)
RETURN -9523
END
INSERT INTO table
(
FromKharidarID,
AmelKharidID,
DateSabt,
TimeSabt,
MojavezCode,
isDeleted,
goodsTypeId,
InsertUserIp,
UniqID,
Weight
)
VALUES
( @kharidarId,
@EtehadyeId,
( SELECT dbo.SolarDate(CONVERT(NVARCHAR(10), GETDATE(), 111))),
( SELECT CONVERT(NVARCHAR(12), GETDATE(), 108)),
LTRIM(RTRIM(@certId)) ,
0,
@goodType ,
LTRIM(RTRIM(@userIP)),
@uniqueId,
@Wight
)
COMMIT TRAN
答:
1赞
Charlieface
11/17/2023
#1
您需要有关子查询的提示,否则它不会锁定这些行。您还应该使用 和 来确保正确的回滚。WITH (HOLDLOCK, UPDLOCK)
IF
SET XACT_ABORT ON
THROW
SET XACT_ABORT ON;
BEGIN TRAN;
IF (
(
SELECT SUM(Weight)
FROM table WITH (HOLDLOCK, UPDLOCK)
WHERE
MojavezCode = @certId AND
goodsTypeId = @goodType AND
isDeleted = 0 AND
DateSabt BETWEEN @StartDore AND @EndDore
)
> @sahmiye
)
BEGIN
THROW 50001, N'---', 1;
END;
INSERT INTO table
(
FromKharidarID,
AmelKharidID,
DateSabt,
TimeSabt,
MojavezCode,
isDeleted,
goodsTypeId,
InsertUserIp,
UniqID,
Weight
)
VALUES
( @kharidarId,
@EtehadyeId,
( SELECT dbo.SolarDate(CONVERT(NVARCHAR(10), GETDATE(), 111))),
( SELECT CONVERT(NVARCHAR(12), GETDATE(), 108)),
LTRIM(RTRIM(@certId)) ,
0,
@goodType ,
LTRIM(RTRIM(@userIP)),
@uniqueId,
@Wight
);
COMMIT TRAN;
顺便说一句:您不应该将日期和时间存储在单独的字段中,而应该只使用 .你当然不应该把它们存放在田里。datetime2
nvarchar
评论
0赞
Dai
11/17/2023
零件的目的是什么?总体上,颠倒逻辑来保护不是更好吗?还是做 ?THROW 50001, N'---', 1;
IF
INSERT
INSERT INTO t ( ... ) SELECT x.a, x.b, x.c WHERE NOT EXISTS( SELECT TOP 1 1 FROM t )
0赞
Charlieface
11/17/2023
THROW
将立即结束批处理,因此它会保护它。是的,您可以这样做,但是您没有自定义错误消息。
评论
USE XACT_ABORT ON; BEGIN TRANSACTION txn; /* do stuff */ COMMIT TRANSACTION txn;