ALTER TABLE — Modifies an existing table definition.
ALTER TABLE table-name DROP CONSTRAINT constraint-name
ALTER TABLE table-name DROP [COLUMN] column-name [CASCADE]
ALTER TABLE table-name DROP {PRIMARY KEY | TTL}
ALTER TABLE table-name ADD constraint-definition
ALTER TABLE table-name ADD column-definition [BEFORE column-name]
ALTER TABLE table-name ADD ttl-definition
ALTER TABLE table-name ALTER column-definition [CASCADE]
ALTER TABLE table-name ALTER [COLUMN] column-name SET {DEFAULT value | [NOT] NULL}
ALTER TABLE table-name ALTER ttl-definition
column-definition: [COLUMN] column-name datatype [DEFAULT value ] [ NOT NULL ] [index-type]
constraint-definition: [CONSTRAINT constraint-name] { index-definition }
index-definition: {index-type} (column-name [,...])
ttl-definition: USING TTL value [time-unit]
ON COLUMN column-name
[BATCH_SIZE
number-of-rows] [MAX_FREQUENCY value]
index-type: PRIMARY KEY | UNIQUE | ASSUMEUNIQUE
The ALTER TABLE modifies an existing table definition by adding, removing or modifying a column, constraint, or clause. There are several different forms of the ALTER TABLE statement, depending on what attribute you are altering and how you are changing it. The key point to remember is that you only alter one item at a time. For example, to change two columns or a column and a constraint, you need to issue two ALTER TABLE statements.
There are three ALTER TABLE operations:
ALTER TABLE ADD
ALTER TABLE DROP
ALTER TABLE ALTER
The syntax of each statement depends on whether you are modifying a column, a constraint, or the TTL clause. You can ADD or DROP columns, indexes, and the TTL clause and you can ALTER columns and the TTL clause. However, you cannot ALTER indexes. To alter an existing constraint you must first DROP the constraint and then ADD the new definition.
There are two forms of the ALTER TABLE DROP statement. You can drop a column or constraint by name or you can drop a PRIMARY KEY or a USING TTL clause by identifying the item to drop, since there is only one such item for any given table.
The syntax for the ALTER TABLE ADD statement uses the same syntax to define a new column, constraint, or clause as that used in the CREATE TABLE command. When adding a column you can also specify the BEFORE clause to specify where the new column falls in the order of table columns. If you to not specify BEFORE, the column is added at the end of the list of columns.
When modifying the USING TTL clause, the ALTER TABLE ALTER command specifies the complete replacement definition for the clause, including either or both the BATCH_SIZE or MAX_FREQUENCY clauses.
You cannot alter the MIGRATE TO TARGET attribute of the table. You also cannot alter any attributes of the table that affect migration. For example, you cannot add, drop, or alter the USING TTL clause if the table is declared with MIGRATE TO TARGET. And if the table has both MIGRATE TO TARGET and USING TTL, you cannot add, drop, or alter the TTL column. However, you can alter the TTL value, batch size, and frequency.
To add, drop, or alter the MIGRATE action you must drop the table first and redefine it using the CREATE TABLE statement.
When modifying columns, the ALTER TABLE ALTER COLUMN statement can have one of two forms. You can alter the column by providing a complete replacement definition, similar to the ALTER TABLE ADD COLUMN statement, or you can alter a specific attribute using the ALTER TABLE ALTER COLUMN... SET syntax. Use SET DEFAULT to add or modify an existing default. Use SET DEFAULT NULL to remove an existing default. You can also use the SET clause to specify whether the column can be null (SET NULL) or must not contain a null value (SET NOT NULL).
You can only alter tables if there are no dependencies on the table, column, or index that would be violated by the change. For example, you cannot drop the partitioning column from a partitioned table if there are stored procedures partitioned on that table and column as well. You must first drop the partitioned store procedures before dropping the column. Note that by dropping the partitioning column, you are also automatically changing the table into a replicated table.
The most common dependency is if the table already has data in it. You can add, delete, and (within reasonable bounds) modify the columns of a table with existing data as long as those columns are not named in an index, view, or PARTITION statement. If a column is referenced in a view or index, you can specify CASCADE when you drop the column to automatically drop the referring indexes and views.
When a table has records in it, data associated with dropped columns is deleted. Added columns are interpreted as null or filled in with the specified default value. (You cannot add a column that is defined as NOT NULL, but without a default, if the table has existing data in it.) You can even change the datatype of the column within reason. In other words, you can increase the size of the datatype (for example, from INTEGER to BIGINT) but you cannot decrease the size (say, from INTEGER to TINYINT) since some of the existing data may already violate the size constraint.
You can also add non-unique indexes to tables with existing data. However, you cannot add unique constraints (such as PRIMARY KEY) if data exists.
If a table has no records in it, you can make almost any changes you like to it assuming, again, there are no dependencies. You can add and remove unique constraints, add, remove, and modify columns, even change column datatypes at will.
However, if there are dependencies, such as stored procedure queries that reference a dropped or modified column, you may not be allowed to make the change. If there are such dependencies, it is often easier to do drop the stored procedures before making the changes then recreate the stored procedures afterwards.
The following example uses ALTER TABLE to drop a unique constraint, add a new column, and then recreate the constraint adding the new column.
ALTER TABLE Employee DROP CONSTRAINT UniqueNames; ALTER TABLE Employee ADD COLUMN MiddleInitial VARCHAR(1); ALTER TABLE Employee ADD CONSTRAINT UniqueNames UNIQUE (FirstName, MiddleInitial, LastName);