パラメータを指定してWebサービスをコールし、その解答を解析して値を戻す関数をPL/SQLで作成しました。それはかなりうまくいく。PL/SQLファンクションのINSERT文
ただし、応答が遅くなることがあります。パラメータは通常、すべての可能な値の非常に小さなサブセットであるため、テーブルに回答をキャッシュするという考えがありました。 機能は、私はこの機能を試してみました次
CREATE OR REPLACE FUNCTION myfct(p1 IN VARCHAR2, p2 IN VARCHAR2)
RETURN VARCHAR2
IS
cache_hit NUMBER ;
res VARCHAR2(200) ;
BEGIN
SELECT COUNT(*) INTO cache_hit FROM MYCACHE WHERE param1 = p1 AND param2 = p2 ;
IF(cache_hit = 1)
THEN
SELECT MYCACHE.result INTO res FROM MYCACHE WHERE param1 = p1 AND param2 = p2 ;
RETURN res ;
END IF ;
-- complex operations
res := p1 || p2 ;
INSERT INTO MYCACHE(param1, param2, result) VALUES(p1, p2, res) ;
RETURN res ;
END ;
次のようになります。
ORA-14551: cannot perform a DML operation inside a query
手順でDMLの一部をラップしようとしている:私はエラーを得た
SELECT myfct('ABC', 'DEF') FROM DUAL ;
を関数内でこのプロシージャを呼び出すと助けにならない
私は仕事アラウンドPRAGMA AUTONOMOUS_TRANSACTIONとを発見し、COMMIT:
CREATE OR REPLACE FUNCTION myfct(p1 IN VARCHAR2, p2 IN VARCHAR2)
RETURN VARCHAR2
IS
PRAGMA AUTONOMOUS_TRANSACTION;
cache_hit NUMBER ;
res VARCHAR2(200) ;
BEGIN
SELECT COUNT(*) INTO cache_hit FROM MYCACHE WHERE param1 = p1 AND param2 = p2 ;
IF(cache_hit = 1)
THEN
SELECT MYCACHE.result INTO res FROM MYCACHE WHERE param1 = p1 AND param2 = p2 ;
RETURN res ;
END IF ;
-- complex operations
res := p1 || p2 ;
INSERT INTO MYCACHE(param1, param2, result) VALUES(p1, p2, res) ;
COMMIT ;
RETURN res ;
END ;
しかし、それは本当に良いアイデアであるのだろうか。この回避策に言及した人は、理由を正確に言わずに、危険である可能性があると言いました。
私の関数はPRAGMA AUTONOMOUS_TRANSACTIONの良い使い方の例ですか、あるいは私が欲しいことをするためのより安全な方法がありますか?
PL/SQLで関数を使用してselectを使用する場合は、グローバル・コレクションに結果を保存してから、表にすべての値を挿入する方がよい場合があります。 – SkyWalker
私はそれについて考えましたが、すべての可能な組み合わせでは、格納する行数は数百万になります。定期的に〜10000個の組み合わせを使用する予定です。キャッシュテーブルを持つこのハイブリッドソリューションでは、あらゆる組み合わせに対応することができますが、最も関連性の高いものだけを格納できます。 –
結果を最新の状態に保つことは可能ですか?複合選択の基礎となるデータが変更された場合はどうなりますか?おそらく、あなたは 'マテリアライズドビュー 'であなたのパフォーマンスの問題を解決できますか? –