【问题标题】:mysql temporary table in subquery子查询中的mysql临时表
【发布时间】:2018-08-03 22:28:36
【问题描述】:

我正在尝试在子查询(存储过程)中使用临时表,但它返回空结果集...

CREATE DEFINER=`root`@`localhost` PROCEDURE `get_profile_with_templates`(IN _username NVARCHAR(50), IN _template NVARCHAR(50))
BEGIN
    SELECT id INTO @template FROM profile_template WHERE name=_template LIMIT 1;
    SELECT * FROM profile WHERE username=_username AND template=@template LIMIT 1;
    CREATE TEMPORARY TABLE IF NOT EXISTS sections SELECT * FROM profile_template_section WHERE template=@template;
    **CREATE TEMPORARY TABLE IF NOT EXISTS components SELECT * FROM component_template WHERE section IN (SELECT id FROM sections);**
    SELECT * FROM sections;
    SELECT * FROM components;
    SELECT * FROM component_template_option WHERE component_template IN (SELECT id FROM components);
END

**之间的查询是返回空的... 如果我在真实表上运行相同的查询,它会返回值...

CREATE DEFINER=`root`@`localhost` PROCEDURE `get_profile_with_templates`(IN _username NVARCHAR(50), IN _template NVARCHAR(50))
BEGIN
    DROP TEMPORARY TABLE IF EXISTS sections;
    DROP TEMPORARY TABLE IF EXISTS components;
    SELECT id INTO @template FROM profile_template WHERE name=_template LIMIT 1;
    SELECT * FROM profile WHERE username=_username AND template=@template LIMIT 1;
    CREATE TEMPORARY TABLE IF NOT EXISTS sections SELECT * FROM profile_template_section WHERE template=@template;
    CREATE TEMPORARY TABLE IF NOT EXISTS components SELECT * FROM component_template WHERE section IN (SELECT id FROM sections);
    SELECT * FROM sections;
    SELECT * FROM components;
    SELECT * FROM component_template_option WHERE component_template IN (SELECT id FROM components);
    DROP TEMPORARY TABLE IF EXISTS sections;
    DROP TEMPORARY TABLE IF EXISTS components;
END

【问题讨论】:

  • 您是否确保在同一连接上的执行之间删除临时表? CREATE...IF NOT IS EXISTS..SELECT 不会插入到已经存在的表中。
  • 所以我应该在程序结束时添加drop table吗?
  • 为过程创建的每个临时表在过程的开头和结尾添加DROP TEMPORARY TABLE IF EXISTS tablename; 查询通常可以使事情顺利进行。 (技术上只需要一次,但如果在通话中出现问题,如果你只有在结尾处有掉线,他们可能会卡住;如果他们只是在开始,他们会在通话结束后徘徊.)
  • 好的,现在可以了,但是当我用node js接收数据并更改参数时,数据保持不变(听起来好像没有删除表)...
  • 你有多个选择(没有 into's),这将导致过程返回多个结果集(看起来像四个);你处理得当吗?另外,不要过分依赖@变量;它们不是私有的,可以继承以前执行的值。

标签: mysql stored-procedures subquery temp-tables


【解决方案1】:

当使用CREATE ... SELECT 语句时,如果表已经存在,SELECT 部分将不会填充该表。

如果在存储过程中创建不会在过程之外使用的临时表,最好在过程的开始和结束处使用DROP TEMPORARY TABLE IF EXISTS 语句。结束的是程序自行清理;起始表确保先前执行留下的临时表(在删除它们之前出错/失败)不会干扰当前执行。 您也可以将过程的主体包裹在 TRY 中,并在 TRY 之外放置 drop,以确保 drop 发生,但这有点高级。

当使用 session/user/@ 变量时,请记住它们对于数据库连接是全局的并且可以传递值;尽可能使用本地 DECLAREd 变量(其范围不超出过程)。 奖励:此外,请尽量确保此类变量的名称和过程参数与过程中使用的表的字段名称没有歧义;这可能会导致非常难以诊断问题。

【讨论】:

    猜你喜欢
    • 2012-12-15
    • 2014-04-30
    • 2013-02-27
    • 1970-01-01
    • 2015-01-20
    • 1970-01-01
    • 2013-02-07
    • 2013-08-09
    • 1970-01-01
    相关资源
    最近更新 更多