MYSQL-TOOLS

Comparison of graphical tools for MySQL

Home Inserting, Updating and Deleting Records in MySQL

Inserting, Updating and Deleting Records in MySQL

In this lesson of the MySQL tutorial, you will learn...
  1. To insert records into a table.
  2. To replace records in a table.
  3. To insert records, managing duplicates.
  4. To update records in a table.
  5. To delete records from a table.
  6. To delete records using join conditions.
  7. To delete records from joined tables.
  8. To truncate a table.
  9. To use joins with updates.
  10. To use joins with deletes.

In this lesson of the MySQL tutorial, we will cover MySQL mechanisms to input data into the databases, and update or delete the data as need be.



Inserting Data in a MySQL Database

Print PDF

Once tables have been created, the database sits like an empty container. To initially fill this database container with data, we need to use INSERT statements to add data in a MySQL database.

To insert a record into a table, you must specify values for all fields that do not have default values and cannot be NULL.

Syntax
INSERT INTO table
(columns)
VALUES (values);

The second line of the above statement can be excluded if all required columns are inserted and the values are listed in the same order as the columns in the table. We recommend you include the second line all the time though as the code will be easier to read and update and less likely to break as the database is modified.

Code Sample:

INSERT INTO studio VALUES (101,'Big-Banner Studios');
Code Explanation

This statement starts with the mandatory keyword INSERT, optional INTO, and the name of the table studio. The VALUES clause includes a value for each of the two columns in studio, in the same order as the columns show up in table definition. The values are enclosed in parentheses and separated with commas.

If the INSERT is successful, the output will read something to this effect:

(1 row(s) affected)

Tip:As the studio_id column is set to AUTO_INCREMENT, a column value for studio_id can be supplied as NULL, and a next incremented value is automatically set on studio_id when a row is added to the table.

Using an INSERT statement, individual or multiple rows are added to a single table on a row-by-row basis, specifying one value per column. If there are fewer values than there are columns, NULL or DEFAULT values are substituted for missing values.

Syntax
<insert statement>::=
INSERT [IGNORE] [INTO]
{<values option> | <set option> | <select option>}
 
<values option>::=
<table name> [(<column name> [{, <column name>}...])]
VALUES ({<expression> | DEFAULT} [{, {<expression> | DEFAULT}}...])
[{, ({<expression> | DEFAULT} [{, {<expression> | DEFAULT}}...])}...]
 
<set option>::=
<table name>
SET <column name>={<expression> | DEFAULT}
[{, <column name>={<expression> | DEFAULT}}...]
 
<select option>::=
<table name> [(<column name> [{, <column name>}...])]
<select statement>

The IGNORE option is used when adding multiple rows where rows with duplicate primary or unique keys are ignored. The remaining rows get added instead of having the whole insert statement aborted.

The remaining part of the syntax defines an INSERT alternative. A number of elements are common to all three statement options. The - <expression> place-holder - is of particular importance and is discussed later.

<VALUES option> of INSERT

Using VALUES clause, one can add one or more rows to a table.

As seen in the simple example earlier, the table name and (optional) column names is followed by a VALUES clause, containing at least one <expression> or a DEFAULT keyword. If column names were specified after table name, the VALUES clause must include a value for each column, in the order that the columns are listed.

If column names are not used, one must supply a value for every column in the table.

Tip: Use DESCRIBE statement to display a list of the columns names, covered in a prior lesson.

The following example uses actual column names to put values into, avoiding any confusion or ambiguity:

Code Sample:

INSERT LOW_PRIORITY INTO film_review (review_id,
film_id, review_by, review_category, review_text, review_date)
VALUES (NULL, 998, 'Film Press', 'PROF', 'C\'est La Vie', '20070605');
Code Explanation

This statement inserts a film_review row with giving all columns.

The statement below specifies only three of the column values for a review, default values are inserted for rest of the columns.

Code Sample:

INSERT INTO film_review (film_id, review_text, review_date)
VALUES (998,'C\'est La Vie','2007-06-05');
Code Explanation

This statement inserts a row with giving just three columns.

Note: If a column remains unspecified in an INSERT statement, the default value for that column is inserted in the column. For example, if review_category column was not specified, DEFAULT value of PUBLIC is used.

Tip: A backslash in a String such as review_text value indicates the text following backslash - a quote - is part of the value and not the ending quote of the string. The backslash is used for any characters that have a special meaning in a string, such as double quotes (\"), a backslash (\\), a percentage sign (\%) or an underscore (\_).

Add Multiple Rows

The next example adds multiple rows to studio at the same time.

Code Sample:

<cw:File xmlns:cw="http://www.webucator.com/Schemas/Courseware" xmlns:
xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http:
//www.webucator.com/Schemas/Courseware http://www.webucatormanuals.com/
WCWC/Authoring/ExternalFile.xsd"><![CDATA[
INSERT INTO studio (studio_id,studio_name)
VALUES (1,'Paramount Pictures'),
(2,'Sony Pictures'),
(3,'MGM Studios');
Code Explanation

Tip:The values for studio_id are explicitly specified here, so no AUTO_INCREMENT values are used. This technique is usually used to preload a table with pre-determined ID values where pre-determined ID values are actively used for searching. It may be best not to use AUTO_INCREMENT and set known values into the ID field oneself. One can set the AUTO_INCREMENT to a high value for any future dynamic values.

Maintaining Relationships

Table relationships defined via foreign keys affect addition of data via inserts. For example, in a default configuration of a foreign key, we will receive an error while adding a row to a child table if the referencing column of the inserted row contains a value that does not exist in the referenced column of the parent table. Relationship and Foreign keys are covered in another lesson.

<set option> Alternative of INSERT

The <set option> in an INSERT statement allows for direct pairing of columns and expressions being set into the columns. This prevents any column ordering issues and provides an explicit assignment, hence correctness without having to refer back and forth between column list and VALUES clause.

The <set option> alternative is very helpful when only selected columns are receiving values and defaults are used for the rest.

The INSERT statement below uses a SET clause where for each value, we give the column name, an equal (=) sign, and an expression or the DEFAULT keyword. The <expression> option and the DEFAULT keyword work same as previous INSERT statement.

Code Sample:

INSERT INTO film_review SET
review_id=NULL,
film_id=999,
review_by='Film Press',
review_text='Movie of the year',
review_date='2007-07-02',
review_category=DEFAULT;

Limitation: The <SET option> alternative does not allow us to insert multiple rows with one statement as in <VALUES option>.

MySQL supports both INSERT and REPLACE statements to add values to a table. In addition, MySQL also supports copying or importing data, explained in in another lesson.

Using REPLACE Statement to Add Data

A REPLACE statement can be used similar to INSERT statement. The main difference between the two is in how values in a primary key column or a unique index are treated. INSERT statement throws an error out for unique values that already exists in the table. A REPLACE statement however deletes the old row and adds the new row.

Code Sample:

<cw:File xmlns:cw="http://www.webucator.com/Schemas/Courseware" xmlns:xsi="http://
www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.webucator.com/
Schemas/Courseware http://www.webucatormanuals.com/WCWC/Authoring/ExternalFile.xsd">
<![CDATA[REPLACE INTO studio
VALUES (5, 'Grand Stand Studios');
Code Explanation

A successful run will simply add the row outputting something like:

Query OK, 1 row affected (0.00 sec)

If you run this script again, the output will (strangely) look like :

Query OK, 2 rows affected (0.00 sec)

What happened here? How did we affect 2 rows for the same key?

Note: The reason we see 2 rows affected is that on the second run, the studio_id was already present in the table. So it was first deleted and subsequently added again, thus affecting 2 rows.

Warning: Use caution executing a REPLACE statement, as we risk overwriting important data without any meaningful indication.

Code Sample:

INSERT INTO film_review (film_id, review_by, review_text, review_date)
VALUES (997, 'Cynic!', 'OK Movie', SUBDATE(now(), INTERVAL 10 DAY));
REPLACE INTO film_review (review_id, film_id, review_by, review_text, review_date)
VALUES (10, 997, 'Nice', 'Good Movie', SUBDATE(now(), INTERVAL 10 DAY));
REPLACE INTO film_review (review_id, film_id, review_by, review_text, review_date)
VALUES (10, 997, 'NotSoNice', 'Bad Movie', now());
Code Explanation

This script contains a mix of Insert and Replace statements. The first Insert simply adds a row. The following first REPLACE will actually INSERT a row, and the second REPLACE will overwrite it, again showing 2 rows affected.

We can use SET clause in REPLACE statement as well.

Code Sample:

REPLACE INTO film_review SET
review_id=12,
film_id=997,
review_by='Film Press',
review_text='Movie of the year (to avoid)',
review_date='2007-06-02',
review_category='PROF';
Code Explanation

The REPLACE using SET clause will insert or overwrite a review for given review_id, showing 1 or 2 rows affected as is the case.

INSERT with ON DUPLICATE KEY UPDATE Syntax

The ON DUPLICATE KEY UPDATE clause of INSERT has a REPLACE like effect where if a row is inserted that would cause a duplicate value in a UNIQUE index or PRIMARY KEY, an UPDATE of the old row is performed instead.

Similar to a REPLACE statement, using ON DUPLICATE KEY UPDATE causes the affected-rows value per row to be 1 if the row is inserted as a new row or 2 if an existing row is updated.

The next INSERT example updates instead of adding rows if the key exists.

Code Sample:

INSERT INTO availability (film_id,in_stock)
SELECT film_id,1 FROM inventory
ON DUPLICATE KEY UPDATE in_stock=in_stock+1;
Code Explanation

The film_id column is not unique in inventory, but is unique (PK) in availability table. Hence as rows are selected from inventory to be inserted into availability, we will start hitting duplicates at some point. Using ON DUPLICATE KEY UPDATE, the in_stock count will be simply incremented by 1 on duplicates, as intended.

Updating Data in MySQL

The primary statement used to modify existing data in a SQL database is an UPDATE statement, though REPLACE above is a viable option. The UPDATE statement lets us modify one or more fields for one or more records in a table. Here is the basic syntax for the statement.

Syntax
UPDATE table
SET field = value
[,field = value]
[WHERE conditions];

UPDATE is followed by a table name and a SET clause with pairs of column names and associated expressions that are being assigned to the column. The WHERE clause - with one or more conditions - to specify which rows in a table are updated, and is discussed more in the SELECT Statement lessons.

Warning: Even with security and tight application controls, it is quite easy to update considerable amount of data with just a single statement. Exercise extreme caution not to update more records than you intend to!.

Code Sample:

UPDATE film_review SET
film_id=997,
review_by='Film Press',
review_text='Movie of the year (to avoid)',
review_date='2007-06-02',
review_category='PROF'
WHERE review_id=12;
Code Explanation

If the UPDATE is successful, the output will read something like:

(1 row(s) affected)

The UPDATE statement here is intended to look like the previous REPLACE using SET to show the similarity between the two. Only in case of UPDATE, no row is added if one did not exist.

ORDER BY and LIMIT Clauses in UPDATE

MySQL allows for for a slightly advanced version of UPDATE as shown:

Syntax
UPDATE <table name> SET ... [WHERE ...]
[ORDER BY <column name> [ASC | DESC] [{, <column name > [ASC | DESC]}...]]
[LIMIT <row count>]

The optional clause of ORDER BY clause decides which rows get UPDATEed first, versus whatever is the default order of data returned in MySQL.

The LIMIT clause limits the count of rows updated and it is best to use LIMIT along with with an ORDER By clause, which provides some control over what rows get returned.

Here is an example to show the use of LIMIT clause:

Code Sample:

UPDATE film_reserve
SET customer_id = 1
WHERE customer_id IS NULL
LIMIT 5;

Code Explanation

A customer with ID=1 wants to reserve any 5 movies that are not already reserved:

Note: One can use expressions as column values for both Updates and Inserts. In many of the tables, the last NULL value is for the updated_on column is configured as a TIMESTAMP, and the current date-time is set automatically in that column.

Tip: Use NOW() function for current date and time, covered in another lesson.

Using DELETE Statement in MySQL

There are times when some data is not needed any longer and may even pose problems by remaining in the database. To discard unwanted data from a database, we will use DELETE statement, that allows you to delete one or more records in a table:

Syntax
DELETE FROM <table-name>
WHERE <conditions>;

As the syntax above shows, the DELETE statement requires a FROM table and we can add a WHERE clause to restrict rows to be deleted.

Warning: As with UPDATE, we must be very careful to limit deletes to intended records only.

Code Sample:

DELETE FROM rental WHERE customer_id = 9190;
Code Explanation

While deleting rentals, we use WHERE clause to restrict deletes only for Customer with ID of 9190:

If a matching row is found to DELETE, the output will read like:

(1 row(s) affected)

Here is a more detailed syntax for DELETE with some MySQL extensions:

Syntax
DELETE [IGNORE] [LOW_PRIORITY] [QUICK]
FROM <table name>
[WHERE <where definition>]
[ORDER BY <column name> [ASC | DESC] [{, <column name> [ASC | DESC]}...]]
[LIMIT <row count>]

Some Advanced MySQL modifiers to DELETE statement

Using the LOW_PRIORITY option, the DELETE statement does not execute until various client connections are done accessing the target table. This affects only storage engines that use only table-level locking such as MyISAM.

Using IGNORE option, any delete errors are replaced with warnings when deleting rows, allowing the rest of the statements in the script to execute.

For MyISAM tables, the use of the QUICK keyword may speed up some delete operations, as the storage engine does not merge index leaves during delete.

One can also use an ORDER BY to sort which rows get deleted first, and a LIMIT clause to limit deletes to number of rows specified.

ORDER BY and LIMIT in DELETE Statement

As with updates before, DELETE statement can be further qualified by using an ORDER BY and a LIMIT clause, as shown with the reservations example below:

Code Sample:

DELETE FROM film_reserve
WHERE customer_id = 1
ORDER BY reserve_date ASC
LIMIT 5;
Code Explanation

If the UPDATE is successful, the output will read something like:

(1 row(s) affected)
Code Explanation

A customer has made too many reservations, and has asked to reduce their reservations by 5. The reservations for given customer are sorted in ascending order of Reservation Date, so 5 oldest reservations are deleted first. The LIMIT clause restricts the deletion to only five or less rows.

The number of rows affected will depend on the amount of data present in the film_reserve table.

Using TRUNCATE Statement to Delete Data

The TRUNCATE statement cleans up a table by removing all rows, and no qualification or filteration can be specified.

Code Sample:

TRUNCATE TABLE film_review;
-- same as
-- DELETE FROM film_review;
Code Explanation

If the UPDATE is successful, the output will read something like:

(1 row(s) affected)
Code Explanation

The TRUNCATE here unconditionally deletes all data from the film_review table, with same effect as DELETEing, but with no possible recovery.

Note:The key difference with TRUNCATE statement is that it is not transaction safe. Also, the TRUNCATE statement starts the AUTO_INCREMENT counts of that table all over again, whereas the DELETE statement leaves those counts as is.

One key benefit of using TRUNCATE is speed, as it runs much faster than a DELETE for large tables. Typically, TRUNCATE is used in seasonal tables, or during reload processes.

Joining Tables in an UPDATE Statement

MySQL also offers the <joined table update> alternative as shown. The join is based on the foreign key relationship established between joined tables.

MySQL allows you to use any join definition in your UPDATE statement. JOINs are discussed further in another lesson. To reflect the ability to use different types of join definitions, the syntax for the UPDATE statement is shown to use join definitions:

The syntax here shows only those components relevant to a multiple-table update. The original syntax uses a basic join for updating data from one table into another.

Syntax
UPDATE [LOW_PRIORITY] [IGNORE]
<join definition>
SET <column name>=<expression> [{, <column name>=<expression>}...]
[WHERE <where definition>]

Warning:Joined Update alternative does not allow you an ORDER BY or a LIMIT clause.

Code Sample:

UPDATE film_detail d
SET d.in_stock = (SELECT COUNT(1) FROM inventory i WHERE d.film_id = i.film_id);

-- Count where we have films in Stock
select count(1) from availability where in_stock > 0;

-- Count where there are no films in Stock
select count(1) from availability where in_stock = 0;

-- Update availability
UPDATE film_detail a JOIN inventory i USING (film_id) JOIN rental r USING (inventory_id)
SET a.avail_count = a.avail_count + 1
WHERE r.return_date IS NOT NULL;
Code Explanation

The in_stock in film_detail table is updated from the inventory table.

The UPDATE clause includes two tables as a join. Only the film_detail table is being updated. The in_stock column being updated is qualified with a table alias. The join is actually specified in the WHERE clause.

Two SELECT statements are used to demonstrate the counts for films where we have and do not have stock.

Note:A qualified column name is preceded by the name or the alias of the table and a period.

Updating Multiple Tables using Joins

We can update more than one value in joined tables. Here is an example:

Code Sample:

UPDATE rental_detail, customer_detail
SET rental_detail.return_date = NOW(),
customer_detail.payment = customer_detail.payment + @rental_rate
WHERE rental_detail.customer_id = customer_detail.customer_id
AND rental_detail.rental_id = @rental_id
AND rental_detail.return_date IS NULL
;
Code Explanation

Update both rental_detail and customer_detail tables.

For the given rental, payment in customer_detail is increased and return_date in rental_detail is updated with current date.

In other words, we are able to update both tables participating in the join condition.

It is possible to different joins in the UPDATE clause. For example, the following statement uses a CROSS join:

Code Sample:

UPDATE availability a 
CROSS JOIN inventory i USING (film_id)
CROSS JOIN rental r USING (inventory_id)
SET a.avail_count = a.avail_count + 1
WHERE r.return_date IS NOT NULL;
Code Explanation

The avail_count in availability table is updated from the inventory and rental tables.

Two cross joins are now used in the UPDATE clause USING common joining column names.

Note:MySQL product documentation recommends against performing multiple-table updates against InnoDB tables joined through foreign key constraints because you cannot always predict how the join optimizer might process tables. If an update is not performed in the correct order, the statement could fail. For InnoDB tables, it is generally recommended that you rely on the ON UPDATE options provided by InnoDB tables to modify the data.

Here is an example to show use of ORDER BY and LIMIT clauses in an UPDATE statement:

Code Sample:

UPDATE film_reserve fr, film_detail f
SET customer_id = 1
WHERE customer_id IS NULL
AND f.category_name = 'Children'
AND fr.film_id = f.film_id
ORDER BY f.release_year DESC
LIMIT 5;
Code Explanation

If the UPDATE is successful, the output will read something like:

(1 row(s) affected)
Code Explanation

A customer has made too many reservations, and has asked to reduce their reservations by 5. The reservations for given customer are sorted in ascending order of Reservation Date, so 5 oldest reservations are deleted first. The LIMIT clause restricts the deletion to only five or less rows.

The number of rows affected will depend on the amount of data present in the film_reserve table.

As another example, a customer wants to reserve any 5 available Sedans of latest model years:

UPDATE CarsInventory
SET CarReserved = @CustomerID
WHERE TypeID = 'SEDAN'
AND CarReserved IS NULL
AND ModelYear > 2005
ORDER BY ModelYear DESC
LIMIT 5;

Joining Tables in a DELETE Statement

The DELETE statement provides two additional alternatives for deleting data from or using a joined table.

The <from join delete> method filters rows to be deleted using joined tables as specified in the FROM clause. The <using join delete> method uses joined tables as specified in the USING clause.

We can define a join condition in a DELETE statement, and can use any of the join definitions as in the SELECT statement. The modified syntax for the DELETE statement to support join definitions is shown below:

Syntax
<delete statement>::=
DELETE
<table name>[.*] [{, <table name>[.*]}...]
FROM <join definition>
[WHERE <where definition>]

DELETE
FROM <table name>[.*] [{, <table name>[.*]}...]
USING <join definition>
[WHERE <where definition>]

Warning: Using a DELETE statement to remove data from joined InnoDB tables is not recommended. It may be better to use the ON DELETE and ON CASCADE options specified in the foreign key constraints of the table definitions.

<FROM JOIN DELETE> Alternative

One can specify multiple tables in the DELETE clause and in the FROM clause.

  • Tables specified in the DELETE clause are the tables from which data will be removed.
  • Tables specified in the FROM clause are those tables that participate in the join.

Using tables in two separate clauses means a join that can contain more tables than the number of tables from which data is actually deleted.

If we want to delete all reviews for film with title ACADEMY DINOSAUR:

Code Sample:

DELETE r.*
FROM film_review r, film f
WHERE r.film_id = f.film_id
AND f.title = 'ACADEMY DINOSAUR';
Code Explanation

We delete reviews joining with film and using a column of the film table to filter the deletes.

If a matching row is found to DELETE, the output will read like:

(1 row(s) affected)

Warning: Deleting data from joined InnoDB tables is normally not recommended.

<using join delete> Clause

In the <using join delete> alternative, the tables from which data is deleted are specified in the FROM clause, as opposed to the DELETE clause, and the tables that are to be joined are specified in the USING clause, as opposed to the FROM clause.

Code Sample:

DELETE FROM r
USING film_review r, film f
WHERE r.film_id = f.film_id
AND f.title = 'ACADEMY DINOSAUR';
Code Explanation

The previous DELETE statement has be rewritten using the <using join delete> alternative. We have the film_review and film tables in the USING clause.

Deleting from multiple tables

You can also delete rows from multiple tables, as shown in the following example:

Code Sample:

START TRANSACTION;
DELETE r, i
FROM rental AS r, inventory AS i, film AS f
WHERE f.film_id = i.film_id
AND r.inventory_id = i.inventory_id
AND f.title = 'ACADEMY DINOSAUR';
ROLLBACK;

Code Explanation

The entire inventory and rental history of a given film needs to be deleted, hence requires deleting data from two different tables - rental and inventory -. This could be easily broken down into two separate statements.

In this case, a basic join is created on the film, rental and inventory tables. The joins are specified as conditions in the WHERE clause. A filter condition that restricts the rows being deleted to a given film title, else this DELETE could be a catastrophe !

You can rewrite this statement to use inner joins as shown:

Code Sample:

START TRANSACTION;
DELETE r, i
FROM rental AS r INNER JOIN inventory AS i ON r.inventory_id = i.inventory_id
INNER JOIN film AS f ON f.film_id = i.film_id
AND f.title = 'ACADEMY DINOSAUR';
ROLLBACK;
Code Explanation

The join conditions are now specified using the ON clause of the specific inner join, while the WHERE clause contains the filter conditions.

Warning: MySQL product documentation recommends against performing multiple-table deletions against InnoDB tables that are joined through foreign key constraints because you cannot always predict how the join optimizer might process tables. If an update is not performed in the correct order, the statement could fail. For InnoDB tables, it is generally recommended that you rely on the ON UPDATE options provided by InnoDB tables to modify the data.

Tip: In addition to joining tables, MySQL also supports the use of subqueries in SQL statements.

Inserting, Updating and Deleting Records in MySQL Conclusion

In this lesson of the MySQL tutorial, you have learned how to insert and replace rows into a MySQL database. Remember to be careful with REPLACE. You may overwrite important data.

In this lesson of the MySQL tutorial, you have learned how to insert, update, and delete records. Remember to be careful with updates and deletes. If you forget or mistype the WHERE clause, you could lose a lot of data.

We also learned how to remove rows from a MySQL database using DELETE and TRUNCATE statements, with JOIN possibilities. Remember to be careful with updates and deletes. If you forget or mistype the WHERE clause, you could mess up or lose a lot of data.

To continue to learn MySQL go to the top of this page and click on the next lesson in this MySQL Tutorial's Table of Contents.
 


mysql tools