Percona modify table to allow nulls - mysql

how do you modify a table to allow nulls using percona.
pt-online-schema-change --modfiy mycolumn default null d=database, t=table
I see the --alter but nothing to modify an existing column.

First of all, you wouldn't HAVE to use pt-online-schema-change to achieve this as you can do it in native SQL (though you may have a reason for asking how to do it with pt-online-schema-change)
For this table:
DROP DATABASE IF EXISTS test;
CREATE DATABASE test;
USE test;
CREATE TABLE t1 (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(40)
) ENGINE=InnoDB;
You can use this SQL:
ALTER TABLE `test`.`t1` CHANGE COLUMN name name VARCHAR(40) NULL;
Next, though, if you have a good reason to use pt-online-schema-change, for example if the table is very big, then this would be the syntax:
pt-online-schema-change h=127.0.0.1,P=3306,u=user,p=password,D=test,t=t1 --alter "CHANGE COLUMN name name VARCHAR(40) NULL" --execute
Here's the link to the tool's documentation https://www.percona.com/doc/percona-toolkit/LATEST/pt-online-schema-change.html

Related

How to set AUTO_INCREMENT PRIMARY KEY when using 'AS SELECT'

I am trying to create a temporary table and right now I am doing something like this:
CREATE IF NOT EXISTS TABLE tempdb.student AS (SELECT * FROM student LIMIT 0)
then
ALTER TABLE tempdb.student MODIFY id INT(20) NOT NULL AUTO_INCREMENT PRIMARY KEY
However, I need to find a way to do this without the ALTER statement because both statements are getting ran together and if the table has already been created, I am getting an error because of the multiple primary keys. Any advice? Thanks
You can define columns, indexes, table options, and partitioning before the AS keyword.
CREATE IF NOT EXISTS TABLE tempdb.student (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(10),
enroll_date DATE,
...etc...
)
AS SELECT * FROM student LIMIT 0
This is the only way you can set some column or table options, such as auto-increment.
But it means you have to define all the columns, not just id.
Since you are using LIMIT 0 it means you don't actually want any rows from the source table. I guess you are just trying to duplicate the table structure, but none of the data.
In that case, you might like to use the following instead:
CREATE IF NOT EXISTS TABLE tempdb.student LIKE student;
This duplicates other column and table options, and indexes, and partitions. The new table will have the AUTO_INCREMENT option for its primary key.
You can explicitly check if the table exists (you need to be careful if the code can be executed in parallel):
SELECT
COUNT(*) INTO #exists
FROM
information_schema.tables
WHERE
table_schema = 'tempdb'
AND table_name = 'student'
;
IF #exists = 0 THEN
CREATE TABLE tempdb.student AS (SELECT * FROM student LIMIT 0); -- or use LIKE syntax
ALTER TABLE tempdb.student MODIFY id INT(20) NOT NULL AUTO_INCREMENT PRIMARY KEY;
END IF;
If your temporary table needed for the session only, I'd use CREATE TEMPORARY TABLE ... LIKE ... and alter as required.

MySQL duplication

Using SQLyog, I was testing whether the correct value was set into table.
And I tried
SELECT type_service FROM service WHERE email='test#gmail.com'
So, only one result was output.
type_service
0
To continue to test, I tried to set value, 1 by force which gave the warning
Warning
There are 2 duplicates of the row you are trying to update. Do you
want to update all the duplicates?
Note: You can turn off this warning by unchecking Tools -> Preferences -> Others -> Prompt if multiple rows are getting updated.
But I thought I already placed limitations with where clause. So I pushed yes.
As a result, the value of all the data in type_service column was changed to 1.
Why?
You have 2 exact duplicate rows in table. Exact. It is a friendly warning, but most likely needs to be addressed by a slight schema change.
The most simple solution is to alter the table and add an auto_increment Primary Key column.
Mysql Alter Table Manual page here.
See this Webyog FAQ link.
Whenever I am about to spook up another table, I usually stub it out like:
create table blah
(
id int auto_increment primary key,
...
...
...
);
for safety sake.
Were you not to have the auto_increment PK, see the following.
create table people
(
firstName varchar(40) not null,
lastName varchar(40) not null,
age int not null
);
insert people (firstName,lastName,age) values ('Kim','Billings',30),('Kim','Billings',30),('Kim','Billings',30);
select * from people;
-- this could be bad:
update people
set age=40
where firstName='Kim' and lastName='Billings';
ALTER TABLE people ADD id INT PRIMARY KEY AUTO_INCREMENT;
select * from people; -- much nicer now, schema has an id column starting at 1
-- you now at least have a way to uniquely identify a row

converting mysql scripts to postgresql script

I have the following line in a .sql file from a mysql db:
ALTER TABLE lcr_gw ALTER COLUMN ip_addr TYPE VARCHAR(50) DEFAULT NULL;
I would like to convert it into syntax that postgresql would understand. In my personal tests, I was only able to get it to work by breaking it down into two separate statements, like so:
ALTER TABLE lcr_gw ALTER COLUMN ip_addr TYPE VARCHAR(50);
ALTER TABLE lcr_gw ALTER COLUMN ip_addr SET DEFAULT NULL;
Just wondering if there's a way to consolidate the two statements back into one, but one that postgresql will be happy with?
Thanks!
The statement you posted is not valid syntax at all:
SQL Fiddle
To change the type in MySQL, you would use CHANGE or MODIFY.
To change the default you would use DROP DEFAULT or SET DEFAULT NULL.
If the intention was to change the type and reset the column default:
Like in MySQL, you can pack multiple actions into a single ALTER TABLEstatement in Postgres .
ALTER TABLE lcr_gw ALTER COLUMN ip_addr SET DEFAULT NULL
,ALTER COLUMN ip_addr TYPE VARCHAR(50);
Per documentation:
The main reason for providing the option to specify multiple changes
in a single ALTER TABLE is that multiple table scans or rewrites can
thereby be combined into a single pass over the table.
But if there was a DEFAULT on the column that is incompatible with the new type, you have to run two separate statements:
ALTER TABLE lcr_gw ALTER COLUMN ip_addr SET DEFAULT NULL;
ALTER TABLE lcr_gw ALTER COLUMN ip_addr TYPE VARCHAR(50);
Doesn't matter in this case anyway.
As #Gordon Linoff states in the comments, postgreSQL by default sets a value to null unless a value is given or the default is changed to something else;
therefore, all you'll need is:
ALTER TABLE lcr_gw ALTER COLUMN ip_addr TYPE VARCHAR(50);
The PostgreSQL ALTER TABLE syntax diagram doesn't show any way to combine changing a data type and changing a default value in a single SQL statement. You can't simply omit set default null in the general case. For example,
create table test (
column_1 char(10) not null default 'a'
);
alter table test alter column column_1 type varchar(50);
insert into test values (default);
select * from test;
column_1
--
a
Instead, either rewrite as two independent statements (which you already know how to do), or as two statements in a single transaction.

SQL alter table works in MySQL but not in Oracle

I have created a table users
create table users (
id int,
name varchar(40)
);
Now i want a default value for name
This query works in MYSQL but not in Oracle database 11g XE
alter table users alter name set default 'user';
Can anyone explain why ?
The syntax for adding a default to an existing column is different in Oracle, viz:
alter table users
modify (name default 'user');
SqlFiddle here
I think the correct query will be like this:
ALTER TABLE users MODIFY name VARCHAR(40) NOT NULL DEFAULT 'user';

`MODIFY COLUMN` vs `CHANGE COLUMN`

I know, we cannot rename a column using MODIFY COLUMN syntax, but we can using CHANGE COLUMN syntax.
My question is: what is the main usage of modify syntax?
For example:
ALATER TABLE tablename CHANGE col1 col1 INT(10) NOT NULL;
instead of
ALATER TABLE tablename MODIFY col1 INT(10) NOT NULL;
Edited (question replaced)
What is the main usage of MODIFY syntax?
Why we have to use CHANGE COLUMN instead of MODIFYCOLUMN?
CHANGE COLUMN
If you have already created your MySQL database, and decide after the fact that one of your columns is named incorrectly, you don't need to remove it and make a replacement, you can simply rename it using change column.
ALTER TABLE MyTable CHANGE COLUMN foo bar VARCHAR(32) NOT NULL FIRST;
MODIFY COLUMN
This command does everything CHANGE COLUMN can, but without renaming the column. You can use the MODIFY SQL command if you need to resize a column in MySQL. By doing this you can allow more or less characters than before. You can't rename a column using MODIFY and other.
ALTER TABLE MyTable MODIFY COLUMN foo VARCHAR(32) NOT NULL AFTER baz;
Note
ALTER TABLE is used for altering a table in order to change column name, size, drop column etc. CHANGE COLUMN and MODIFY COLUMN commands cannot be used without help of ALTER TABLE command.
The difference is whether you want to change the column name, column definition or both.
CHANGE
Can change a column name or definition, or both
ALTER TABLE t1 CHANGE a b BIGINT NOT NULL
MODIFY
Can change a column definition but not its name
ALTER TABLE t1 MODIFY b INT NOT NULL
RENAME COLUMN (from MySQL 8.0)
Can change a column name but not its definition
ALTER TABLE t1 RENAME COLUMN b TO a
Also, CHANGE and MODIFY can be followed by an optional COLUMN keyword.
For complete explanation:
MySQL 5.7 Docs- Renaming, Redefining, and Reordering Columns
MySQL 8.0 Docs- Renaming, Redefining, and Reordering Columns
I found one difference after more than an hour of effort in trying to make a non auto_increment column into auto_increment
statement:
alter table `doctor_experience` modify column `id` int(11) unsigned auto_increment
works, but statment:
alter table `doctor_experience` change column `id` `id` int(11) unsigned auto_increment
will report an error.
That is the same. It was done to support another syntax (Oracle ALTER TABLE as I know). You can use both of them.
Note: ALTER TABLE CHANGE old_col_name new_col_name syntax allows renaming column using one command.
Change Column : Used when we want to change the column name with its definition.
eg - alter table student CHANGE name full_name VARCHAR(32) NOT NULL;
Modify column : Used when column name is to be same but change in its definition.
eg - alter table student MODIFY full_name VARCHAR(64) NOT NULL;
Rename column : Used when we only need to change the column name (its definition will be same)
alter table student RENAME COLUMN full_name TO name;