2013-10-29 76 views
0

我創建了一個MySQL的過程,但它不是設定在正確的SQL查詢執行的情況下支付= 1的值:MySQL存儲過程不工作

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 

回答

1

您從您的存儲過程的開始缺少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

+0

我還沒有在這裏寫其默認的男人:)和問題解決 –