Oracle Virtual Columns and MySQL Generated Columns - Oracle to Aurora MySQL Migration Playbook
Services or capabilities described in Amazon Web Services documentation might vary by Region. To see the differences applicable to the China Regions, see Getting Started with Amazon Web Services in China (PDF).

Oracle Virtual Columns and MySQL Generated Columns

Feature compatibility Amazon SCT / Amazon DMS automation level Amazon SCT action code index Key differences

Four star feature compatibility

Three star automation level

Creating Table

Different paradigm and syntax.

Oracle Usage

Oracle virtual columns appear as normal columns, but their values are calculated instead of being stored in the database. You can’t create virtual columns based on other virtual columns and can only reference columns from the same table. When you create a virtual column, you can either explicitly specify the data type or let the database select the data type based on the expression.

You can use virtual columns with constraints, indexes, table partitioning, and foreign keys.

Functions in expressions must be deterministic at the time of table creation.

Virtual columns can’t be manipulated by DML operations.

You can use virtual columns in a WHERE clause and as part of DML commands.

When you create an index on a virtual column, Oracle creates a function-based index.

Virtual columns don’t support index-organized tables, external, objects, clusters, or temporary tables.

The output of a virtual column expression must be a scalar value.

The virtual column keywords GENERATED ALWAYS AS and VIRTUAL aren’t mandatory and are provided for clarity only.

COLUMN_NAME [data type] [GENERATED ALWAYS] AS (expression) [VIRTUAL]

The keyword AS after the column name indicates the column is created as a virtual column.

A virtual column doesn’t need to be specified in an INSERT statement.

Examples

Create a table that includes two virtual columns.

CREATE TABLE EMPLOYEES (
  EMPLOYEE_ID NUMBER,
  FIRST_NAME VARCHAR2(20),
  LAST_NAME VARCHAR2(25),
  USER_NAME VARCHAR2(25),
  EMAIL AS (LOWER(USER_NAME) || '@aws.com'),
  HIRE_DATE DATE,
  BASE_SALARY NUMBER,
  SALES_COUNT NUMBER,
  FINAL_SALARY NUMBER GENERATED ALWAYS AS
    (CASE WHEN SALES_COUNT >= 10 THEN BASE_SALARY +
    (BASE_SALARY * (SALES_COUNT * 0.05))
    END)
  VIRTUAL);

Insert a new record into the table without specifying values for the virtual column.

INSERT INTO EMPLOYEES
  (EMPLOYEE_ID, FIRST_NAME, LAST_NAME,
    USER_NAME, HIRE_DATE,BASE_SALARY, SALES_COUNT)
  VALUES(1, 'John', 'Smith', 'jsmith',
    '17-JUN-2003', 5000, 21);

Select the email Virtual Column from the table.

SELECT email FROM EMPLOYEES;

EMAIL           FINAL_SALARY
jsmith@aws.com  10250

For more information, see CREATE TABLE in the Oracle documentation.

MySQL Usage

The syntax and functionality of generated columns are similar to virtual columns. They appear as normal columns, but their values are calculated. Generated columns cannot be created based on other Generated Columns and can only reference columns from the same table. When you create generated columns, make sure that you explicitly specify the data type of the column.

  • Unlike Oracle, you can create generated columns based on other generated columns preceding them in the field list.

  • You can use generated columns with constraints, indexes, table partitioning.

  • Functions in expressions must be deterministic at the time of table creation.

  • Generated columns can’t be manipulated by DML operations.

  • Generated columns can be used in a WHERE clause and as part of DML commands.

  • When you create an index on a generated column, the generated values are stored in the index.

  • The output of a generated column expression must be a scalar value.

Examples

Create a table that includes two generated columns.

CREATE TABLE EMPLOYEES (
  EMPLOYEE_ID INT,
  FIRST_NAME VARCHAR(20),
  LAST_NAME VARCHAR(25),
  USER_NAME VARCHAR(25),
  EMAIL VARCHAR(25) AS
    (CONCAT(LOWER(USER_ NAME),'@aws.com')),
  HIRE_DATE DATE,
  BASE_SALARY INT,
  SALES_COUNT INT,
  FINAL_SALARY INT GENERATED ALWAYS AS
    (CASE WHEN SALES_COUNT >= 10 THEN BASE_SALARY + (
    BASE_SALARY * (SALES_COUNT * 0.05)) END) VIRTUAL);

Insert a new record into the table without specifying values for the generated column.

INSERT INTO EMPLOYEES
  (EMPLOYEE_ID, FIRST_NAME, LAST_NAME, USER_NAME, HIRE_DATE,
  BASE_SALARY, SALES_COUNT)
  VALUES(1, 'John', 'Smith', 'jsmith', now(), 5000, 21);

Select the email and the generated column from the table.

SELECT EMAIL, FINAL_SALARY FROM EMPLOYEES;

For the preceding example, the result looks as shown following.

email           FINAL_SALARY
jsmith@aws.com  10250

For more information, see CREATE TABLE and Generated Columns and Secondary Indexes and Generated Columns in the MySQL documentation.