在 MySQL 中创建表变量
Posted
技术标签:
【中文标题】在 MySQL 中创建表变量【英文标题】:Create table variable in MySQL 【发布时间】:2010-12-04 05:39:44 【问题描述】:我需要一个表变量来存储mysql 过程中表中的特定行。 例如。声明@tb 表 (id int,name varchar(200))
这可能吗?如果是怎么办?
【问题讨论】:
实际上,Aleksey 是对的,您可以将表存储在变量中,但您需要使用函数,而不是过程。 MySQL 文档对此非常清楚。 不是问题的解决方案,而是另一种简单的选择。如果该表是您想要的单列表,则通过连接值导出字符串参数并在 SP 内提取。 【参考方案1】:它们在 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 here
"您可以使用 TEMPORARY 关键字 创建表时。一个临时的 表只对当前可见 连接,并被丢弃 连接成功时自动 关闭。这意味着两个不同的 连接可以使用相同的临时 表名不冲突 彼此或与现有的 同名的非 TEMPORARY 表。 (现有表被隐藏,直到 临时表被删除。)”
【讨论】:
如果多个用户尝试运行相同的程序会产生并发问题吗? 临时表是特定于会话而不是特定于用户的 根据您的应用程序使用会话的方式,它可以使用相同的数据库会话进行多线程处理。在那种情况下,您不会遇到并发问题吗?即线程 A 开始添加记录,然后线程 B 也开始添加记录,现在表已损坏,因为线程 A 只需要它插入的记录,而不是线程 B 的 @humility【参考方案2】:也许临时表会做你想做的事。
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。另见this article 的临时表部分。
【讨论】:
【参考方案3】:回答您的问题:不,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) 命令来流式传输数据进入临时表。然后,您可以将临时表的名称传递给您的存储过程。这仍然会导致对数据库服务器的两次调用,但如果您移动了足够多的行,则可能会节省一些费用。当然,这只有在更新目标表时在存储过程中执行某种逻辑时才真正有用。如果没有,您可能只想将数据直接加载到目标表中。
【讨论】:
【参考方案4】:MYSQL 8 在某种程度上做到了:
MYSQL 8 支持 JSON 表,因此您可以将结果加载到 JSON 变量中并使用 JSON_TABLE() 命令从该变量中进行选择。
【讨论】:
【参考方案5】:如果您不想将表存储在数据库中,那么 @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/
【讨论】:
以上是关于在 MySQL 中创建表变量的主要内容,如果未能解决你的问题,请参考以下文章