2016-11-25 26 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 

これはうまくいきます。しかし、私が持っている問題は、これはマルチスレッドアプリケーションであり、複数のスレッドがこのストアドプロシージャを呼び出すときに、同じ一時テーブルを共有し始めます。これは、コンパイルしようとしているStatsを壊してしまいます。

ストアドプロシージャの呼び出しごとにユニークなテーブル名を適用するか、またはテンポラリテーブルのスコープをストアドプロシージャのそのインスタンスだけに制限する方法がありますか?

答えて

0

特定の質問に答えるために:最も簡単な解決策は、一時テーブルがsession (connection) specificであるため、スレッドごとに異なるデータベース接続を使用することです:

テーブルを作成するときは、TEMPORARYキーワードを使用できます。 TEMPORARYテーブルは現在のセッションにのみ表示され、セッションが終了すると自動的に削除されます。これは、2つの異なるセッションが、互いに矛盾することなく、または同じ名前の既存の非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

私は同様の考えを持っていましたが、(用簡潔さ)私は統計量の計算の1つしか示していません - それらの約14があります。したがって、関連する行をテンポラリテーブルにコピーしてから14個の統計を計算する方が意味があります。私は別の接続を使用して見てみましょう。 – John

+0

私はあなたのソリューションをどのように動作するか見てみましたが、私は同じ問題を抱えていました。内側のSELECTについては、AS Tを追加して、さらに分析を行いました。しかし、返される行数が間違っていました。内側のSELECTで 'AS T'を使用すると、 'T'がすべてのスレッドに表示されますか? – John

+0

最終的なコメント - 接続文字列に 'POOLING = False'を追加すると、各スレッドから別の接続が得られますか? – John

関連する問題