web-dev-qa-db-ja.com

ストアドプロシージャ/関数はテーブルを返すことができますか?

MySqlストアドプロシージャ/関数は、一時テーブルを使用せずにテーブルを返すことができますか?

次の手順を作成する

CREATE PROCEDURE database.getExamples() 
    SELECT * FROM examples;

後でそれを呼び出す

CALL database.getExamples()

予想どおりにテーブル例を表示しますが、次のようなことはできないようです:

SELECT * FROM CALL database.getExamples()

ストアドプロシージャ/関数からクエリ結果テーブルを返すことはまったく可能ですか?

25
Cambiata

今のところ、これは不可能です。

FROM句で使用できるものに関する documentation は次のとおりです。

table_references:
    table_reference [, table_reference] ...

table_reference:
    table_factor
  | join_table

table_factor:
    tbl_name [[AS] alias] [index_hint)]
  | table_subquery [AS] alias
  | ( table_references )
  | { OJ table_reference LEFT OUTER JOIN table_reference
        ON conditional_expr }

join_table:
    table_reference [INNER | CROSS] JOIN table_factor [join_condition]
  | table_reference STRAIGHT_JOIN table_factor
  | table_reference STRAIGHT_JOIN table_factor ON conditional_expr
  | table_reference {LEFT|RIGHT} [OUTER] JOIN table_reference join_condition
  | table_reference NATURAL [{LEFT|RIGHT} [OUTER]] JOIN table_factor

join_condition:
    ON conditional_expr
  | USING (column_list)

index_hint:
    USE {INDEX|KEY} [FOR JOIN] (index_list)
  | IGNORE {INDEX|KEY} [FOR JOIN] (index_list)
  | FORCE {INDEX|KEY} [FOR JOIN] (index_list)

index_list:
    index_name [, index_name] ...

ご覧のとおり、ストアドプロシージャはこのリストにありません。

18
Quassnoi

A.4 MySQL 5.6 FAQ:ストアドプロシージャと関数

A.4.14:MySQL 5.6ストアドルーチンは結果セットを返すことができますか?

ストアドプロシージャはできますが、ストアドファンクションはできません。

10
Jakub Czaplicki

できるように見えますが、ストアドプロシージャの出力変数を使用しています。 http://www.sqlinfo.net/mysql/mysql_stored_procedure_SELECT.php

-- 1. Create Procedure
DROP PROCEDURE IF EXISTS `sp_students_SELECT_byPK` 
GO

CREATE PROCEDURE sp_students_SELECT_byPK
(
    IN   p_student_id                    INT(11)       , 
    OUT  p_password                      VARCHAR(15)   , 
    OUT  p_active_flg                    TINYINT(4)    , 
    OUT  p_lastname                      VARCHAR(30)   , 
    OUT  p_firstname                     VARCHAR(20)   , 
    OUT  p_gender_code                   VARCHAR(1)    , 
    OUT  p_birth_dttm                    DATETIME      
 )
BEGIN 

SELECT password                      , 
       active_flg                    , 
       lastname                      , 
       firstname                     , 
       gender_code                   , 
       birth_dttm                    
INTO   p_password                      , 
       p_active_flg                    , 
       p_lastname                      , 
       p_firstname                     , 
       p_gender_code                   , 
       p_birth_dttm                    
FROM   students
WHERE  student_id = p_student_id ; 

END 

GO

-- 2. Select Results from Stored Procedure
/***
IN    p_student_id   INT(11)
OUT   p_password     VARCHAR(15)
OUT   p_active_flg   TINYINT(4)
OUT   p_lastname     VARCHAR(30)
OUT   p_firstname    VARCHAR(20)
OUT   p_gender_code  VARCHAR(1)
OUT   p_birth_dttm   DATETIME
***/

CALL sp_students_SELECT_byPK
(
  8, 
  @p_password , 
  @p_active_flg , 
  @p_lastname , 
  @p_firstname , 
  @p_gender_code , 
  @p_birth_dttm
)
GO

SELECT @p_password      AS p_password      , 
   @p_active_flg    AS p_active_flg    , 
   @p_lastname      AS p_lastname      , 
   @p_firstname     AS p_firstname     , 
   @p_gender_code   AS p_gender_code   , 
   @p_birth_dttm    AS p_birth_dttm   
GO
3
atjoedonahue

テーブルまたは変数に挿入しない各SELECTステートメントは、結果セットを生成します。

ストアドプロシージャが1つの結果セットのみを返すようにする場合は、SELECTステートメントが1つだけであることを確認してください。他のSELECTステートメントがある場合は、それらが結果をテーブルまたは変数に挿入することを確認してください。

更新ストアドプロシージャの例を次に示します。

このストアドプロシージャは、1つの結果セットを返します。

DELIMITER ;;
CREATE DEFINER=CURRENT_USER PROCEDURE stored_procedure_name()
BEGIN
    DECLARE local_variable_name INT;

    SELECT column_name FROM table_1 LIMIT 1 INTO local_variable_name;

    SELECT * FROM table_1;
END;;
DELIMITER ;
This stored procedure would return two result sets:

DELIMITER ;;
CREATE DEFINER=CURRENT_USER PROCEDURE stored_procedure_name()
BEGIN
    DECLARE local_variable_name INT;

    SELECT column_name FROM table_1 LIMIT 1 INTO local_variable_name;

    SELECT * FROM table_1;

    SELECT * FROM table_2;
END;;
DELIMITER ;

参照: https://dba.stackexchange.com/questions/8291/how-does-mysql-return-a-result-set-from-a-stored-procedure

1
Harshal

ストアドプロシージャの代わりにビューを使用して、しようとしていることを実行できる場合がありますが、それはストアドプロシージャの動作に完全に依存します。

一時テーブルを使用することが唯一のオプションである場合は、MEMORYストレージエンジンの使用を検討してください。

1
Ian Gregory