Get multiple rows result from a mysql variable [duplicate] - mysql

I need a table variable to store the particular rows from the table within the MySQL procedure.
E.g. declare #tb table (id int,name varchar(200))
Is this possible? If yes how?

They don't exist in MySQL do they? Just use a temp table:
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 .... */
From MySQL here
"You can use the TEMPORARY keyword
when creating a table. A TEMPORARY
table is visible only to the current
connection, and is dropped
automatically when the connection is
closed. This means that two different
connections can use the same temporary
table name without conflicting with
each other or with an existing
non-TEMPORARY table of the same name.
(The existing table is hidden until
the temporary table is dropped.)"

Perhaps a temporary table will do what you want.
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;
From forge.mysql.com. See also the temporary tables piece of this article.

TO answer your question: no, MySQL does not support Table-typed variables in the same manner that SQL Server (http://msdn.microsoft.com/en-us/library/ms188927.aspx) provides. Oracle provides similar functionality but calls them Cursor types instead of table types (http://docs.oracle.com/cd/B12037_01/appdev.101/b10807/13_elems012.htm).
Depending your needs you can simulate table/cursor-typed variables in MySQL using temporary tables in a manner similar to what is provided by both Oracle and SQL Server.
However, there is an important difference between the temporary table approach and the table/cursor-typed variable approach and it has a lot of performance implications (this is the reason why Oracle and SQL Server provide this functionality over and above what is provided with temporary tables).
Specifically: table/cursor-typed variables allow the client to collate multiple rows of data on the client side and send them up to the server as input to a stored procedure or prepared statement. What this eliminates is the overhead of sending up each individual row and instead pay that overhead once for a batch of rows. This can have a significant impact on overall performance when you are trying to import larger quantities of data.
A possible work-around:
What you may want to try is creating a temporary table and then using a LOAD DATA (http://dev.mysql.com/doc/refman/5.1/en/load-data.html) command to stream the data into the temporary table. You could then pass them name of the temporary table into your stored procedure. This will still result in two calls to the database server, but if you are moving enough rows there may be a savings there. Of course, this is really only beneficial if you are doing some kind of logic inside the stored procedure as you update the target table. If not, you may just want to LOAD DATA directly into the target table.

MYSQL 8 does, in a way:
MYSQL 8 supports JSON tables, so you could load your results into a JSON variable and select from that variable using the JSON_TABLE() command.

If you don't want to store table in database then #Evan Todd already has been provided temporary table solution.
But if you need that table for other users and want to store in db then you can use below procedure.
Create below ‘stored procedure’:
————————————
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 ;
———————————————–
Now you can execute this procedure to create a variable name table as per below-
call sp_variable_table();
You can check new table after executing below command-
use test;show tables like ‘%zafar%’; — test is here ‘database’ name.
You can also check more details at below path-
http://mydbsolutions.in/how-can-create-a-table-with-variable-name/

Related

Is it possible to have a MySQL table comment defined before its create statement?

In order to document SQL code in a more linear fashion, I wanted to make appear the description of a table that is going to be created before the creation statement. So my first idea was to put that in a user-defined variable with which I could fill the comment instruction, but it seems to be unsupported (at least in the 5.6 version I have to deal with):
set #description = 'The following table is a useless dummy test.';
drop table if exists `test`;
create table `test` (dummy int) comment #test; -- syntax error
show table status where name='test';
Is there an other way to achieve the initial goal? Of course it's always possible to use -- SQL comments before the creation statement, but then it wouldn't appear in the recorded database structure, or at the price of a awful duplication.
We might be able to do this using dynamic SQL:
SET #description = 'The following table is a useless dummy test.';
SET #sql = CONCAT('CREATE TABLE test (dummy int) COMMENT=''', #description, '''');
PREPARE stmt FROM #sql;
EXECUTE stmt;
Note that each prepared statement is precisely just that; a single statement. So, to do this from the command line, you might need 3 statements to cover the full logic you want to run.
Although it doesn't match the question, here is a solution to its underlying problem: having the description of a table directly next to it's creation statement.
The MySQL syntax require to put the comment attached to the table at the end, but if the table have many fields, each declared on one or several lines, then the table comment can quickly be sent of sight of its declaration start.
Now, one can easily create a table with it's comment as sole attached statement, then alter it to include fields it should contains.
CREATE TALBE `test` COMMENT 'Informative description';
ALTER TABLE test
ADD id
INT UNSIGNED NOT NULL AUTO_INCREMENT
COMMENT 'Description of the id field',
ADD data
BLOB
COMMENT 'Description of the data field',
;

Splitting mysql value into unknown number of parts

I have been given a mySQL database to restructure into an OpenCart installation.
I've pulled most of the data across but in the old site "product categories" have been all put in a single column
|228|243|228|239|228|
or
|88|
or
|88|243|
So I have no idea how many would be in any particular record.
I don't want to use a php function to extract this, as I am manually extracting the data with SQL queries into the new database.
An added complication is I have to create a new line in the products_to_categories for each value in the column - I don't mind a multiple step process, I'm not expecting to do this with a single query - I am looking to avoid re-entering all the data.
I know this is similar to MySQL Split String but I don't feel it's a duplicate as that does not answer my question fully as there may be any number of values in the column - not just 2.
[EDIT] I tried common_schema, but at my current level of skill I found it difficult to get the result I was seeking, but I will certainly use it in future. For the record this is closest to my my solution - Can you split/explode a field in a MySQL query?
One option that I recommend is to use common_schema and specifically functions get_num_tokens() and split_token(), this will help.
Here a simple example of the use that you can adapt for your solution:
/* CODE FOR DEMONSTRATION PURPOSES */
/* Need to install common_schema - code.google.com/p/common-schema/ */
/* Procedure structure for procedure `explode1` */
/*!50003 DROP PROCEDURE IF EXISTS `explode1` */;
DELIMITER $$
CREATE PROCEDURE `explode1`(str varchar(65500), delim VARCHAR(255))
BEGIN
DECLARE _iteration, _num_tokens INT UNSIGNED DEFAULT 0;
DROP TEMPORARY TABLE IF EXISTS `temp_explode`;
CREATE TEMPORARY TABLE `temp_explode` (`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, `word` VARCHAR(200), PRIMARY KEY (`id`));
SET _num_tokens := (SELECT `common_schema`.`get_num_tokens`(str, delim));
WHILE _iteration < _num_tokens DO
SET _iteration := _iteration + 1;
INSERT INTO `temp_explode` (`word`) SELECT `common_schema`.`split_token`(str, delim, _iteration);
END WHILE;
SELECT `id`, `word` FROM `temp_explode`;
DROP TEMPORARY TABLE IF EXISTS `temp_explode`;
END $$
DELIMITER ;
/* TEST */
CALL `explode1`('Lorem Ipsum is simply dummy text of the printing and typesetting', CHAR(32));

Alternative solutions to table-valued parameters in mysql stored procedure [duplicate]

I need a table variable to store the particular rows from the table within the MySQL procedure.
E.g. declare #tb table (id int,name varchar(200))
Is this possible? If yes how?
They don't exist in MySQL do they? Just use a temp table:
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 .... */
From MySQL here
"You can use the TEMPORARY keyword
when creating a table. A TEMPORARY
table is visible only to the current
connection, and is dropped
automatically when the connection is
closed. This means that two different
connections can use the same temporary
table name without conflicting with
each other or with an existing
non-TEMPORARY table of the same name.
(The existing table is hidden until
the temporary table is dropped.)"
Perhaps a temporary table will do what you want.
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;
From forge.mysql.com. See also the temporary tables piece of this article.
TO answer your question: no, MySQL does not support Table-typed variables in the same manner that SQL Server (http://msdn.microsoft.com/en-us/library/ms188927.aspx) provides. Oracle provides similar functionality but calls them Cursor types instead of table types (http://docs.oracle.com/cd/B12037_01/appdev.101/b10807/13_elems012.htm).
Depending your needs you can simulate table/cursor-typed variables in MySQL using temporary tables in a manner similar to what is provided by both Oracle and SQL Server.
However, there is an important difference between the temporary table approach and the table/cursor-typed variable approach and it has a lot of performance implications (this is the reason why Oracle and SQL Server provide this functionality over and above what is provided with temporary tables).
Specifically: table/cursor-typed variables allow the client to collate multiple rows of data on the client side and send them up to the server as input to a stored procedure or prepared statement. What this eliminates is the overhead of sending up each individual row and instead pay that overhead once for a batch of rows. This can have a significant impact on overall performance when you are trying to import larger quantities of data.
A possible work-around:
What you may want to try is creating a temporary table and then using a LOAD DATA (http://dev.mysql.com/doc/refman/5.1/en/load-data.html) command to stream the data into the temporary table. You could then pass them name of the temporary table into your stored procedure. This will still result in two calls to the database server, but if you are moving enough rows there may be a savings there. Of course, this is really only beneficial if you are doing some kind of logic inside the stored procedure as you update the target table. If not, you may just want to LOAD DATA directly into the target table.
MYSQL 8 does, in a way:
MYSQL 8 supports JSON tables, so you could load your results into a JSON variable and select from that variable using the JSON_TABLE() command.
If you don't want to store table in database then #Evan Todd already has been provided temporary table solution.
But if you need that table for other users and want to store in db then you can use below procedure.
Create below ‘stored procedure’:
————————————
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 ;
———————————————–
Now you can execute this procedure to create a variable name table as per below-
call sp_variable_table();
You can check new table after executing below command-
use test;show tables like ‘%zafar%’; — test is here ‘database’ name.
You can also check more details at below path-
http://mydbsolutions.in/how-can-create-a-table-with-variable-name/

User-defined Table Variables in MySQL 5.5?

I've recently moved from MSSQL to MySQL.
I would like to use a table variable (or equivalent) inside a MySQL 5.5 stored routine, to populate a dataset for an online report.
In MS SQL, I would do it this way
...
...
DECLARE #tblName TABLE
WHILE <condition>
BEGIN
Insert Row based on iteration value
END
...
...
From what I understand, I can't declare table variables in MySQL (correct me if I'm wrong) How do I implement the above logic in a MySQL stored procedure?
You could create a table or temporary table and populate it with data you need.
CREATE TABLE Syntax
You understand that limitation correctly. The MySQL user manual clearly states that user-defined variables cannot refer to a table:
http://dev.mysql.com/doc/refman/5.5/en/user-variables.html
User variables are intended to provide data values. They cannot be used directly in an SQL statement as an identifier or as part of an identifier, such as in contexts where a table or database name is expected, or as a reserved word such as SELECT.
create temporary table tmp
(
id int unsigned not null,
name varchar(32) not null
)
engine=memory; -- change engine type if required e.g myisam/innodb
insert into tmp (id, name) select id, name from foo... ;
-- do more work...
select * from tmp order by id;
drop temporary table if exists tmp;
I think this covers it. Also, this may be helpful.

Create table variable in MySQL

I need a table variable to store the particular rows from the table within the MySQL procedure.
E.g. declare #tb table (id int,name varchar(200))
Is this possible? If yes how?
They don't exist in MySQL do they? Just use a temp table:
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 .... */
From MySQL here
"You can use the TEMPORARY keyword
when creating a table. A TEMPORARY
table is visible only to the current
connection, and is dropped
automatically when the connection is
closed. This means that two different
connections can use the same temporary
table name without conflicting with
each other or with an existing
non-TEMPORARY table of the same name.
(The existing table is hidden until
the temporary table is dropped.)"
Perhaps a temporary table will do what you want.
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;
From forge.mysql.com. See also the temporary tables piece of this article.
TO answer your question: no, MySQL does not support Table-typed variables in the same manner that SQL Server (http://msdn.microsoft.com/en-us/library/ms188927.aspx) provides. Oracle provides similar functionality but calls them Cursor types instead of table types (http://docs.oracle.com/cd/B12037_01/appdev.101/b10807/13_elems012.htm).
Depending your needs you can simulate table/cursor-typed variables in MySQL using temporary tables in a manner similar to what is provided by both Oracle and SQL Server.
However, there is an important difference between the temporary table approach and the table/cursor-typed variable approach and it has a lot of performance implications (this is the reason why Oracle and SQL Server provide this functionality over and above what is provided with temporary tables).
Specifically: table/cursor-typed variables allow the client to collate multiple rows of data on the client side and send them up to the server as input to a stored procedure or prepared statement. What this eliminates is the overhead of sending up each individual row and instead pay that overhead once for a batch of rows. This can have a significant impact on overall performance when you are trying to import larger quantities of data.
A possible work-around:
What you may want to try is creating a temporary table and then using a LOAD DATA (http://dev.mysql.com/doc/refman/5.1/en/load-data.html) command to stream the data into the temporary table. You could then pass them name of the temporary table into your stored procedure. This will still result in two calls to the database server, but if you are moving enough rows there may be a savings there. Of course, this is really only beneficial if you are doing some kind of logic inside the stored procedure as you update the target table. If not, you may just want to LOAD DATA directly into the target table.
MYSQL 8 does, in a way:
MYSQL 8 supports JSON tables, so you could load your results into a JSON variable and select from that variable using the JSON_TABLE() command.
If you don't want to store table in database then #Evan Todd already has been provided temporary table solution.
But if you need that table for other users and want to store in db then you can use below procedure.
Create below ‘stored procedure’:
————————————
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 ;
———————————————–
Now you can execute this procedure to create a variable name table as per below-
call sp_variable_table();
You can check new table after executing below command-
use test;show tables like ‘%zafar%’; — test is here ‘database’ name.
You can also check more details at below path-
http://mydbsolutions.in/how-can-create-a-table-with-variable-name/