2016-11-25 275 views
1

我在mySQL中有一個存儲過程,它從表中獲取數據的一個子集,並對臨時表中的那個子集執行一些分析。這是我的代碼:mySQL創建多個臨時表

CREATE PROCEDURE GetPortfolioStats 
(
    InIdx_i  INT, 
    InStart_i INT, 
    InEnd_i  INT 
) 
BEGIN 

DECLARE myLimit  INT; 
DECLARE myOffset INT; 

SET myLimit = InEnd_i - InStart_i + 1; 
SET myOffset = InStart_i - 1; 

CREATE TEMPORARY TABLE IF NOT EXISTS myTmpTable AS (SELECT * FROM Leases WHERE Portfolio_i = InIdx_i ORDER BY Index_i LIMIT myLimit OFFSET myOffset); 

SET @Additive_i := (SELECT COUNT(Index_i) FROM myTmpTable WHERE ReviewType_vc = 'Additive'); 
DROP TABLE myTmpTable; 

SELECT @Additive_i; 

END; GO 

這工作正常。但是,我遇到的問題是這是一個多線程應用程序,當多個線程調用此存儲過程時,它們開始共享相同的臨時表,這會混淆我試圖編譯的統計信息。

有沒有辦法爲存儲過程的每個調用應用唯一表名或將temp表的範圍限制爲存儲過程的那個實例?

回答

0

要回答的具體問題:最簡單的解決辦法是使用每個線程不同的數據庫連接,因爲臨時表是session (connection) specific

創建表時,您可以使用TEMPORARY關鍵詞。 TEMPORARY表僅對當前會話可見,並在會話關閉時自動刪除。這意味着兩個不同的會話可以使用相同的臨時表名稱而不會相互衝突,或與現有的非TEMPORARY同名表相衝突。

然而,檢查出實際的代碼後,我會建議不要使用臨時表中的所有,使用單一的查詢與子查詢:

SELECT COUNT(Index_i) 
FROM 
    (SELECT Index_i, ReviewType_vc 
    FROM Leases 
    WHERE Portfolio_i = InIdx_i 
    ORDER BY Index_i 
    LIMIT myLimit OFFSET myOffset) t 
WHERE ReviewType_vc = 'Additive' 
+0

我也有類似的想法,但(對於簡潔)我只顯示了一個統計計算 - 其中約有14個。因此,將相關行復制到臨時表中,然後計算14個更合理的統計數據。我會看看使用不同的連接。 – John

+0

我剛試過你的解決方案,看看它是如何工作的,但我遇到了同樣的問題。對於內部SELECT,我添加了AS T,然後執行了附加分析。但是,我收到錯誤的行數被返回。當我用內部SELECT使用'AS T'時,是否所有線程都可以看到'T'? – John

+0

最終評論 - 如果我將'POOLING = False'添加到連接字符串,這是否意味着我從每個線程獲得不同的連接? – John