MySql 存储过程不起作用
本文关键字:不起作用 存储过程 MySql | 更新日期: 2023-09-27 18:37:14
我创建了一个 mysql 过程,但在正确执行 sql 查询的情况下,它没有设置 paid=1 的值:
PROCEDURE `PaidUser`(in IpId varchar(45),in UId int(20))
BEGIN
if(select count(*) as count from users u inner join subscription s on u.ID=s.usersID inner join item i on i.id=s.itemID where i.item_typeID !=6 and u.ID = UId having count >0)
then
update location_byhits set Paid=1 where location_byhits.IpAddress =IpId;
END if;
end
您从存储过程开始就缺少CREATE
,通过添加此内容,我能够让您的过程在 SQL Fiddle 上工作(请注意,第 4 个结果集有一行付费更新)
为了进行测试,我创建了以下数据:
CREATE TABLE location_byhits (Paid INT, IpAddress INT);
CREATE TABLE Users (ID INT);
CREATE TABLE Subscription(ItemID INT, UsersID INT);
CREATE TABLE Item (ID INT, Item_TypeID INT);
//
INSERT location_byhits VALUES (0, '192.168.0.0'), (0, '192.168.0.1');
INSERT Users VALUES (1), (2);
INSERT Subscription (1, 1), (2, 2);
INSERT Item (1, 1), (2, 6);
然后使用各种参数调用该过程 4 次。
CALL PaidUser ('192.168.0.2', 1);
CALL PaidUser ('192.168.0.0', 3);
CALL PaidUser ('192.168.0.1', 2);
CALL PaidUser ('192.168.0.1', 1);
- 第一个不应更新,因为没有 IP 匹配。
- 第二个不应更新,因为没有用户匹配。
- 第三个不应更新,因为尽管存在用户和 IP 匹配项,但用户 2 没有关联的项目,其Item_TypeID为 6。
- 第四个应该更新,因为同时存在用户匹配和 ip 匹配,并且用户具有具有 ID 不是 6 的关联项。
不过,我倾向于重写您的存储过程,如下所示:
CREATE PROCEDURE `PaidUser`(in IpId VARCHAR(45),in UId INT(20))
BEGIN
UPDATE location_byhits
SET Paid = 1
WHERE location_byhits.IpAddress = IpId
AND EXISTS
( SELECT 1
FROM Users u
INNER JOIN Subscription s
ON u.ID = s.usersID
INNER JOIN Item i
ON i.ID = s.ItemID
WHERE i.Item_TypeID != 6
AND u.ID = UId
);
END
如果在更新之前进行检查,尽管可能性很小,但在开始检查和执行更新之间,数据被另一个会话更改并非不可能。这可能会导致意外行为。如果在单个语句中完成所有操作,则可以避免并发问题。
关于 SQL 小提琴的示例