Converting an INT column to an ENUM column in MySQL - mysql

I have following INT column in my MySQL table with two records:
I have tried to change the datatype to ENUM with following:
`BetalingsStatus` ENUM ('BestillingRegistreret','FakturaSendt','Betalt') NOT NULL,
But my existing data goes missing. How do I convert my existing INT values to ENUM ?.

create the new column:
ALTER TABLE XXX ADD `BetalingsStatus_Tmp` ENUM('BestillingRegistreret','FakturaSendt','Betalt') NOT NULL DEFAULT '' AFTER BetalingsStatus;
Update the data:
UPDATE XXXX SET BetalingsStatus_Tmp = CASE BetalingsStatus
WHEN 0 THEN 'BestillingRegistreret'
WHEN 1 THEN 'FakturaSendt'
WHEN 2 THEN 'Betalt'
END
Delete old column:
ALTER TABLE XXX DROP BetalingsStatus;
Rename tmp column:
ALTER TABLE XXX CHANGE BetalingsStatus_Tmp BetalingsStatus ENUM('BestillingRegistreret','FakturaSendt','Betalt') NOT NULL;

Related

ALTER COLUMN TYPE from tinyInt to Varchar in Mysql

I need to change column type from tinyInt(used as bool) to Varchar, without loosing data.
I have found many answers on stack-overflow but all of them are written in postgres and I have no idea how to rewrite it in Mysql.
Answers for this problem on stack-overflow looks like that:
ALTER TABLE mytabe ALTER mycolumn TYPE VARCHAR(10) USING CASE WHEN mycolumn=0 THEN 'Something' ELSE 'TEST' END;
How would similar logic look like in Mysql?
The syntax you show has no equivalent in MySQL. There's no way to modify values during an ALTER TABLE. An ALTER TABLE in MySQL will only translate values using builtin type casting. That is, an integer will be translated to the string format of that integer value, just it would in a string expression.
For MySQL, here's what you have to do:
Add a new column:
ALTER TABLE mytable ADD COLUMN type2 VARCHAR(10);
Backfill that column:
UPDATE mytable SET type2 = CASE `type` WHEN 0 THEN 'Something' ELSE 'TEST' END;
If the table has millions of rows, you may have to do this in batches.
Drop the old column and optionally rename the new column to the name of the old one:
ALTER TABLE mytable DROP COLUMN `type`, RENAME COLUMN type2 to `type`;
Another approach would be to change the column, allowing integers to convert to the string format of the integer values. Then update the strings as you want.
ALTER TABLE mytable MODIFY COLUMN `type` VARCHAR(10);
UPDATE mytable SET `type` = CASE `type` WHEN '0' THEN 'Something' ELSE 'TEST' END;
Either way, be sure to test this first on another table before trying it on your real table.

Copy table data on same server with field remapping

I need to copy the data of an old table with millions of rows to a newer table, with a slightly different definition. Most importantly, there is one new field with a null-default, and a varchar field became an enum (with directly mapping values).
Old table:
id : integer
type : varchar
New table:
id : integer
type : enum
number : integer, default null
All of the possible string values of type are within the new enumeration.
I tried the following:
insert into new.table select * from old.table
But I obviously get:
Insert value list does not match column list: 1136 Column count doesn't match value count at row 1
You can copy the table data and structure from phpmyadmin window, and then modify the new table and add the new column.
Using the INSERT ... SELECT syntax:
INSERT INTO new.table `id`, `type` SELECT `id`, `type` FROM old.table
Apparently the varchar to enum remapping isn't a problem.

Insert DataFrame into SQL table with AUTO_INCREMENT column

I have a MySQL table which includes a column that is AUTO_INCREMENT:
CREATE TABLE features (
id INT NOT NULL AUTO_INCREMENT,
name CHAR(30),
value DOUBLE PRECISION
);
I created a DataFrame and wanted to insert it into this table.
case class Feature(name: String, value: Double)
val rdd: RDD[Feature]
val df = rdd.toDF()
df.write.mode(SaveMode.Append).jdbc("jdbc:mysql://...", "features", new Properties)
I get the error, Column count doesn’t match value count at row 1. If I delete the id column it works. How could I insert this data into the table without changing the schema?
You have to include an id field in the DataFrame, but its value will be ignored and replaced with the auto-incremented ID. That is:
case class Feature(id: Int, name: String, value: Double)
Then just set id to 0, or any number when you create a Feature.

MYSQL-Update Existing Varchar column GUID values to Binary

I have a MYSQL database with GUID(or UUID) stored as Varchar(36). To improve performance, I want to convert them to Binary(16). For new values I can use something like
INSERT INTO sometable (SOMECOLUMN,UUID) VALUES
("Something",UNHEX([the-uuid]))
But how can I update the existing stored GUID values to Binary(16)?
Got the answer myself.
In case anyone else need it. Here it is
Change the Type of GUID column to VARBINARY to avoid right padding.
ALTER TABLE newtable MODIFY COLUMN id VARBINARY(36) NOT NULL;
Update the existing id data to the BINARY id
UPDATE newtable set id=UNHEX(REPLACE(id,'-',''));
Now change the column datatype to BINARY(16)
ALTER TABLE newtable MODIFY COLUMN id BINARY(16) NOT NULL;
Create a new column:
ALTER TABLE sometable ADD newColumn BINARY(16) AFTER UUID;
Update the table:
UPDATE sometable SET newColumn = UNHEX(UUID);
Drop the old column and rename the new one (if so desired—often best not to rename, so that application code that has not been updated will fail rather than use the table incorrectly):
ALTER TABLE sometable DROP UUID, CHANGE newColumn UUID BINARY(16);

Sql script to modify column data types

Does anyone know a script to alter the data type of a column in a table which is part of number of databases? e.g.
I have a user table in 20 different databases with same columns. I want to change the datatype of one of the columns from that table.
You can use the information_schema to generate DDL commands to modify the columns.
For example, if all of the tables are named "user" (and there are no "user" tables in other databases that you DO NOT want to change), and your column is named "change_me", and you want to make it an unsigned int that is never null, you could do something like this:
select concat('ALTER TABLE ',table_schema,
'.',table_name,
' MODIFY COLUMN ',column_name,
' INT UNSIGNED NOT NULL;') as sql_stmt
into outfile '/tmp/modify_columns.sql'
from information_schema.columns
where table_name = 'user'
and column_name = 'change_me';
\. /tmp/modify_columns.sql
Also remember that many times, the column must be empty to change data types and will depend upon DBMS. Please specify from and to what datatype. Alternatives:
desc foo;
Name Null Type
------------------------------ -------- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
BAR1 NUMBER
-- this will not work:
alter table foo modify ( bar1 varchar(255) );
--instead
alter table foo add ( bar2 varchar(255));
-- assume the DB will auto change type:
update foo set bar2=bar1;
alter table foo drop (bar1);
alter table foo rename column bar2 to bar1;