5.
Inserting, Deleting, and Updating Data

In this chapter, we will look at how to insert and change data in your MySQL database with the INSERT, DELETE, and UPDATE statements.

We will cover the following:

• Using INSERT

• Using DELETE

• Using UPDATE

• Uploading data with LOAD DATA INFILE

• Extensions: REPLACE and TRUNCATE

We have now moved into the DML (Data Manipulation Language) aspects of SQL. After we have learned how to insert data into a database, we will spend the next few chapters learning the many and varied ways to retrieve data from a database.

Using INSERT

The INSERT SQL statement is used to insert rows into a table. We'll begin by looking at an example. Again, you can type these statements directly into the MySQL monitor or into a file, or you can download this file from the book's Web site.

Some sample insert statements are shown in Listing 5.1.

Listing 5.1. employee_data.sql


use employee;

delete from department;
insert into department values
(42, 'Finance'),
(128, 'Research and Development'),
(NULL, 'Human Resources'),
(NULL, 'Marketing'),

delete from employee;
insert into employee values
(7513,'Nora Edwards','Programmer',128),
(9842, 'Ben Smith', 'DBA', 42),
(6651, 'Ajay Patel', 'Programmer', 128),
(9006, 'Candy Burnett', 'Systems Administrator', 128);

delete from employeeSkills;
insert into employeeSkills values
(7513, 'C'),
(7513, 'Perl'),
(7513, 'Java'),
(9842, 'DB2'),
(6651, 'VB'),
(6651, 'Java'), 
(9006, 'NT'),
(9006, 'Linux'),

delete from client;
insert into client values
(NULL, 'Telco Inc', '1 Collins St Melbourne',  'Fred Smith', '95551234'),
(NULL, 'The Bank', '100 Bourke St Melbourne',  'Jan Tristan', '95559876'),

delete from assignment;
insert into assignment values
(1, 7513, '2003-01-20', 8.5); 


You'll see that before we insert any data into each table, we are running a DELETE statement—again, this isn't necessary, but it will clean out any test data that you may have inserted so far. We'll come back to the DELETE statement in the next section.

Also note that we have inserted the sample data to match the examples in Chapter 3, “Database Design Crash Course.” We have added some additional rows as well.

All of these INSERT statements are pretty similar. Let's look at the first one to see how it works:


insert into department values
(42, 'Finance'),
(128, 'Research and Development'),
(NULL, 'Human Resources'),
(NULL, 'Marketing'),


We specify the table that we want to insert data into on the first line—in this case, department. Here, we are inserting four rows into the table. You may recall that the department table has two columns, departmentID and name. (You can check this for yourself by running a describe department command.)

In the first two rows, we have specified the departmentID that we want to use. Let's look back at the definition of departmentID. You may recall that in the last chapter, we declared it as


departmentID int not null auto_increment primary key


Because this is an auto_increment column, we can specify the value or let MySQL calculate it for us. (Usually, in this case, we would let MySQL allocate a number, but there may be cases like this one in which we have an existing number we want to use.)

In the rows for Human Resources and Marketing, you will see that we have left the departmentID as NULL. This will allow the auto_increment to do its magic and allocate a value. Let's see what we get from this INSERT statement.

If you look through the various INSERT statements, you will see that when we insert data into a string or date type, we enclose it in single quotes, for example, 'Research and Development'. When it is a numerical type, you should not use quotes.

If we are enclosing data in quotes, what do we do when the data contains quotes? The answer is that we need to escape the quotes. In simple terms, we need to put a backslash () in front of the single quote, for example, 'O'Leary'.

Obviously, this brings up the question, “What do we do if we want a backslash to be just a backslash, without any special meaning?” In this case, we need to escape the backslash in the same way—replace the backslash with two backslashes (\).

We retrieve data from the database using the SELECT statement. We will cover SELECT fairly exhaustively in the next few chapters. For the moment, we only need to know that typing


select * from tablename;


will return all the data currently stored in a table.

If you type


select * from department;


you should get output similar to the following:

image

4 rows in set (0.01 sec)

You should be able to see that the effect of auto_increment is a value which is one greater than the highest current value in the column.

The general form of the INSERT statement from the MySQL manual is as follows:


    INSERT [LOW_PRIORITY | DELAYED] [IGNORE]
        [INTO] tbl_name [(col_name,...)]
        VALUES ((expression | DEFAULT),...),(...),...
        [ ON DUPLICATE KEY UPDATE col_name=expression, ... ]

or  INSERT [LOW_PRIORITY | DELAYED] [IGNORE]
        [INTO] tbl_name [(col_name,...)]
        SELECT ...

or  INSERT [LOW_PRIORITY | DELAYED] [IGNORE]
        [INTO] tbl_name
        SET col_name=(expression | DEFAULT), ...
        [ ON DUPLICATE KEY UPDATE col_name=expression, ... ]


The examples we have looked at all follow the first form of the expression. You will note that the keyword INTO is optional. We could leave it out and begin our query with insert employee values, but we find it a little harder to read.

With this first form, we need to list values for each column value in each row in the same order as the columns are in the table. For example, we had to specify the departmentID first, followed by the name, because that's the way the department table is structured. As demonstrated, this form allows us to insert multiple rows in a table with a single INSERT statement.

The second form ends in a SELECT statement. Rather than inserting values manually, this allows us to retrieve data from another table or tables in the database and store it in this table.

The third form allows us to specify which columns data should be inserted into. An example of using INSERT in this way is


insert into department
set name='Asset Management';


This form only allows you to insert a single row at a time, but you don't need to specify values for all the columns. In this case, we are setting a value for only the name. All the unspecified values will either take their default value, if one is specified, or be NULL. In this case, departmentID will be set to NULL, which causes the auto_increment to work its magic and generate a new departmentID for us. (You can check this by typing select * from department again.)

There are a couple of optional clauses in the INSERT statement. Let's briefly go through what these do:

• We can specify that an INSERT should be LOW PRIORITY or DELAYED. Both of these clauses will cause the insertion to be delayed until no client is trying to read from the table. The difference between them is that LOW PRIORITY will block the inserting client and DELAYED will not. What this means is that if you run a LOW PRIORITY insert, you may wait for some time before you can continue running queries in your client. With DELAYED, you will be told OK and can continue running queries, but you need to remember that the insert will not be performed until the table is not in use.

• Specifying IGNORE is chiefly useful when you are inserting multiple rows. Normally, if one of the rows you are trying to insert clashes with an existing row's PRIMARY KEY or UNIQUE value, an error will occur and the insert will be aborted. If you specify IGNORE, the error will be ignored and the insert will continue and will attempt to insert the next row.

• We can specify that a column should contain its default value by specifying DEFAULT as the value for that column.

• The ON DUPLICATE KEY UPDATE clause allows us to deal elegantly with clashing primary key or unique values. We follow this clause with an update statement that we can use to change the primary key or unique value in the row already in the table so that it no longer clashes with the new row.

The following short example demonstrates a common style of use for the ON DUPLICATE KEY UPDATE clause:


create table warning
(
  employeeID int primary key not null references employee(employeeID),
  count int default 1
) type =InnoDB;

insert into warning (employeeID)
  values (6651)
  on duplicate key update count=count+1;


This clause is very useful for situations in which you want to not only record unique events, but also take some action, such as incrementing a counter when non-unique events occur. Any sort of logging would be a good example, but in keeping with the employee database we have been using, we will record employees who have been given a warning in the table warning.

To record somebody's warning, we run this insert statement. Because count has a default value of 1 and we are not specifying a value in the insert, it will be 1 the first time the insert is done for each employeeID. Subsequent inserts with the same employeeID will trigger the ON DUPLICATE KEY UPDATE clause and will increment the counter.

Using REPLACE

The REPLACE statement is exactly like the INSERT statement except that if a key clash occurs, the new row you are inserting will replace the old row.

This is the general form of REPLACE from the MySQL manual:


REPLACE [LOW_PRIORITY | DELAYED]
        [INTO] tbl_name [(col_name,...)]
        VALUES (expression,...),(...),...

or  REPLACE [LOW_PRIORITY | DELAYED]
        [INTO] tbl_name [(col_name,...)]
        SELECT ...

or  REPLACE [LOW_PRIORITY | DELAYED]
        [INTO] tbl_name
        SET col_name=expression, col_name=expression,...


The similarity to INSERT should be obvious.

Using DELETE

The DELETE SQL statement allows us to delete rows from a table. There are some delete statements in Listing 5.1, for example,


delete from department;


In this form, the delete statement will delete all the rows from the department table.

We can also limit which rows are deleted using a WHERE clause, for example,


delete from department where name='Asset Management';


This will only delete the rows matching the criteria in the where clause. In this case, only rows in which the department name is 'Asset Management' will be deleted.

It is unusual to want to delete all the rows from a table. However, because this is the shortest form of the delete statement, you may sometimes type it by accident without a WHERE clause. You can save yourself this anguish by switching on the -–safe-updates or –-iam-a-dummy command-line options of the mysql client as discussed in Chapter 2, “Quick Tour.” These options prevent you from deleting (or updating) rows without specifying a key constraint in the WHERE clause. That is, you need to specify that you want to delete only rows containing certain key values.

This is the general form of the DELETE statement from the MySQL manual:


DELETE [LOW_PRIORITY] [QUICK] FROM table_name
       [WHERE where_definition]
       [ORDER BY ...]
       [LIMIT rows]


or

DELETE [LOW_PRIORITY] [QUICK] table_name[.*] [, table_name[.*] ...]
       FROM table-references
       [WHERE where_definition]

or

DELETE [LOW_PRIORITY] [QUICK]
       FROM table_name[.*] [, table_name[.*] ...]
       USING table-references
       [WHERE where_definition]


The first form is the one we have seen examples of so far.

The other two forms are designed to allow us to delete rows from one or more tables with references to other tables. For example:


delete employee, employeeSkills
from employee, employeeSkills, department
where employee.employeeID = employeeSkills.employeeID
and employee.departmentID = department.departmentID
and department.name='Finance';


This example deletes all the employees who work for the Finance department and erases all records of their skills. Note that rows are deleted from employee and employeeSkills (the tables listed in the initial where clause), but not department (because it is listed only in the from clause).

The tables in the initial delete clause will have rows deleted from them, whereas the tables listed in the from clause are used for searching for data and will not have rows deleted unless they are also listed in the delete clause.

Note that this is quite a complex example because it involves three tables! We need three tables to illustrate this example, but we suggest that you come back and review the WHERE clause after reading about joins in Chapter 7, “Advanced Queries.”

We have used a couple of new things in this where clause: the AND operator and the table.column notation. We have used AND to join our conditions together. This is a simple Boolean AND. We have also used the notation employee.employeeID. This notation means “the employeeID column of the employee table.” We will revisit both of these things in more detail in the next two chapters.

The third form of DELETE is similar to the second form, except that, in this case, we delete only from the tables listed in the FROM clause while referring to the tables in the USING clause. For example:


delete from employee, employeeSkills
using employee, employeeSkills, department
where employee.employeeID = employeeSkills.employeeID
and employee.departmentID = department.departmentID
and department.name='Finance';


This is equivalent to the preceding example, except that it uses an alternative syntax.

There are a couple of other optional clauses in the general form of the DELETE statement:

• The LOW_PRIORITY clause works in the same way as it does in the INSERT statement.

• Specifying QUICK may speed up the DELETE statement by telling MySQL not to do some of its housekeeping on indexes while deleting from the table.

• The ORDER BY clause specifies the order in which to delete rows. This is most useful in conjunction with the LIMIT clause—we may want to delete the oldest n rows from a table, for example.

• The LIMIT clause allows us to set a maximum number of rows that can be deleted by the DELETE statement. This is useful either in conjunction with the ORDER BY clause or to save us from accidentally deleting too many rows.

Using TRUNCATE

The TRUNCATE statement allows us to delete all the rows from a table. For example:


TRUNCATE TABLE employee;


This query would delete all the employees from the employee table. This is faster than a DELETE statement because it works by dropping the table and re-creating it empty. One thing to bear in mind is that TRUNCATE is not transaction safe.

Using UPDATE

We can use the UPDATE SQL statement to change rows already stored in the database. For example, imagine that one of our employees changes jobs:


update employee
set job='DBA'
where employeeID='6651';


This statement changes the value of the job column for employee number 6651.

The general form of the UPDATE statement from the MySQL manual is as follows:


UPDATE [LOW_PRIORITY] [IGNORE] tbl_name
    SET col_name1=expr1 [, col_name2=expr2 ...]
    [WHERE where_definition]
    [ORDER BY ...]
    [LIMIT rows]

or

UPDATE [LOW_PRIORITY] [IGNORE] tbl_name [, tbl_name ...]
    SET col_name1=expr1 [, col_name2=expr2 ...]
    [WHERE where_definition]


The UPDATE statement is similar in many respects to the DELETE statement.

We can use an optional WHERE clause to update particular rows or leave it off to update all rows. Again, you can fall into the trap of forgetting to specify a WHERE clause—I remember one project when a foolish colleague typed something along these lines:


update user
set password='test';


This again highlights the usefulness of the --i-am-a-dummy mysql option, particularly if you are forced to work with dummies.

The second version of the UPDATE statement listed previously is a multi-table update. This works similarly to the multi-table deletes we looked at before. Note that only the columns you specifically list in the SET clause will be updated.

We have seen all the other clauses of the UPDATE statement before. The LOW_PRIORITY and IGNORE clauses work the same way as they do in INSERT. The ORDER BY and LIMIT clauses work the same way they do in DELETE.

Uploading Data with LOAD DATA INFILE

The LOAD DATA INFILE command allows you to bulk insert data from a text file into a single table without having to write INSERT statements. For example, we could have loaded the data in the department table using this technique as follows. Listing 5.2 shows the contents of a data file containing department information.

Listing 5.2. department_infile.txt


42     Finance
128    Research and Development
NULL   Human Resources
NULL   Marketing


This file is in the default LOAD DATA INFILE format, with each row listed on a separate line with tabs between column values. (This is configurable and we will see how in a minute.)

We can load this information into the department table with the following LOAD DATA INFILE statement:


load data local infile 'department_infile.txt'
into table department;


This facility is particularly useful for converting data from another database format, spreadsheet, or CSV (comma-separated values) file.

The LOAD DATA INFILE statement requires the FILE privilege—see Chapter 11, “Managing User Privileges,” for further information, especially if you are having trouble running this command. The privilege to perform this is often restricted for good security reasons—to stop people from loading in /etc/passwd, for example.

The general form of the LOAD DATA INFILE statement is as follows:


LOAD DATA [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE 'fileName.txt'
    [REPLACE | IGNORE]
    INTO TABLE tbl_name
    [FIELDS
        [TERMINATED BY ' ']
        [[OPTIONALLY] ENCLOSED BY '']
        [ESCAPED BY '' ]
    ]
    [LINES TERMINATED BY ' ']
    [IGNORE number LINES]
    [(col_name,...)]


The optional clauses are as listed here:

• The LOW PRIORITY clause works the same way it does in the INSERT statement by waiting for other clients to stop reading from the table. CONCURRENT, on the other hand, allows other clients to read from the table while the bulk insert is going on.

• In our example, we specified the optional keyword LOCAL, meaning that the data file is on the client machine. If this is not specified, MySQL will look for the infile on the server.

• If you have key clashes while inserting data, REPLACE and IGNORE provide two methods for dealing with this. Specifying REPLACE tells MySQL to replace the old row with the new row, while IGNORE tells MySQL to keep the old row.

• The FIELDS and LINES clauses specify how the data in the infile is laid out. The values in the general form are the defaults—each row on a new line, column values separated by tabs. We can also enclose column values in quotes and use the backslash character to escape any special characters (like single quotes) that might confuse MySQL.

• The IGNORE number LINES clause tells MySQL to ignore the first number lines in the infile.

• The final clause allows you to specify that you only want to read data into some of the table's columns.

A common format to receive data in is CSV or comma-separated values. Many programs can read and write files of this type, but one notable example is Microsoft Excel. Listing 5.3 shows a small CSV file saved from Excel.

Listing 5.3. new_programmers.csv


Name, Job, DepartmentID

Julia Lenin, Programmer, 128
Douglas Smith, Programmer, 128
Tim O'Leary, Programmer, 128


We can load this data into the employee table with the following query:


load data infile 'e:\new_programmers.csv'
into table employee
fields terminated by ','
lines terminated by ' '
ignore 2 lines
(name, job, departmentID);


You can see that we have used more options to load this data than we did when the data was in the default format. A few points are worth noting:

• Because we have used a Windows/DOS-style path that includes a backslash, we need to escape the backslash. Our path therefore became 'e:\new_programmers.csv'.

• It possibly goes without saying that the fields in a CSV file are terminated by commas, but we need to specify it.

• We do not need to specify that lines are terminated by a newline character, but we have chosen to.

• This file has a header, so the first two lines do not contain data and should be ignored.

• The data in this file does not contain employeeIDs, so to allocate the three columns of data into the four columns in the database, we need to specify what columns (in order) the data will be mapped to. In this case, we have specified (name, job, departmentID).

Summary

In this chapter, we looked at ways to insert, delete, and update data from the tables in our database.

Inserting Data

• String values should be in quotes. Single quotes or backslashes within a string need to be escaped with a backslash.

• Add data to tables with the INSERT statement:


    INSERT [LOW_PRIORITY | DELAYED] [IGNORE]
        [INTO] tbl_name [(col_name,...)]
        VALUES ((expression | DEFAULT),...),(...),...
        [ ON DUPLICATE KEY UPDATE col_name=expression, ... ]

or  INSERT [LOW_PRIORITY | DELAYED] [IGNORE]
        [INTO] tbl_name [(col_name,...)]
        SELECT ...


or  INSERT [LOW_PRIORITY | DELAYED] [IGNORE]
        [INTO] tbl_name
        SET col_name=(expression | DEFAULT), ...
        [ ON DUPLICATE KEY UPDATE col_name=expression, ... ]


• The REPLACE statement is just like INSERT, but it overwrites rows where a key clash occurs. INSERT fails or triggers the ON DUPLICATE KEY UPDATE clause when a key clash occurs.

Deleting Data

• Avoid disasters with --i-am-a-dummy.

• Delete data from tables with the DELETE statement:


   DELETE [LOW_PRIORITY] [QUICK] FROM table_name
          [WHERE where_definition]
          [ORDER BY ...]
          [LIMIT rows]
or DELETE [LOW_PRIORITY] [QUICK] table_name[.*] [, table_name[.*] ...]
          FROM table-references
          [WHERE where_definition]
or DELETE [LOW_PRIORITY] [QUICK]
          FROM table_name[.*] [, table_name[.*] ...]
          USING table-references
          [WHERE where_definition]


• The TRUNCATE TABLE statement deletes all rows from a table.

Updating Data

• Update data in tables with the UPDATE TABLE statement:


   UPDATE [LOW_PRIORITY] [IGNORE] tbl_name
       SET col_name1=expr1 [, col_name2=expr2 ...]
       [WHERE where_definition]
       [ORDER BY ...]
       [LIMIT rows]
or UPDATE [LOW_PRIORITY] [IGNORE] tbl_name [, tbl_name ...]
       SET col_name1=expr1 [, col_name2=expr2 ...]
       [WHERE where_definition]


LOAD DATA INFILE

• Use LOAD DATA INFILE to load the contents of a text file into a table:


LOAD DATA [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE 'file_name.txt'
    [REPLACE | IGNORE]
    INTO TABLE tbl_name
    [FIELDS
        [TERMINATED BY ' ']
        [[OPTIONALLY] ENCLOSED BY '']
        [ESCAPED BY '\' ]
    ]
    [LINES TERMINATED BY ' ']
    [IGNORE number LINES]
    [(col_name,...)]


Quiz

1.

Which of the following statements will successfully insert a row into the employee table?

a)

insert into employee values
set employeeID=NULL, name='Laura Thomson',
job='Programmer', departmentID=128;


b)

insert employee values
(NULL, 'Laura Thomson', 'Programmer', 128);


c)

insert into employee values
(NULL, Laura Thomson, Programmer, 128);


d)

insert employee values
(NULL, 'Laura O'Leary', 'Programmer', 128);


2.

The REPLACE statement

a) is similar to INSERT except that where a key clash occurs, it will replace the old row with the new row

b) is similar to INSERT except that where a key clash occurs, it will keep the old row and discard the new row

c) is similar to UPDATE except that where a key clash occurs, it will replace the old row with the new row

d) is similar to UPDATE except that where a key clash occurs, it will keep the old row and discard the new row

3.

The --i-am-a-dummy startup option for the mysql client

a) prevents you from inserting any data

b) prevents you from updating data without specifying a key constraint

c) prevents you from deleting data without specifying a key constraint

d) both b) and c)

4.

By default, fields in data files for load data infile are separated by

a) commas

b) spaces

c) tabs

d) pipes

5.

The optional LOCAL clause in LOAD DATA INFILE

a) specifies that the client and server are running on the same machine

b) specifies that the data file is on the server

c) specifies that the data file is on the client

d) specifies that the server is running on the local host

Exercises

1.

Create a set of INSERT statements to place data in each table of your orders table.

2.

Delete the data from your tables.

3.

Write a data file containing the same data that you inserted in part 1 and load it into your orders database using LOAD DATA INFILE.

Answers

Quiz

1.

b

2.

a

3.

d

4.

c

5.

c

Exercises

There is no single “correct” answer for the exercises in this chapter. Just make sure that you can work through each of the exercises.

Next

In Chapter 6, “Querying MySQL,” we will begin looking at the workhorse of SQL: the SELECT statement, in all its many variations.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset