2009-10-06 34 views
32

我需要一个表变量来存储MySQL过程中表中的特定行。 例如declare @tb table(id int,name varchar(200))在MySQL中创建表变量

这可能吗?如果是的话如何?

+0

实际检查的详细信息,阿列克谢是正确的,你可以存储一个表中的变量,但你需要使用的功能,而不是一个程序。 MySQL文档非常清晰。 – 2012-07-02 21:22:13

回答

51

它们在MySQL中不存在吗?只需使用一个临时表:

CREATE PROCEDURE my_proc() BEGIN 

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

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

MySQL here

“创建表时,您可以使用TEMPORARY关键词 临时 表可见只对当前 连接,并且被丢弃。当连接为 时, 自动关闭。这意味着两个不同的 连接可以使用相同的临时表 表名而不会与 相互冲突或与现有的 非TEMPORARY表具有相同的名称。 (现有的表被隐藏,直到 临时表被删除)。”

+2

如果多个用户尝试运行相同的过程,会产生任何并发问题? – 2009-10-06 11:01:49

+8

没有。临时表是用户特定的。 – longneck 2009-10-06 13:18:29

8

也许一个临时表会做你想要什么。

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

-6

其实你可以使用MySQL表变量。下面是官方文档的例子 http://dev.mysql.com/doc/refman/5.5/en/sql-syntax-prepared-statements.html

mysql> USE test; 
mysql> CREATE TABLE t1 (a INT NOT NULL); 
mysql> INSERT INTO t1 VALUES (4), (8), (11), (32), (80); 

mysql> SET @table = 't1'; 
mysql> SET @s = CONCAT('SELECT * FROM ', @table); 

mysql> PREPARE stmt3 FROM @s; 
mysql> EXECUTE stmt3; 
+6

-1,这不是一个表变量,本例中的变量只包含表名。 – gazarsgo 2012-05-30 22:36:38

4

回答您的问题:不,MySQL不支持SQL Server(http://msdn.microsoft.com/zh-cn/library/ms188927.aspx)提供的相同方式的Table-typed变量。 Oracle提供了类似的功能,但将其称为游标类型而不是表类型(http://docs.oracle.com/cd/B12037_01/appdev.101/b10807/13_elems012.htm)。

根据您的需要,您可以使用临时表以类似于Oracle和SQL Server提供的方式在MySQL中模拟表/光标类型的变量。

但是,临时表方法和表/游标类型变量方法之间有一个重要的区别,它有很多性能影响(这就是为什么Oracle和SQL Server在超过提供临时表格)。

具体来说:表/游标类型变量允许客户端整理客户端上的多行数据,并将它们作为输入发送到存储过程或预准备语句。这消除了发送每个单独行的开销,而是为一批行支付一次开销。当您尝试导入大量数据时,这可能会对整体性能产生重大影响。

一个可能的解决方法:

你可能想尝试是建立一个临时表,然后使用LOAD DATA(http://dev.mysql.com/doc/refman/5.1/en/ load-data.html)命令将数据流式传输到临时表中。然后,您可以将临时表的名称传递给您的存储过程。这仍然会导致对数据库服务器的两次调用,但是如果您移动了足够多的行,那么可能会在那里节省。当然,如果您在更新目标表时正在存储过程中执行某种逻辑,这实际上只是有益的。如果没有,您可能只想将数据直接加载到目标表中。

0

不是问题的解决方案,而是另一个简单的选择。 如果表是您想要的单列表,则通过连接这些值并在SP内部提取来导出字符串参数。

2

如果你不想在数据库中存储表,那么@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();

您可以在下面命令 -

使用测试执行后检查新表; LIKE“%扎法尔%”节目表; - 测试在这里是'数据库'的名称。

您也可以按照以下路径 -

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