• Aucun résultat trouvé

Now that you’ve created some tables, you are ready to put data in them. Data is added to tables by way of the insertstatement, existing data is changed by way of the updatestatement, and data is removed by way of the deletestatement. The cus-tomer table created earlier for examples is used for discussing all these statements.

Before these statements are discussed, sequences are introduced. Sequences solve a fundamental problem—that of creating unique keys for your tables. But before you read about any of these topics, you need to learn about Oracle transactions.

When you add and modify data, you use the xsql:dmlaction. This action isn’t lim-ited to only one SQL statement the way that the xsql:selectaction is. Even though our examples here use one statement only, you can combine as many statements as you like between the beginand endstatements inside the xsql:dmlelement.

Transactions

A transaction is one or more SQL statements executing against the database. They are very important when you work with Data Manipulation Language (DML) statements because you often want all of the statements to succeed or fail as a group. A classic

example is a banking transaction in which $100 is transferred from a savings to a checking account. This transaction really involves three steps:

1. Subtract $100 from savings.

2. Add $100 to checking.

3. Record the transaction in the transaction log.

If any of the preceding statements fail individually, you will have problems. If the cus-tomer doesn’t have $100 in savings, you will hand him or her free money to put into their checking account. If a problem occurs in adding the money to checking, you will have an upset customer. If you can’t log the transaction, you will have bookkeeping problems in the future.

Oracle addresses this problem with the commit, rollback, and savepoint state-ments. No data is saved permanently to the database until a commitis issued. The commitis the end of the transaction, and the first SQL statement issued—either in a session or after a commit—is the beginning of the session.

If you run into trouble halfway through a transaction, you can issue a rollbackto tell Oracle to ignore all the statements that have been executed so far in the transaction.

The database is rolled back to the state that it was in before the start of the transaction.

You can also specify a savepoint, which is an intermediate commit. At the time you issue a savepoint, no data is permanently written to the database; instead, you have a point to roll back to other than the beginning of the transaction. This can save time and horsepower, because you don’t have to repeat all of the work that was done before you issue the savepoint, which is presumably okay.

Sequences

Earlier, you created a table with a primary key. The purpose of the primary key is to uniquely identify each row in your table. Each time you insert a new row, you need to create a new, unique key. You know that Oracle won’t let you insert a nonunique key, but how do you generate a new key? Finding the last key used is one strategy, but what if multiple sessions are creating new keys at the same time?

Fortunately, there is an easy solution—a sequence. An Oracle sequence generates a sequence of numbers. The numbers are guaranteed to be unique. Each time a call is made, the next number in the sequence is returned. Here is a simple sequence:

create sequence my_seq;

To use the sequence to generate ids, you can use the dual table as follows:

<?xml version=”1.0”?>

<page connection=”demo” xmlns:xsql=”urn:oracle-xsql”>

<xsql:query>

168 Chapter 8

SELECT my_seq.nextval FROM dual

</xsql:query>

</page>

If you are interested in getting the last value that was selected—known as the current value—you can do that as follows:

SELECT my_seq.currval FROM dual

Each time you reload the page, you will get a new sequence number. By default, a sequence starts at 1, increments by 1, has no maxvalue (other than 10^27), will never cycle back to where it started, will cache 20 numbers at a time, and does not guarantee that numbers will be generated in the order of the request. All these options can be tweaked, as listed in Table 8.18.

Table 8.18 Sequence Options

KEYWORD DESCRIPTION EXAMPLE

INCREMENT BY Value to increment by create sequence between calls. Can be negative. my_seq increment by 2 START WITH The first sequence number to create sequence

be generated. Defaults to my_seq start with 10 MINVALUEfor ascending

sequences and MAXVALUE for descending sequences.

MAXVALUE The largest value possible for create sequence the sequence. Default is 10^27. my_seq MAXVALUE 9999 MINVALUE The smallest value possible create sequence

for the sequence. Default is 1. my_seq MINVALUE 20 CYCLE The sequence will cycle when create sequence

either MINVALUEor MAXVALUE my_seq CYCLE is reached.

CACHE Number of numbers that will Create sequence be kept in cache. Unused my_seq CACHE 100 numbers are lost when the

database shuts down.

ORDER The sequence will guarantee CREATE SEQUENCE that numbers are returned in my_seq ORDER the order that requests were

received.

Often, developers make the assumption that if they always use the sequence there will be no holes in their list of ids. For instance, if you always use the a sequence that increments by 1 for your order table and you have 1,000 orders, the numbers 1 to 1,000 will be your keys. There are several reasons why this may not be the case. First, if the database is shutdown any unused ids left in the cache are lost. Second, if a transaction has to be rolled back before completion and a call to your sequence is made, that par-ticular id will be lost. Thus, you can be certain that all your ids are unique, but you can’t be certain that they are all sequential.

Sequences can be altered with the ALTER SEQUENCEstatement and the keywords documented above. Sequences can be dropped using the DROP SEQUENCEstatement:

DROP SEQUENCE my_seq;