您從您的存儲過程的開始缺少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
在更新之前檢查,儘管這是不太可能的,我在開始檢查和執行更新之間,數據被另一個會話改變並不是不可能的。這可能會導致意外的行爲。如果您在一個語句中完成所有操作,則可避免併發問題。
Example on SQL Fiddle
我還沒有在這裏寫其默認的男人:)和問題解決 –