I'd like to create a table and insert data only changing the variable name.
but instead, it creates a table with the name #myId, and not with the value of the variable.
i also have tried to remove the `` but i got an sql error.
set #myId = "tabletest";
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";
CREATE TABLE `#myId` (
`id` int(10) NOT NULL,
`position` int(10) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `#myId` (`id`, `position`) VALUES
(1, 1);
I am not recommending that you do this. Table names should not be coming from variables. However, you did ask a valid question and if you were going to do this, you need dynamic SQL:
SET #sql = 'CREATE TABLE #myId (id int(10) NOT NULL, position int(10) NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=latin1;';
SET #sql = REPLACE(#sql, '#myId', 'tabletest');
PREPARE ct FROM #sql;
EXECUTE ct;
DEALLOCATE PREPARE ct;
SET #sql = 'INSERT INTO #myId (id, position) VALUES (1, 1);';
SET #sql = REPLACE(#sql, '#myId', 'tabletest');
PREPARE st FROM #sql;
EXECUTE st;
DEALLOCATE PREPARE st;
You can then execute:
SELECT * FROM tabletest;
Note that if you wanted to use #myId in the SELECT, you would need more dynamic SQL: Yucch!
Usually the right solution is just a table where you insert rows with an identifier. You can then delete those rows (or invalidate them) if necessary when you are done.
Here is a db<>fiddle.
Related
In MySQL offcial document for count,there are descriptions as below:
For MyISAM tables, COUNT(*) is optimized to return very quickly if the SELECT retrieves from one > table, no other columns are retrieved, and there is no WHERE clause. For example:
mysql> SELECT COUNT(*) FROM student;
This optimization only applies to MyISAM tables, because an exact row count is stored for this >storage engine and can be accessed very quickly. COUNT(1) is only subject to the same >optimization if the first column is defined as NOT NULL.
I want to test it for myself, and make a test as below,I make a table called system_user and the first column is type,all the value of type is null,however when I use SELECT COUNT(1) and SELECT COUNT(*) to query, I found the time cost is nearly the same,even if tried for serval times.
I am wonder why the first column is null and the optimization in MyISAM is still working?
When I use SQL_NO_CACHE,the time cost is still nearly the same:
related table:
CREATE TABLE `system_user` (
`type` varchar(10) DEFAULT NULL,
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(8) NOT NULL,
`age` int(11) DEFAULT NULL,
`tag` varchar(8) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
related procdure to create massive data:
DELIMITER $$
USE `test`$$
DROP PROCEDURE IF EXISTS `add_user_batch`$$
CREATE DEFINER=`root`#`%` PROCEDURE `add_user_batch`(IN COUNT INT)
BEGIN
DECLARE i INT;
DECLARE t_name VARCHAR(8);
DECLARE t_tag VARCHAR(20);
DECLARE t_age INT(2);
DECLARE t_sql_template VARCHAR(100);
DECLARE t_sql TEXT;
DECLARE t_tag_mod_val INT DEFAULT(25);
DECLARE t_commit_mod_val INT DEFAULT(100);
DECLARE t_start_time DATETIME;
DECLARE t_end_time DATETIME;
TRUNCATE TABLE `system_user`;
SET t_start_time=NOW();
SET t_sql_template = “INSERT INTO `system_user`(NAME, age, tag) VALUES“;
SET t_sql = t_sql_template;
SET i = 1;
WHILE i <= COUNT
DO
SET t_age = FLOOR(1 + RAND() * 60);
SET t_name = LEFT(UUID(), 8);
IF MOD(i, t_tag_mod_val) = 0 THEN
SET t_tag = “NULL“;
ELSE
SET t_tag = CONCAT(“'“,LEFT(UUID(), 8),“'“);
END IF;
SET t_sql = CONCAT(t_sql,“('“,t_name,“',“,t_age,“,“,t_tag,“)“);
IF MOD(i,t_commit_mod_val) != 0 THEN
SET t_sql = CONCAT(t_sql,“,“);
ELSE
SET t_sql = CONCAT(t_sql,“;“);
SET #insert_sql = t_sql;
PREPARE stmt FROM #insert_sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
COMMIT;
SET t_sql=t_sql_template;
END IF;
SET i = i + 1;
END WHILE;
IF LENGTH(t_sql) > LENGTH(t_sql_template) THEN
SET t_sql=CONCAT(SUBSTRING(t_sql,1,LENGTH(t_sql)-1),';');
SET #insert_sql = t_sql;
PREPARE stmt FROM #insert_sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
COMMIT;
END IF;
SET t_end_time=NOW();
SELECT CONCAT('insert data success,time cost ',TIMEDIFF(t_end_time,t_start_time)) AS finishedTag;
END$$
DELIMITER ;
I want all the tables' list with corresponding count of number of NULL entries in column 'user'. I have printed all table's name beginning with cm using
SELECT
TABLE_NAME
FROM
INFORMATION_SCHEMA.TABLES WHERE (TABLE_NAME LIKE 'cm%') ;
but for each table i want to run
SELECT COUNT(1) FROM <TABLENAME> WHERE `create_user` IS NULL
OR `create_time` IS NULL
and print
Create the table below, replacing it with the correct database name:
CREATE TABLE `db`.`tbl_count_null` (
`tableschema` varchar(64) NOT NULL DEFAULT '',
`tablename` varchar(64) NOT NULL DEFAULT '',
`qtd` char(0) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
See if the procedure below meets you:
CREATE DEFINER=`user`#`%` PROCEDURE `nameprocedure`()
BEGIN
DECLARE x, y LONGTEXT;
DECLARE done INT DEFAULT 0;
DECLARE databasesCursor CURSOR FOR
SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME LIKE 'cm%';
DECLARE CONTINUE HANDLER
FOR SQLSTATE '02000' SET done = 1;
OPEN databasesCursor;
myLoop: LOOP
FETCH databasesCursor INTO x, y;
IF NOT done THEN
SET #query = CONCAT("INSERT INTO`db`.`tbl_count_null` (tableschema, tablename, qtd) SELECT '",x,"' AS `schema`,'",y,"' AS `table`,COUNT(1) FROM `",x,"`.`",y,"` WHERE `create_user` IS NULL OR `create_time` IS NULL;");
PREPARE stmt FROM #query;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END IF;
END LOOP myLoop;
CLOSE databasesCursor;
END;
After creating the above procedure, call with the command:
call db.nameprocedure;
Verify that the records have been inserted into the table db.tbl_count_null
I have a Table Structure as below
CREATE TABLE `eatables` (
`Sno` int(11) NOT NULL auto_increment,
`Name` varchar(255) collate latin1_general_ci default NULL,
PRIMARY KEY (`Sno`)
);
The Table contains Rows as below
insert into `eatables`(`Sno`,`Name`) values (1,'Apples');
insert into `eatables`(`Sno`,`Name`) values (2,'Oranges');
insert into `eatables`(`Sno`,`Name`) values (3,'Papaya');
insert into `eatables`(`Sno`,`Name`) values (4,'Jackfruit');
insert into `eatables`(`Sno`,`Name`) values (5,'Pineapple');
insert into `eatables`(`Sno`,`Name`) values (6,'Mango');
I created a Procedure to get the Count based on Name as Constraint
DROP PROCEDURE IF EXISTS proc_fruit_count;
CREATE PROCEDURE mp_user_preference(pFruitName VARCHAR(255))
BEGIN
SELECT #lngCount = COUNT(Sno)
FROM eatables
WHERE Name = pFruitName;
SELECT #lngCount;
END
But my Procedure is returning Null every time I execute it.
You have to modify your stored procedure! You also need to use IN keyword:
CREATE PROCEDURE mp_user_preference(IN pFruitName VARCHAR(255))
BEGIN
SELECT #lngCount = COUNT(Sno)
FROM eatables
WHERE Name = pFruitName;
SELECT #lngCount;
END
See http://www.mysqltutorial.org/stored-procedures-parameters.aspx
Edit:If you want to return lngCount you can modify the stored procedure as follow:
CREATE PROCEDURE mp_user_preference(IN pFruitName VARCHAR(255), OUT toReturn INT)
BEGIN
SELECT #lngCount = COUNT(Sno)
FROM eatables
WHERE Name = pFruitName
INTO toReturn;
END
You don't need a stored procedure here. You can solve this conveniently with a prepared statement.
prepare stmt from 'select count(*) from eatables where name = ?';
set #whatever = 'Mango';
execute stmt using #whatever; /* #whatever replaces the ? in the query above */
/* and if you don't need the prepared statement any more you do... */
deallocate prepare stmt;
Read more about prepared statements here.
I have data in a wp_users table, and I want to duplicate the data from that table (except for the ID column) into another table, called wp_users2.
If I didn't care about the id column, which I want to auto-increment, I could just do this:
insert into wp_users2 (select *, NULL as ID from wp_users)
So I know I could do this by typing out all of the column headers except for ID and manually selecting that one as NULL,
SELECT NULL as id, col2, col3...
but I'd like to do it dynamically. I read this great S.O. post about how to do that, and it works, however I can't figure out how to take the data it gives me and put it into an insert statement.
INSERT INTO wp_users2 (
SET #sql = CONCAT('SELECT NULL as ID,',
(SELECT REPLACE(GROUP_CONCAT(COLUMN_NAME), 'ID,', '')
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'wp_users'
AND TABLE_SCHEMA = 'wp1'),
' FROM wp_users');
PREPARE stmt1 FROM #sql;
EXECUTE stmt1;
)
What's the right syntax for that?
As I understand - id is AUTO_INCREMENT field.
So, try to use this script as an example for your task -
CREATE TABLE table1(
id INT(11) NOT NULL AUTO_INCREMENT,
column1 VARCHAR(255) DEFAULT NULL,
column2 VARCHAR(255) DEFAULT NULL,
PRIMARY KEY (id)
);
CREATE TABLE table2(
id INT(11) NOT NULL AUTO_INCREMENT,
column1 VARCHAR(255) DEFAULT NULL,
column2 VARCHAR(255) DEFAULT NULL,
PRIMARY KEY (id)
);
INSERT INTO table1 VALUES
(1, 'c1', 'c2'),
(2, 'c3', 'c4');
SET #source_table = 'table1';
SET #target_table = 'table2';
SET #id = 'id';
SET #columns = NULL;
SELECT group_concat(column_name) INTO #columns FROM information_schema.columns
WHERE
table_schema = 'database_name' -- Set your database name here
AND table_name = #source_table
AND column_name != #id;
SET #insert = concat('INSERT INTO ', #target_table, '(', #id, ',', #columns, ') SELECT NULL, ', #columns, ' FROM ', #source_table);
PREPARE stmt1 FROM #insert;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
set #sql = (select concat('insert into wp_users2 SELECT NULL,',
group_concat(column_name),' from ',table_name) from information_schema.columns
where table_name = 'wp_users' and table_schema = 'wp1' and column_name != 'id'
order by ordinal_position);
prepare stmt1 from #sql;
execute stmt1;
deallocate prepare stmt1;
In MySQL, I have a table, and I want to set the auto_increment value to 5 instead of 1. Is this possible and what query statement does this?
You can use ALTER TABLE to change the auto_increment initial value:
ALTER TABLE tbl AUTO_INCREMENT = 5;
See the MySQL reference for more details.
Yes, you can use the ALTER TABLE t AUTO_INCREMENT = 42 statement. However, you need to be aware that this will cause the rebuilding of your entire table, at least with InnoDB and certain MySQL versions. If you have an already existing dataset with millions of rows, it could take a very long time to complete.
In my experience, it's better to do the following:
BEGIN WORK;
-- You may also need to add other mandatory columns and values
INSERT INTO t (id) VALUES (42);
ROLLBACK;
In this way, even if you're rolling back the transaction, MySQL will keep the auto-increment value, and the change will be applied instantly.
You can verify this by issuing a SHOW CREATE TABLE t statement. You should see:
> SHOW CREATE TABLE t \G
*************************** 1. row ***************************
Table: t
Create Table: CREATE TABLE `t` (
...
) ENGINE=InnoDB AUTO_INCREMENT=43 ...
How to auto increment by one, starting at 10 in MySQL:
create table foobar(
id INT PRIMARY KEY AUTO_INCREMENT,
moobar VARCHAR(500)
);
ALTER TABLE foobar AUTO_INCREMENT=10;
INSERT INTO foobar(moobar) values ("abc");
INSERT INTO foobar(moobar) values ("def");
INSERT INTO foobar(moobar) values ("xyz");
select * from foobar;
'10', 'abc'
'11', 'def'
'12', 'xyz'
This auto increments the id column by one starting at 10.
Auto increment in MySQL by 5, starting at 10:
drop table foobar
create table foobar(
id INT PRIMARY KEY AUTO_INCREMENT,
moobar VARCHAR(500)
);
SET ##auto_increment_increment=5;
ALTER TABLE foobar AUTO_INCREMENT=10;
INSERT INTO foobar(moobar) values ("abc");
INSERT INTO foobar(moobar) values ("def");
INSERT INTO foobar(moobar) values ("xyz");
select * from foobar;
'11', 'abc'
'16', 'def'
'21', 'xyz'
This auto increments the id column by 5 each time, starting at 10.
You can also do it using phpmyadmin. Just select the table than go to actions. And change the Auto increment below table options. Don't forget to click on start
Procedure to auto fix AUTO_INCREMENT value of table
DROP PROCEDURE IF EXISTS update_auto_increment;
DELIMITER //
CREATE PROCEDURE update_auto_increment (_table VARCHAR(64))
BEGIN
DECLARE _max_stmt VARCHAR(1024);
DECLARE _stmt VARCHAR(1024);
SET #inc := 0;
SET #MAX_SQL := CONCAT('SELECT IFNULL(MAX(`id`), 0) + 1 INTO #inc FROM ', _table);
PREPARE _max_stmt FROM #MAX_SQL;
EXECUTE _max_stmt;
DEALLOCATE PREPARE _max_stmt;
SET #SQL := CONCAT('ALTER TABLE ', _table, ' AUTO_INCREMENT = ', #inc);
PREPARE _stmt FROM #SQL;
EXECUTE _stmt;
DEALLOCATE PREPARE _stmt;
END//
DELIMITER ;
CALL update_auto_increment('your_table_name')
If you need this procedure for variable fieldnames instead of id this might be helpful:
DROP PROCEDURE IF EXISTS update_auto_increment;
DELIMITER //
CREATE PROCEDURE update_auto_increment (_table VARCHAR(128), _fieldname VARCHAR(128))
BEGIN
DECLARE _max_stmt VARCHAR(1024);
DECLARE _stmt VARCHAR(1024);
SET #inc := 0;
SET #MAX_SQL := CONCAT('SELECT IFNULL(MAX(',_fieldname,'), 0) + 1 INTO #inc FROM ', _table);
PREPARE _max_stmt FROM #MAX_SQL;
EXECUTE _max_stmt;
DEALLOCATE PREPARE _max_stmt;
SET #SQL := CONCAT('ALTER TABLE ', _table, ' AUTO_INCREMENT = ', #inc);
PREPARE _stmt FROM #SQL;
EXECUTE _stmt;
DEALLOCATE PREPARE _stmt;
END //
DELIMITER ;
CALL update_auto_increment('your_table_name', 'autoincrement_fieldname');
just export the table with data ..
then copy its sql like
CREATE TABLE IF NOT EXISTS `employees` (
`emp_badgenumber` int(20) NOT NULL AUTO_INCREMENT,
`emp_fullname` varchar(100) NOT NULL,
`emp_father_name` varchar(30) NOT NULL,
`emp_mobile` varchar(20) DEFAULT NULL,
`emp_cnic` varchar(20) DEFAULT NULL,
`emp_gender` varchar(10) NOT NULL,
`emp_is_deleted` tinyint(4) DEFAULT '0',
`emp_registration_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`emp_overtime_allowed` tinyint(4) DEFAULT '1',
PRIMARY KEY (`emp_badgenumber`),
UNIQUE KEY `bagdenumber` (`emp_badgenumber`),
KEY `emp_badgenumber` (`emp_badgenumber`),
KEY `emp_badgenumber_2` (`emp_badgenumber`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=111121326 ;
now change auto increment value and execute sql.