web-dev-qa-db-ja.com

MySQL [temp table] FROM [ストアドプロシージャ]に挿入する方法

これは質問 653714 と非常に似ていますが、SQLServerではなくMySQLの場合です。

基本的に、いくつかのストアドプロシージャの基礎となる複雑な選択があります。ストアドプロシージャ間でコードを共有したいのですが、その方法がわかりません。これを行う1つの方法は、共有でストアドプロシージャを選択し、他のストアドプロシージャからそのストアドプロシージャを呼び出すことです。ネストされたストアドプロシージャの結果セットを操作する方法がわかりません。それらを一時テーブルに入れることができれば、結果を効果的に使用できますが、それらを一時テーブルに入れる方法がわかりません。たとえば、これは機能しません。

CREATE TEMPORARY TABLE tmp EXEC nested_sp();
17
Brian Fisher

問題は、ストアドプロシージャが実際に出力を直接返さないことです。スクリプト内でselectステートメントを実行できますが、戻り値はありません。

MySQLはCALL StoredProcedureName();を介してストアドプロシージャを呼び出します。何も返さないため(関数とは異なり)、その出力を何かに向けることはできません。 )。

MySQL呼び出しコマンド

12

私の最初の反応は「それは私にとっての見解のように聞こえる」でした。ケースごとにSP)に変動性を追加できるように、それは十分に抽象化されていませんか?

他の方法では存在しない一時テーブルを追加するものはすべて、アンチパターンである可能性が非常に高くなります。

5
dkretz

ストアドプロシージャで「SELECTINTO」することはできません。

最初に一時テーブルを作成し、通常の「INSERTINTO」を使用してクエリ結果を作成された一時テーブルに格納するストアドプロシージャを用意します。一時テーブルは、ドロップするか、接続が閉じられるまで表示されます。

4
slaakso

私はこれが本当に遅くなることを知っていますが、本当の解決策を見つけるのに何年もかかったので、共有したほうがいいでしょう。以下の例に取り組みました。

作成されるテーブルは次のとおりです。

_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));
_
  1. デリミタ
_
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_を表します。

言い過ぎでごめんなさい。他のすべての人は、あなたがそれを行う方法を自動的に知っていることを期待しています。それが役に立てば幸い

4
coder 222

クローズドトピックかもしれませんが、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

この手法を使用して文字列を分析し、テーブルに変換します

1
Janhell