存储过程/函数可以返回表吗?
Posted
技术标签:
【中文标题】存储过程/函数可以返回表吗?【英文标题】:Can a stored procedure/function return a table? 【发布时间】:2010-12-10 20:56:17 【问题描述】:mysql 存储过程/函数可以不使用临时表返回表吗?
创建以下过程
CREATE PROCEDURE database.getExamples()
SELECT * FROM examples;
然后用
调用它CALL database.getExamples()
显示示例表 - 正如预期的那样 - 但以下内容似乎是不可能的:
SELECT * FROM CALL database.getExamples()
是否有可能从存储过程/函数中返回查询结果表,如果可以 - 如何?
【问题讨论】:
【参考方案1】:就目前而言,这是不可能的。
这里是documentation 可以在FROM
子句中使用的内容:
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] ...
如您所见,存储过程不在此列表中。
【讨论】:
表引用不是一个可能的解决方案吗?因为当您传递子查询时,它还会提供表引用,所以这可能是真的,但我认为原因不是您发布的架构 @Niton 我不确定我明白你在问什么 我的意思是您发布的文档并没有说我们不可能使用过程/功能。因为您看到您可以使用“表引用”(这是我认为子查询返回的东西)。因此,如果 DBMS 支持返回表引用的过程,即使文档没有直接说明,也可以在选择中使用它们 @Niton 是的,它确实这么说。你知道如何阅读 BNF 中的语法描述吗?【参考方案2】:您可以通过使用视图而不是存储过程来完成您正在尝试的事情,但这完全取决于存储过程的作用。
如果使用临时表是您唯一的选择,请考虑使用 MEMORY 存储引擎。
【讨论】:
【参考方案3】:根据A.4 MySQL 5.6 FAQ: Stored Procedures and Functions:
A.4.14: Can MySQL 5.6 stored routines return result sets?
存储过程可以,但存储函数不能。
【讨论】:
Jakub 是正确的。如果您创建的是存储过程而不是函数,它将返回一个结果集。 @TomT 但如何使用 SELECT 使用这样的结果集? dev.mysql.com/doc/refman/5.7/en/select.html 仍然不允许 FROM 中的程序 @Arioch'我认为这也是更重要的问题。 :( 也许是链接上的澄清和总结:存储过程可以返回结果集以供后端调用者(如 JAVA、C# 等)使用,每个 SELECT 语句导致单独的结果-放。但是,在本地它可能是不可能的(即在 MySQL Workbench 中,您可以在屏幕上看到存储过程的结果作为结果集,但您不能将表返回给存储过程的调用者(除非您使用 OUT 变量对于每个返回值,并将结果重新组合到一个表格行中,这可以说是灵活实用的)【参考方案4】:看起来可以做到,但使用存储过程的输出变量。 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
【讨论】:
这正是我的想法。您已经发布了答案。 +1【参考方案5】:每个不插入表或变量的 SELECT 语句都会产生一个结果集。
如果您希望您的存储过程只返回一个结果集,请确保您只有一个 SELECT 语句。如果您有其他 SELECT 语句,请确保它们将结果插入到表或变量中。
更新 以下是存储过程的示例。
此存储过程将返回一个结果集:
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
【讨论】:
以上是关于存储过程/函数可以返回表吗?的主要内容,如果未能解决你的问题,请参考以下文章