Modifying data

DML statements

Data Manipulation Language (DML) is subset of SQL that is employed to change data.
Oracle DML statements
Statement Description
INSERT Adds rows to a table or tables.
UPDATE Changes values stored in a table.
MERGE Updates or inserts rows from one table into another.
DELETE Removes rows from a table.
SELECT FOR UPDATE Prevents other sessions from performing DML on selected rows.
LOCK TABLE Prevents other sessions from performing DML on a table.

Inserting rows into a table

INSERT INTO [schema.]{table | view}[@DBlink]
 [(colunm_list)]
 { VALUES (value_list) | subquery};
Here are several examples:
INSERT INTO departments
       VALUES ('sd01', 'Statistics', 'Communications Building', 19645, 'dp01');
or
INSERT INTO ist.departments (id, name, location)
       VALUES ('sd01', 'Statistics', 'Communications Building');
or
INSERT INTO main_departments
       SELECT * FROM departments WHERE name LIKE 'dp%';
Another syntax of the INSERT statement is
INSERT INTO (subquery)
 [(colunm_list)]
 { VALUES (value_list) | subquery};
Here is an example:
INSERT INTO
 (SELECT * FROM departments WHERE name LIKE 'dp%')
 VALUES ('test', 'Test department.', 'Nowhere', NULL, NULL);
Note: if the subquery we are trying to insert into is a join of several tables, then we cannot insert into more than one table with one query.

We also cannot insert rows into a view that contains any of the following:

Using the INSERT statement we can insert into several tables. There are two types of multi-table insert: simple multitable insert and conditional multitable insert.

INSERT ALL
  INTO [schema.]{table_1 | view_1}[@DBlink]
    [(colunm_list)] VALUES ( expr_list )
  INTO [schema.]{table_2 | view_2}[@DBlink]
    [(colunm_list)] VALUES ( expr_list )
  ...
  INTO [schema.]{table_n | view_n}[@DBlink]
    [(colunm_list)] VALUES ( expr_list )
  subquery;
Here is an example:
INSERT ALL
  INTO sales (prod_id, cust_id, time_id, amount)
       VALUES (product_id, customer_id, weekly_start_date, sales_sun)
  INTO sales (prod_id, cust_id, time_id, amount)
       VALUES (product_id, customer_id, weekly_start_date+1, sales_mon)
  INTO sales (prod_id, cust_id, time_id, amount)
       VALUES (product_id, customer_id, weekly_start_date+2, sales_tue)
  INTO sales (prod_id, cust_id, time_id, amount)
       VALUES (product_id, customer_id, weekly_start_date+3, sales_wed)
  INTO sales (prod_id, cust_id, time_id, amount)
       VALUES (product_id, customer_id, weekly_start_date+4, sales_thu)
  INTO sales (prod_id, cust_id, time_id, amount)
       VALUES (product_id, customer_id, weekly_start_date+5, sales_fri)
  INTO sales (prod_id, cust_id, time_id, amount)
       VALUES (product_id, customer_id, weekly_start_date+6, sales_sat)
 SELECT product_id, customer_id, weekly_start_date, sales_sun,
        sales_mon, sales_tue, sales_wed, sales_thu, sales_fri, sales_sat
   FROM sales_input_table;

The conditional insert (unlike the simple multitable insert) can insert new rows only in some of the tables, not all of them. The general syntax of the conditional insert statement is

INSERT { ALL | FIRST }
  WHEN condition_1
    THEN INTO [schema.]{table_1 | view_1}[@DBlink]
  WHEN condition_2
    THEN INTO [schema.]{table_2 | view_2}[@DBlink]
  ...
  WHEN condition_n
    THEN INTO [schema.]{table_n | view_n}[@DBlink]
  [ELSE]
    INTO [schema.]{table | view}[@DBlink]
  subquery;
The keyword ALL makes Oracle evaluate each WHEN clause, whether or not any evaluate to true. The keyword FIRST stops the evaluation when the first encountered condition evaluates to true. The example show how to use is:
INSERT FIRST
  WHEN category = 'V' THEN
    INTO video_sales (product_id, customer_id, quantity, price) VALUES (pid, cid, qty, price)
  WHEN category = 'A' THEN
    INTO audio_sales (product_id, customer_id, quantity, price) VALUES (pid, cid, qty, price)
  WHEN category = 'B' THEN
    INTO book_sales (product_id, customer_id, quantity, price) VALUES (pid, cid, qty, price)
  ELSE INTO errors VALUES (sysdate, 'Unknown product code: ' || categody)
 SELECT pid, cid, qty, price, category
   FROM sales;

Updating rows in a table

To modify data in a table we use the UPDATE statement. The syntax of the query is
UPDATE [schema.]{table | view}[@DBlink]
   SET column = {expression | (subquery)}
 [WHERE conditions];
or
UPDATE [schema.]{table | view}[@DBlink]
   SET (column_list) = (subquery)
 [WHERE conditions];
For example,
UPDATE employees
   SET dob = trunc(dob);
or
UPDATE employees e
   SET bonus = (SELECT salary*0.10
                  FROM employees s, departments
                 WHERE s.ssn = head AND e.dep = id)
 WHERE dep = 'sd03';

Merging rows in a table

The MERGE statement is used to both insert and update rows in a table. This statement has a join specification that describes how to determine which operation should be executed. The general syntax if the MERGE statement is
MERGE INTO [schema.]{table | view}[@DBlink]
   USING {[schema.]{table | view} | (subquery)}
      ON ( condition )
   WHEN MATCHED THEN UPDATE SET column = expression
   WHEN NOT MATCHED THEN INSERT [(column_list)] VALUES (expression_list);
Here is an example
MERGE INTO products p
  USING new_products np
     ON (p.id = np.id)
   WHEN MATCHED THEN UPDATE SET
        p.price=np.price, p.min_price=np.min_price, p.qty=p.qty+np.qty
   WHEN NOT MATCHED THEN INSERT
        VALUES (np.id, 33, np.price, np.min_price, np.qty);

Deleting rows from a table

The DELETE statement is used to remove rows from a table. The general syntax of the statement is
DELETE [FROM] [schema.]{table | view}[@DBlink]
  [WHERE conditions];
Examples:
-- remove all employees from the department 'sd03'
DELETE FROM employees
 WHERE dep = 'sd03';

-- remove all subdepartments
DELETE FROM departments
 WHERE id LIKE 's%';

-- remove all rows from the table TestTable
DEKETE FROM TestTable;

Another way to remove all rows from a table is to use the TRUNCATE command. The syntax for the TRUNCATE statement is

TRUNCATE TABLE [schema.]table [{ DROP | REUSE} STORAGE];
This statement removes all rows from the specified table, but TRUNCATE is a DDL (Data Definition Language), and therefore it has different characteristics from the DELETE statement:

One more way to remove all rows from a table is to drop the table and recreate it back. This method also has its own characteristics:

Locking a table

The SELECT FOR UPDATE statement is used to lock specific rows of a table, preventing other sessions from changing those locked rows. When rows are locked, other sessions can read them, but not change. The syntax for the statement is identical to a SELECT statement, except we append the keywords FOR UPDATE. The lock acquired for a SELECT FOR UPDATE will not be released until the transaction ends, even if no data changes.

The LOCK TABLE statement is used to lock am entire table, preventing other sessions from performing most or all DML on it. The LOCK TABLE statement syntax is

LOCK TABLE [schema.]table IN locking_mode MODE [NOWAIT];
Oracle has 5 types of locking mode: described in the table below.
Lock modes
Lock Prevents Allows Acquiring statements
RS X RS, RX, S, SRX   SELECT FOR UPDATE
LOCK TABLE IN ROW SHARE MODE
RX X, SRX, S RS, RX INSERT, MERGE, UPDATE, DELETE
LOCK TABLE IN ROW EXCLUSIVE MODE
S X, SRX, RX RS, S LOCK TABLE IN SHARE MODE
SRX   X, SRX, S, RX RS LOCK TABLE IN SHARE ROW EXCLUSIVE MODE
X X, SRX, S, RX, RS     LOCK TABLE IN EXCLUSIVE MODE
  RS RX S SRX X
RS          
RX          
S          
SRX          
X          
Legend:   - allowed
  - prevented

Transaction control

Transactions represent an atomic unit of work. All changes to data in a transaction are applied together or rolled back together.
Transaction control statements
Statement Description
COMMIT Ends the current transaction, making data changes permanent and visible to other sessions.
ROLLBACK Undoes all the data changes in the current transaction. Ends the transaction.
ROLLBACK TO SAVEPOINT   Undoes all data changes in the current transaction going chronologically backwards to the optionally named savepoint.
SET TRANSACTION Enables transaction or statement consistency; specifies named rollback segment for transaction use.
A transactions starts A transaction ends when

Oracle implements consistency (one of the key concepts underlying the use of the transaction control statements) to guarantee that the data seen by a statement or transaction does not change until that statement or transaction completes. This support is only important to multiuser databases, where one session can change and commit data that is being read by another session.

There are two levels of consistency:

Transaction level consistency can also be enabled for transactions that only read (do not modify) data. To set this level use
SET TRANSACTION READ ONLY;
Any attempt to change data during a read only transaction will result in an error message. Therefore, only the following statements can be used during such transactions: Note: to end a read-only transaction we must use either COMMIT or ROLLBACK statements.

Using the SET TRANSACTION statement we can also select a particular roll back segment to use for it. The syntax of the corresponding statement is

SET TRANSACTION USE ROLLBACK SEGMENT segment_name;