在 MySQL 存储过程中创建临时表

Posted

技术标签:

【中文标题】在 MySQL 存储过程中创建临时表【英文标题】:Creating temporary tables in MySQL Stored Procedure 【发布时间】:2011-07-15 14:29:10 【问题描述】:

当我使用 CALL 语句调用它时,以下过程给了我一个错误:


CREATE DEFINER=`user`@`localhost` PROCEDURE `emp_performance`(id VARCHAR(10))
BEGIN
DROP TEMPORARY TABLE IF EXISTS performance;
CREATE TEMPORARY TABLE performance AS  
    SELECT time_in, time_out, day FROM attendance WHERE employee_id = id;
END

错误提示“未知表'性能'”

这是我第一次实际使用存储过程,我的资源来自 Google。我只是无法弄清楚我做错了什么。

【问题讨论】:

【参考方案1】:

默认情况下 mysql 配置变量 sql_notes 设置为 1。

这意味着 DROP TEMPORARY TABLE IF EXISTS performance; 将warning_count 加一,当存储过程完成时您会收到警告。

您可以在 my.cnf 中将sql_notes 变量设置为 0,或者像这样重写存储过程:

CREATE DEFINER=`user`@`localhost` PROCEDURE `emp_performance`(id VARCHAR(10))
BEGIN
SET @@session.sql_notes = 0;
DROP TEMPORARY TABLE IF EXISTS performance;
CREATE TEMPORARY TABLE performance AS  
    SELECT time_in, time_out, day FROM attendance WHERE employee_id = id;
SET @@session.sql_notes = 1;
END

【讨论】:

【参考方案2】:

我已经为您整理了一下,并添加了示例代码。我始终保持参数名称与它们所代表的字段相同,但前缀为 p_ 以防止出现问题。我对在 sproc 主体中声明的变量做同样的事情,但以 v_ 为前缀。

你可以在这里找到我的另一个例子:

Generating Depth based tree from Hierarchical Data in MySQL (no CTEs)

drop procedure if exists emp_performance;

delimiter #

create procedure emp_performance
(
in p_employee_id varchar(10)
)
begin

declare v_counter int unsigned default 0;

create temporary table tmp engine=memory select time_in, time_out 
 from attendance where employee_id = p_employee_id;

-- do stuff with tmp...

select count(*) into v_counter from tmp;

-- output and cleanup

select * from tmp order by time_in;

drop temporary table if exists tmp;

end#

delimiter ;

call emp_performance('E123456789');

【讨论】:

我创建临时表的目的是事后查询。我刚刚尝试了您的代码,您创建的 tmp 表不可用于查询。相反,它给了我一个结果集。所以程序只是准备员工出勤 您可以按照您的建议进行操作,但该表仅对创建它或调用存储过程的连接可用。我不会推荐这种方法,但如果你能详细说明你正在尝试做的事情,我可能还有其他一些想法。您可能还想查看pastie.org/1673574 您将如何测试会员资格。如果 tmp 表只有(作者的)ID,我想查询类似:“select * from books where author in (tmp)”。 MySQL 返回错误:'unknown column tmp' 关于并行性的另一个问题:'tmp' 似乎是一个全局对象(或具有全局范围)。例如,如果我没有“drop temporary ...”行,那么第二次执行将无法创建 tmp。那么......当过程并行执行两次时,服务器如何处理?

以上是关于在 MySQL 存储过程中创建临时表的主要内容,如果未能解决你的问题,请参考以下文章

如何在打开游标之前在存储过程中创建一个临时表?

oracle 怎么在存储过程中创建一个临时表,在里面插入数据,再查找这个临时表的所有数据,最后drop这个表。

在SQL存储过程中创建临时表

oracle 怎么在存储过程中创建一个临时表,在里面插入数据,再查找这个临时表的所有数据,最后drop这个表。

如何在mysql程序中创建临时表并生成不同的名称?

MySQL 存储过程,获取使用游标查询的结果集