MySQL如何插入[临时表] FROM [存储过程]

Bri*_*her 17 mysql sql stored-procedures

这与问题653714非常相似,但对于MySQL而不是SQL Server.

基本上,我有一个复杂的选择,这是几个存储过程的基础.我想在存储过程中共享代码,但是,我不知道如何做到这一点.我可以这样做的一种方法是使共享选择一个存储过程,然后从其他存储过程调用该存储过程.我无法弄清楚如何使用嵌套存储过程的结果集.如果我可以将它们放在临时表中,我可以有效地使用结果,但我无法弄清楚如何在临时表中获取它们.例如,这不起作用:

CREATE TEMPORARY TABLE tmp EXEC nested_sp();
Run Code Online (Sandbox Code Playgroud)

St.*_*son 11

问题是,存储过程并不直接返回输出.它们可以在脚本中执行select语句,但没有返回值.

MySQL通过CALL StoredProcedureName(); And 调用存储过程而不能将输出定向到任何东西,因为它们不返回任何内容(与函数不同).

MySQL调用命令

  • 那么,这是一个答案吗?解决方案在哪里? (23认同)
  • 所以这是不可能的? (3认同)

dkr*_*etz 5

我的第一反应是"这听起来像是对我的看法".这不是足够抽象,所以你可以在每个案例中将可变性添加到SP中吗?

任何添加临时表的东西都不会出现反模式.


小智 5

我知道这来得太晚了,但由于我花了很长时间才找到真正的解决方案,我不妨分享一下。我研究了下面的一个例子。

创建的表是:

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));
Run Code Online (Sandbox Code Playgroud)
  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
Run Code Online (Sandbox Code Playgroud)

然后使用以下内容插入值。

CALL BOOK_IMPORTANT('0.79',LAST_INSERT_ID(),'',LAST_INSERT_ID());
Run Code Online (Sandbox Code Playgroud)

LAST_INSERT_ID() 获取表的最后一个自动增量并将其插入到子表的引用列中。

在过程参数_B_ID_BD_ID 表示B_ID因为我需要B_ID作为两个表中的外键。

抱歉措辞过多。所有其他人都希望你自动知道如何去做。希望能帮助到你


sla*_*kso 5

您不能使用存储过程“SELECT INTO”。

首先创建临时表,并让您的存储过程使用正常的“INSERT INTO”将查询结果存储到创建的临时表中。只要您删除临时表或直到连接关闭,临时表都是可见的。


小智 5

也许这是一个封闭的话题,但我想根据 MySQL 临时表的属性提供一个解决方案。首先,创建临时表的方式不会是调用存储过程“CREATE TEMPORARY TABLE tmp EXEC nested_sp();”。查询是“基础设施”的临时表,(以某种方式命名)。

为了达到预期的结果,需要创建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
Run Code Online (Sandbox Code Playgroud)

这是第二个存储过程:

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
Run Code Online (Sandbox Code Playgroud)

我使用这种技术来分析字符串并将其转换为表格

  • 这应该是公认的答案 - 这是唯一能用可用的解决方案真正回答问题的方法。 (2认同)