2011-12-12 72 views
1

我試圖做一個程序,它將檢查用戶是否已經登錄(他有一個會話,並檢查他的最後一個動作是否超過15分鐘)。我的過程是這樣的:這個簡短的程序有什麼問題(MySQL)

CREATE PROCEDURE `isLogged`(in p_sessid VARCHAR(32), out res INT(1)) 
BEGIN 
    DECLARE v_customer_id INT(9); 
    DECLARE v_date DATE; 

    SELECT customer_id INTO v_customer_id FROM Sessions WHERE sessid=p_sessid; 
    SELECT expiry_date INTO v_date FROM Sessions WHERE sessid=p_sessid; 

    SET res=3; 

    IF v_customer_id > 0 THEN 
     IF UNIX_TIMESTAMP(NOW()) > UNIX_TIMESTAMP(v_date) THEN 
     DELETE FROM Sessions WHERE sessid=p_sessid; 
     SET res=1; 
    ELSE 
     UPDATE Sessions SET expiry_date=DATE_ADD(NOW(), INTERVAL 15 MINUTE) WHERE customer_id=v_customer_id; 
     SET res=0; 
     END IF; 
    END IF; 
END 

誰能告訴,爲什麼它總是返回1,什麼是指用戶不再登錄?我正在手動檢查表達式UNIX_TIMESTAMP(NOW())> UNIX_TIMESTAMP(v_date),它給了我0的迴應,所以?這是怎麼回事?

由於提前, 馬辛

+0

在我看來,一切都很好,但它不起作用。我需要找到任何調試器,我可以在其中放置表達式,斷點,並逐步檢查變量中的值。 – marxin

+0

你有沒有在我的答案中看到調試器鏈接? – Devart

回答

2

第一IF語句應該這樣寫:

UNIX_TIMESTAMP(NOW()) > UNIX_TIMESTAMP(DATE_ADD(v_date, INTERVAL 15 MINUTE)) 

要不然現在總是比最後的登錄日期。

+0

當我設定日期時,我總是在那裏()+ 15分鐘,所以它不是真的。 – marxin

0

您可以重寫/優化您的程序來運行。例如 -

CREATE FUNCTION `isLogged`(IN p_sessid VARCHAR(32)) 
    RETURNS INT 
BEGIN 

    DELETE FROM Sessions WHERE sessid = p_sessid AND v_date <= NOW() - INTERVAL 15 MINUTE; 
    IF ROW_COUNT() > 0 THEN -- check how many rows were deleted 
    RETURN 1; 
    ELSE 
    UPDATE Sessions SET expiry_date = NOW() + INTERVAL 15 MINUTE WHERE customer_id = v_customer_id; 
    IF ROW_COUNT() > 0 THEN -- check how many rows were updated 
     RETURN 0; 
    END IF; 
    END IF; 
    RETURN 3; 
END 

此外,您還可以嘗試debug代碼理解的錯誤。

+0

您設置NOW()+ 15分鐘的到期日期,並檢查到期日是否低於NOW() - 15分鐘。這不好。可以說,它的7點。你檢查,如果你登錄。它的真實和有效期限是7點15分。然後,5分鐘後,您執行操作,如果7:15低於7:05 - 15分鐘 - >如果7:15 <6:55,您的腳本將檢查腳本。壞邏輯。 30分鐘或更長時間後可能會降低。 – marxin

+0

我沒有建議你有時間差異的邏輯。我建議你另外一個邏輯來跳過第一個SELECT語句。 – Devart

+0

問題解決了:)閱讀下一篇文章。 – marxin

0

Omg,這很愚蠢。

有一個類型不匹配。 v_date類型是DATE,這只是一天!像2011-12-14一樣。

解決方案:

變化DATE - > DATETIME。

現在一切正常。 無論如何,謝謝你的答案。