これは質問 653714 と非常に似ていますが、SQLServerではなくMySQLの場合です。
基本的に、いくつかのストアドプロシージャの基礎となる複雑な選択があります。ストアドプロシージャ間でコードを共有したいのですが、その方法がわかりません。これを行う1つの方法は、共有でストアドプロシージャを選択し、他のストアドプロシージャからそのストアドプロシージャを呼び出すことです。ネストされたストアドプロシージャの結果セットを操作する方法がわかりません。それらを一時テーブルに入れることができれば、結果を効果的に使用できますが、それらを一時テーブルに入れる方法がわかりません。たとえば、これは機能しません。
CREATE TEMPORARY TABLE tmp EXEC nested_sp();
問題は、ストアドプロシージャが実際に出力を直接返さないことです。スクリプト内でselectステートメントを実行できますが、戻り値はありません。
MySQLはCALL StoredProcedureName();
を介してストアドプロシージャを呼び出します。何も返さないため(関数とは異なり)、その出力を何かに向けることはできません。 )。
私の最初の反応は「それは私にとっての見解のように聞こえる」でした。ケースごとにSP)に変動性を追加できるように、それは十分に抽象化されていませんか?
他の方法では存在しない一時テーブルを追加するものはすべて、アンチパターンである可能性が非常に高くなります。
ストアドプロシージャで「SELECTINTO」することはできません。
最初に一時テーブルを作成し、通常の「INSERTINTO」を使用してクエリ結果を作成された一時テーブルに格納するストアドプロシージャを用意します。一時テーブルは、ドロップするか、接続が閉じられるまで表示されます。
私はこれが本当に遅くなることを知っていますが、本当の解決策を見つけるのに何年もかかったので、共有したほうがいいでしょう。以下の例に取り組みました。
作成されるテーブルは次のとおりです。
_CREATE TABLE BOOK(
B_ID INT NOT NULL AUTO_INCREMENT,
PRIMARY KEY(B_ID),
TITLE VARCHAR(100),
DESCRIPTION VARCHAR(30),
PRICE DOUBLE);
CREATE TABLE BOOK_COMMENT(
PRIMARY KEY(B_C_ID),
B_C_ID INT NOT NULL AUTO_INCREMENT,
REMARK VARCHAR(120),
B_ID INT,
FOREIGN KEY(B_ID) REFERENCES BOOK(B_ID));
CREATE TABLE AUTHOR(
A_ID INT NOT NULL AUTO_INCREMENT,
PRIMARY KEY(A_ID),
A_NAME CHAR(15),
B_ID INT,
FOREIGN KEY(B_ID) REFERENCES BOOK(B_ID));
_
_
CREATE PROCEDURE BOOK_IMPORTANT( _PRICE DOUBLE, _B_ID INT, A_NAME CHAR(15), _BD_ID INT)
BEGIN
INSERT INTO BOOK(PRICE)
VALUES(_PRICE);
SET _B_ID=LAST_INSERT_ID();
INSERT INTO BOOK_COMMENT(B_ID)
VALUES(_B_ID);
SET _BD_ID=LAST_INSERT_ID();
INSERT INTO AUTHOR(A_NAME,B_ID)
VALUES(A_NAME,_BD_ID);
END
_
次に、以下を使用して値を挿入します。
_CALL BOOK_IMPORTANT('0.79',LAST_INSERT_ID(),'',LAST_INSERT_ID());
_
LAST_INSERT_ID()
は、テーブルの最後の自動インクリメントを取得し、それを子テーブルの参照列に挿入します。
プロシージャパラメータ__B_ID
_と__BD_ID
_は、両方のテーブルで外部キーとして_B_ID
_が必要なため、_B_ID
_を表します。
言い過ぎでごめんなさい。他のすべての人は、あなたがそれを行う方法を自動的に知っていることを期待しています。それが役に立てば幸い
クローズドトピックかもしれませんが、MySQL一時テーブルのプロパティに基づいたソリューションを提供したいと思います。まず、一時テーブルを作成する方法は、ストアドプロシージャ「CREATETEMPORARY TABLE tmp EXECnested_sp();」を呼び出すことではありません。クエリは、「インフラストラクチャ」の一時テーブルに対するものです(なんらかの名前を付けるため)。
目的の結果を得るには、2つのストアドプロシージャを作成する必要があります。最初のストアドプロシージャはデータを処理して一時的な「インフラストラクチャ」テーブルに入力し、2番目のストアドプロシージャはこのテーブルを読み取ってプロセスを続行し、最後に「DROP」します。 「インフラストラクチャ」テーブル
これは最初のストアドプロシージャです。
CREATE DEFINER = 'root'@'localhost'
PROCEDURE cajareal.priv_test()
BEGIN
CREATE TEMPORARY TABLE IF NOT EXISTS tmp(
column1 TEXT
, column2 TEXT
, column3 TEXT
);
INSERT INTO tmp(column1, column2 , column3) VALUES(CURDATE(), CURRENT_DATE(), CURRENT_TIMESTAMP());
END
これは2番目のストアドプロシージャです。
CREATE DEFINER = 'root'@'localhost'
PROCEDURE cajareal.priv_caller()
BEGIN
CALL priv_test;
-- Read data of "infrastructure" table
SELECT * FROM tmp;
-- Do the business logic
-- Delete the "infrastructure" table
DROP TABLE tmp;
END
この手法を使用して文字列を分析し、テーブルに変換します