it-swarm.com.ru

MySQL Как вставить INTO [временная таблица] FROM [хранимая процедура]

Это очень похоже на вопрос 653714 , но для MySQL вместо SQL Server.

По сути, у меня есть сложный выбор, который является основой для нескольких хранимых процедур. Я хотел бы поделиться кодом между хранимыми процедурами, однако я не уверен, как это сделать. Один из способов, которым я мог бы сделать это, - сделать общий доступ к хранимой процедуре, а затем вызвать эту хранимую процедуру из других. Я не могу понять, как работать с набором результатов вложенной хранимой процедуры. Если бы я мог поместить их во временную таблицу, я мог бы эффективно использовать результаты, но я не могу понять, как получить их во временной таблице. Например, это не работает:

CREATE TEMPORARY TABLE tmp EXEC nested_sp();
16
Brian Fisher

Проблема в том, что хранимые процедуры на самом деле не возвращают вывод напрямую. Они могут выполнять операторы select внутри скрипта, но не имеют возвращаемого значения.

MySQL вызывает хранимые процедуры через CALL StoredProcedureName();, и вы не можете направить этот вывод ни на что, поскольку они ничего не возвращают (в отличие от функции).

MySQL Call Command

13
St. John Johnson

Моей первой реакцией было «Это звучит как вид для меня». Разве это недостаточно абстрагируется, чтобы вы могли просто добавить изменчивость в SP для каждого случая?

Все, что добавляет временную таблицу, которой иначе не было бы, является весьма вероятным антипаттерном.

5
dkretz

Вы не можете "ВЫБРАТЬ В" с помощью хранимых процедур.

Сначала создайте временную таблицу, и у вас есть хранимая процедура для сохранения результата запроса во созданную временную таблицу с использованием обычного «INSERT INTO». Временная таблица видна до тех пор, пока вы ее не сбросите или пока соединение не будет закрыто.

4
slaakso

я знаю, что это будет очень поздно, но так как мне потребовались целые годы, чтобы найти реальное решение, я мог бы также поделиться им. Я работал над примером, который ниже.

созданные таблицы:

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));
  1. DELIMITER 

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

затем используйте следующее, чтобы вставить значения.

CALL BOOK_IMPORTANT('0.79',LAST_INSERT_ID(),'',LAST_INSERT_ID());

LAST_INSERT_ID() берет последнее автоинкремент таблицы и вставляет его в столбец ссылок дочерней таблицы.

В процедуре параметры _B_ID и _BD_ID представляют B_ID, так как мне нужно B_ID в качестве внешнего ключа в обеих таблицах.

Извините за лишнюю формулировку. Все остальные парни ожидают, что вы автоматически узнаете, как это сделать. Надеюсь, поможет

4
coder 222

Может быть, это закрытая тема, но я хотел бы предложить решение, основанное на свойствах временных таблиц MySQL. Во-первых, способ создания временной таблицы не состоял бы в том, чтобы вызвать SP «CREATE TEMPORARY TABLE tmp EXEC nested_sp ();». Запрос к временной таблице "инфраструктуры", (чтобы назвать это как-то).

Чтобы достичь желаемого результата, необходимо создать 2 SP, первый SP обрабатывает данные и заполняет временную таблицу «инфраструктуры», второй SP читает эту таблицу и продолжает процесс, и, наконец, «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

Второй ИП

CREATE DEFINER = 'root'@'localhost'
PROCEDURE cajareal.priv_caller()
BEGIN
  CALL priv_test;

  -- Read data of "infrastructure" table
  SELECT * FROM tmp;


  -- Do the bussiness logic


  -- Delete the "infrastructure" table
  DROP TABLE tmp;
END

Я использую эту технику для анализа строки и преобразования ее в таблицу

0
Janhell