Создать табличную переменную в MySQL

Мне нужна табличная переменная для хранения определенных строк из таблицы в процедуре MySQL. Например. объявить таблицу @tb (id int, name varchar (200))

Это возможно? Если да, то как?


person ANIL MANE    schedule 06.10.2009    source источник
comment
На самом деле, Алексей прав, можно хранить таблицу в переменной, но для этого нужно использовать функцию, а не процедуру. Документы MySQL очень ясно говорят об этом.   -  person    schedule 03.07.2012
comment
Не решение вопроса, а еще одна простая альтернатива. если таблица представляет собой таблицу с одним столбцом, которую вы хотите, тогда получите строковый параметр, объединив значения и извлекая их внутри SP.   -  person sjd    schedule 27.08.2013


Ответы (5)


Их не существует в MySQL, не так ли? Просто используйте временную таблицу:

CREATE PROCEDURE my_proc () BEGIN 

CREATE TEMPORARY TABLE TempTable (myid int, myfield varchar(100)); 
INSERT INTO TempTable SELECT tblid, tblfield FROM Table1; 

/* Do some more stuff .... */

Из MySQL здесь

«Вы можете использовать ключевое слово TEMPORARY при создании таблицы. ВРЕМЕННАЯ таблица видна только для текущего соединения и автоматически удаляется при закрытии соединения. Это означает, что два разных соединения могут использовать одно и то же имя временной таблицы, не конфликтуя друг с другом. другой или с существующей не-TEMPORARY таблицей с таким же именем. (Существующая таблица скрыта до тех пор, пока временная таблица не будет удалена.)"

person Preet Sangha    schedule 06.10.2009
comment
Что, если несколько пользователей попытаются запустить одну и ту же процедуру, создаст ли это проблему параллелизма? - person ANIL MANE; 06.10.2009
comment
временные таблицы зависят от сеанса, а не от пользователя - person humility; 15.05.2019
comment
В зависимости от того, как ваше приложение использует сеанс, оно может быть многопоточным с использованием одного и того же сеанса БД. В этом сценарии вы не столкнетесь с проблемами параллелизма? то есть поток A начал добавлять записи, а затем поток B, и теперь таблица повреждена, потому что поток A нуждался только в вставленных записях, а не в @humility потока B. - person Flippi; 24.11.2020

Возможно, временная таблица сделает то, что вы хотите.

CREATE TEMPORARY TABLE SalesSummary (
product_name VARCHAR(50) NOT NULL
, total_sales DECIMAL(12,2) NOT NULL DEFAULT 0.00
, avg_unit_price DECIMAL(7,2) NOT NULL DEFAULT 0.00
, total_units_sold INT UNSIGNED NOT NULL DEFAULT 0
) ENGINE=MEMORY;

INSERT INTO SalesSummary
(product_name, total_sales, avg_unit_price, total_units_sold)
SELECT 
  p.name
  , SUM(oi.sales_amount)
  , AVG(oi.unit_price)
  , SUM(oi.quantity_sold)
FROM OrderItems oi
INNER JOIN Products p
    ON oi.product_id = p.product_id
GROUP BY p.name;

/* Just output the table */
SELECT * FROM SalesSummary;

/* OK, get the highest selling product from the table */
SELECT product_name AS "Top Seller"
FROM SalesSummary
ORDER BY total_sales DESC
LIMIT 1;

/* Explicitly destroy the table */
DROP TABLE SalesSummary; 

Из forge.mysql.com. См. также часть временных таблиц этой статьи. .

person Ewan Todd    schedule 06.10.2009

Чтобы ответить на ваш вопрос: нет, MySQL не поддерживает переменные табличного типа так же, как SQL Server (http://msdn.microsoft.com/en-us/library/ms188927.aspx). Oracle предоставляет аналогичные функции, но называет их типами курсора, а не типами таблиц (http://docs.oracle.com/cd/B12037_01/appdev.101/b10807/13_elems012.htm).

В зависимости от ваших потребностей вы можете имитировать переменные типа таблицы/курсора в MySQL, используя временные таблицы способом, аналогичным тому, что предоставляется как Oracle, так и SQL Server.

Однако существует важное различие между подходом с временной таблицей и подходом с использованием таблицы/курсорной переменной, и это сильно влияет на производительность (это причина, по которой Oracle и SQL Server предоставляют эту функциональность в дополнение к тому, что предоставляется с временными таблицами). таблицы).

В частности: табличные/курсорные переменные позволяют клиенту сопоставлять несколько строк данных на стороне клиента и отправлять их на сервер в качестве входных данных для хранимой процедуры или подготовленного оператора. Это устраняет накладные расходы на отправку каждой отдельной строки и вместо этого оплачивает эти накладные расходы один раз за пакет строк. Это может существенно повлиять на общую производительность, когда вы пытаетесь импортировать большие объемы данных.

Возможный обходной путь:

Что вы можете попробовать, так это создать временную таблицу, а затем использовать команду LOAD DATA (http://dev.mysql.com/doc/refman/5.1/en/load-data.html) для потоковой передачи данных во временную таблицу. стол. Затем вы можете передать им имя временной таблицы в свою хранимую процедуру. Это по-прежнему приведет к двум обращениям к серверу базы данных, но если вы перемещаете достаточно строк, это может дать экономию. Конечно, на самом деле это полезно только в том случае, если вы выполняете какую-то логику внутри хранимой процедуры при обновлении целевой таблицы. Если нет, вы можете просто ЗАГРУЗИТЬ ДАННЫЕ непосредственно в целевую таблицу.

person numbsafari    schedule 17.05.2012

MYSQL 8 делает так:

MYSQL 8 поддерживает таблицы JSON, поэтому вы можете загружать свои результаты в переменную JSON и выбирать из этой переменной с помощью команды JSON_TABLE().

person Justin Levene    schedule 11.10.2018

Если вы не хотите хранить таблицу в базе данных, то @Evan Todd уже предоставил решение для временной таблицы.

Но если вам нужна эта таблица для других пользователей и вы хотите сохранить ее в БД, вы можете использовать следующую процедуру.

Создайте ниже «хранимую процедуру»:

————————————

DELIMITER $$

USE `test`$$

DROP PROCEDURE IF EXISTS `sp_variable_table`$$

CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_variable_table`()
BEGIN

SELECT CONCAT(‘zafar_’,REPLACE(TIME(NOW()),’:',’_')) INTO @tbl;

SET @str=CONCAT(“create table “,@tbl,” (pbirfnum BIGINT(20) NOT NULL DEFAULT ’0′, paymentModes TEXT ,paymentmodeDetails TEXT ,shippingCharges TEXT ,shippingDetails TEXT ,hypenedSkuCodes TEXT ,skuCodes TEXT ,itemDetails TEXT ,colorDesc TEXT ,size TEXT ,atmDesc TEXT ,promotional TEXT ,productSeqNumber VARCHAR(16) DEFAULT NULL,entity TEXT ,entityDetails TEXT ,kmtnmt TEXT ,rating BIGINT(1) DEFAULT NULL,discount DECIMAL(15,0) DEFAULT NULL,itemStockDetails VARCHAR(38) NOT NULL DEFAULT ”) ENGINE=INNODB DEFAULT CHARSET=utf8″);
PREPARE stmt FROM @str;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

SELECT ‘Table has been created’;
END$$

DELIMITER ;

———————————————–

Теперь вы можете выполнить эту процедуру, чтобы создать таблицу имен переменных, как показано ниже:

вызвать sp_variable_table();

Вы можете проверить новую таблицу после выполнения следующей команды:

использовать тест; показывать таблицы типа «%zafar%»; — test здесь имя «базы данных».

Вы также можете проверить более подробную информацию по пути ниже:

http://mydbsolutions.in/how-can-create-a-table-with-variable-name/

person Zafar Malik    schedule 19.02.2014