1. Trang chủ
  2. » Công Nghệ Thông Tin

Oracle Unleashed- P11

50 290 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Nội dung

cause all references in the child table to be deleted automatically. In this respect, using ON DELETE CASCADE is similar to creating a DELETE trigger on the referenced table. This is an extremely powerful option and should be used with caution. If it is not properly understood, unwanted automatic deletions could result. Although they are ideally suited to enforcing referential integrity, REFERENCES constraints may not be desirable in certain situations. For example, if a table has a high volume of transactions and contains several foreign keys that are simple lookups, performance can be adversely affected by using the REFERENCES constraint. Each time a row is inserted or updated, the referenced tables must be checked to ensure that each foreign key being inserted exists in the referenced tables. Depending on the nature of the data and the importance of performance, it may be preferable to enforce the foreign keys through the application itself. Table Constraints Each of the column constraints described in the previous section can also be applied as table constraints, with the exception of NOT NULL. Table constraints have the additional advantage of being able to operate on multiple columns. Refer to the CHECK constraint in Listing 20.6. This provides a sanity check on the lower bounds of date_of_birth, but it would be better to check the upper bounds as well. Listing 20.10 illustrates how you can accomplish this using a table constraint. Listing 20.10. This DDL script, containing a CHECK table constraint, is an improvement on the column constraint used in Listing 20.6. CREATE TABLE individual ( ID NUMBER(10) CONSTRAINT indiv_pk PRIMARY KEY ,last_name VARCHAR2(30) CONSTRAINT indiv_l_name NOT NULL ,first_name VARCHAR2(30) CONSTRAINT indiv_f_name NOT NULL ,notes VARCHAR2(255) ,date_of_birth DATE ,last_updt_user VARCHAR2(20) CONSTRAINT indiv_lu_id NOT NULL ,last_updt_date DATE CONSTRAINT indiv_lu_dt NOT NULL ,CONSTRAINT indiv_chk_bday CHECK (date_of_birth BETWEEN (TO_DATE('01JAN1845', 'DDMONYYYY', 'nls_date_language = American')) AND last_updt_date) Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. ); The syntax of table constraints is nearly identical to that of column constraints, except that the CONSTRAINT clause comes at the end of the column list. Another advantage to using a table constraint applies only to constraints that result in the creation of an index. The table constraint syntax allows the designation of a tablespace and storage specification for the corresponding index. When indexes are created automatically for column constraints, they are created in the default tablespace using the default storage specification. The script in Listing 20.11 adds a UNIQUE constraint to the ind_co_rel table, enforcing uniqueness in the combination of individual_id and company_id. It also implements the USING INDEX clause to designate a tablespace and storage specification for the index that will be created. Listing 20.11. This DDL script uses the ALTER TABLE syntax to create a UNIQUE table constraint and a storage specification for the corresponding index. ALTER TABLE ind_co_rel ADD CONSTRAINT ind_co_rel_u UNIQUE(individual_id, company_id) USING INDEX TABLESPACE oracle_unleashed STORAGE (INITIAL 10K NEXT 10K MAXEXTENTS 100 PCTINCREASE 10); The syntax for tablespace and storage specification following the USING INDEX keyword is identical to that for the CREATE INDEX statement. The USING INDEX clause can also be used in a PRIMARY KEY constraint, as illustrated in Listing 20.12. Listing 20.12. This DDL script removes the UNIQUE constraint created in Listing 20.11 and re-creates it as a PRIMARY KEY. ALTER TABLE ind_co_rel DROP CONSTRAINT ind_co_rel_u / ALTER TABLE ind_co_rel DROP CONSTRAINT indco_ind_nn / ALTER TABLE ind_co_rel DROP CONSTRAINT indco_co_nn Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. / ALTER TABLE ind_co_rel ADD CONSTRAINT ind_co_rel_pk PRIMARY KEY(individual_id, company_id) USING INDEX TABLESPACE oracle_unleashed STORAGE (INITIAL 10K NEXT 10K MAXEXTENTS 100 PCTINCREASE 10) / Notice that the NOT NULL constraints on the individual_id and company_id columns were also dropped. To keep them would be redundant, because columns included in a PRIMARY KEY constraint cannot have null values. Foreign key table constraints are implemented in much the same way as REFERENCING column constraints. If necessary, multiple columns can be included in a FOREIGN KEY table constraint. This is not the case with the column constraint implementation. Note also that the FOREIGN KEY keyword is only available for the table constraint syntax. Listing 20.13, the final script for ind_co_rel, also defines temporary tables into which exceptions are logged. Listing 20.13. The final ind_co_rel script uses the FOREIGN KEY table constraint syntax and logs exceptions into temporary tables. CREATE TABLE ind_co_rel ( individual_id NUMBER(10) ,company_id NUMBER(10) ,title VARCHAR2(80) ,last_updt_user VARCHAR2(20) CONSTRAINT indco_lu_id NOT NULL EXCEPTIONS INTO ind_co_err_1 ,last_updt_date DATE CONSTRAINT indco_lu_dt NOT NULL EXCEPTIONS INTO ind_co_err_2 ,CONSTRAINT indco_ind_fk FOREIGN KEY (individual_id) REFERENCES individual(ID) ON DELETE CASCADE Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. EXCEPTIONS INTO ind_co_err_3 ,CONSTRAINT indco_co_fk FOREIGN KEY (company_id) REFERENCES company(ID) ON DELETE CASCADE EXCEPTIONS INTO ind_co_err_4 ,CONSTRAINT ind_co_rel_pk PRIMARY KEY(individual_id, company_id) USING INDEX TABLESPACE oracle_unleashed STORAGE (INITIAL 10K NEXT 10K MAXEXTENTS 100 PCTINCREASE 10) EXCEPTIONS INTO ind_co_err_5 ) TABLESPACE oracle_unleashed; Each type of exception is logged into a different temporary table in Listing 20.13, which is helpful in debugging and resolving integrity problems. The tables into which exceptions are logged should be identical to the ind_co_rel table, except that they should have no constraints, for obvious reasons. The EXCEPTIONS INTO clause can be used for any type of column or table constraint. If the table referenced by EXCEPTIONS INTO does not exist, using the clause will produce an error. The EXCEPTIONS INTO clause is particularly useful in applications where frequent and timely bulk loads are required. In order to use SQL*Loader with the direct path option to maximize its performance, constraints must be disabled. When the constraints are re-enabled, the EXCEPTIONS INTO clause can be used to categorize problem records by inserting them in separate tables based on the constraint that was violated. This minimizes the negative impact constraints have on performance, while maintaining integrity and providing a means of identifying and resolving problems with the data being loaded. As shown by these examples, Oracle provides a wide variety of options for enforcing integrity through column and table constraints. Constraints are powerful tools for enforcing integrity, but they should be used with care. Overuse of constraints can add significantly to long-term maintenance requirements, and misuse can create unwanted dependencies or unnecessary exceptions. The possible trade-offs involving constraints and performance will be discussed in greater detail later in this chapter. Using Sequences Oracle sequences are ideally suited to the task of generating unique key values. A sequence is a stored object that simply generates a sequence of numbers. Listing 20.14 illustrates the syntax for creating a sequence. Listing 20.14. This sequence is used to generate primary keys for the individual table. Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. CREATE SEQUENCE individual_ids START WITH 1 INCREMENT BY 1 NOMAXVALUE; The values specified for the START WITH, and INCREMENT BY parameters in Listing 20.14 are the defaults. NOMAXVALUE is the default as well. The script in Listing 20.13 will produce the same result as the following: CREATE SEQUENCE individual_ids; It is a good practice to explicitly declare these defaults for documentation purposes, if nothing else. The implementation is fairly self-explanatory. The START WITH parameter indicates the first number that will be generated, INCREMENT BY specifies a number to be added to the current value to generate the next value, and NOMAXVALUE indicates that there is no maximum to the numbers it will generate, (practically no maximum, although there is an upper limit). The MINVALUE parameter is used only by descending sequences. (Specifying a negative value for INCREMENT BY produces a descending sequence.) CYCLE, when used in conjunction with MAXVALUE or MINVALUE, indicates that the sequence should start from the beginning when the minimum or maximum value is reached. The default for this option is NOCYCLE. The CACHE parameter indicates the number of values that should be pre-generated and cached by the sequence. The default value for CACHE is 20. Raising this parameter can improve performance in high transaction volume environments. ORDER ensures that sequences are used in the order generated. Regardless of the setting of this option, the same value will never be returned twice. If an application uses a sequence in a transaction that is rolled back, the value is simply discarded. NORDER, the default for this option, is acceptable unless the sequence is being used like a timestamp to indicate the order of events over time. A sequence has two pseudocolumns, currval and nextval. Currval returns the current value of the sequence, while nextval increments the sequence and returns the new value. Listing 20.15 demonstrates how a sequence can be used in an Oracle function to generate new keys when inserting records. Listing 20.15. This function accesses a sequence to fetch a new key when inserting a record. CREATE OR REPLACE FUNCTION insert_indiv (last CHAR, first CHAR, notes CHAR, dob DATE) RETURN NUMBER IS new_id NUMBER; BEGIN SELECT individual_ids.nextval INTO new_id FROM dual; INSERT INTO individual VALUES (new_id, last, first, notes, dob, user, sysdate); Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. COMMIT; RETURN(new_id); EXCEPTION WHEN OTHERS THEN ROLLBACK; RETURN(1); END insert_indiv; It is a common practice to use sequences for generating unique primary keys. One sequence can be used for many tables, or a separate sequence can be created for each table requiring generated keys. Either option is preferable to any key that requires user intervention, because typographical errors are bound to occur. It is typically preferable to generate unique keys even when one exists naturally in the data (Social Security number, for example). Using a sequence to generate primary keys can improve performance in certain situations, as well. As mentioned previously, integer joins are typically faster than character-based joins, and even when a natural integer primary key exists, a sequence is often a better choice. To use Social Security number as an example, 10 bytes must be stored for each key. If a sequence is used, starting with 1, a considerable amount of disk space can be conserved, and a much smaller index produced, which will result in less I/O. Perhaps a less important consideration is the order in which values are inserted. Depending on how inserts are handled by applications accessing the sequence, the index on a sequence- generated primary key may be created in ascending order naturally, which is somewhat of an optimization in terms of I/ O performance. If the sequence is created with the ORDER option, and inserts are handled using Oracle subprograms similar to Listing 20.15, this will always be true. Using Triggers Triggers are stored procedures associated with a specific operation on a specific table. A trigger is automatically fired when the operation with which it is associated is performed on the table with which it is associated. Triggers can perform many of the same tasks as constraints, and in most cases, they can go beyond what constraints can do. For example, a NOT NULL constraint can only ensure that a value is present in a column, but it does nothing to ensure the accuracy of the data. Listing 20.16 provides an example of how you can use triggers to enforce a NOT NULL constraint and ensure the accuracy of the data being inserted. Listing 20.16. This trigger ensures that the columns last_updt_user and last_updt_date are inserted and updated accurately. CREATE OR REPLACE TRIGGER indiv_timestamp BEFORE INSERT OR UPDATE ON individual FOR EACH ROW BEGIN :new.last_updt_user := user; :new.last_updt_date := sysdate; END indiv_timestamp; The simple trigger in Listing 20.16 ensures that the last_updt_user and last_updt_date are being inserted and updated accurately in the individual table. In effect, the trigger intercepts the actual values being inserted and replaces them with Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. user and sysdate. Using the NOT NULL constraint for these columns is no longer necessary, and the trigger goes far beyond what the constraint could do. The trigger in Listing 20.16 also relieves the application of the burden of supplying values for the last_updt_user and last_updt_date columns when inserting and updating records. INSERT and UPDATE triggers are commonly used for customized transaction logging, or to generate statistical summaries to be accessed by a different group of users than those applying the transactions. For example, a large order entry system might use an INSERT trigger to write only the date, the order amount, and the salesperson to a separate table to be used only for management reporting. The syntax for creating triggers is very similar to the creation of procedures, with a few notable exceptions. The BEFORE or AFTER keyword must follow the name of the trigger, indicating whether it should be fired before or after the operation that causes it is fired. Although it may not seem logical to do so, this trigger had to be created with the BEFORE option. Trying to implement this trigger with the AFTER option produces the following error: ORA04091: table SCOTTY.INDIVIDUAL is mutating, trigger/function may not see it Because the trigger is being executed by a process that is currently involved in a transaction on the same row, it cannot be created with the AFTER option. This would, in effect, invalidate the old correlation of the trigger. Immediately following the BEFORE or AFTER keyword is the action (or actions) with which the trigger is associated. This can be INSERT, UPDATE, or DELETE, or any combination of these separated by OR. The FOR EACH ROW keyword defines the behavior of the trigger when it is fired by statements affecting multiple rows. The default behavior is to fire the trigger only once, regardless of the number of rows affected. A trigger may also include a WHEN clause, which limits the conditions under which it will fire. The WHEN clause can be used for specialized reporting, or to draw attention to a value that may seem to be out of range. For example, an accounts payable system might use an INSERT trigger to log all payments of greater than $10,000 to a temporary table, which can then be used to generate a report for management's review and approval. This could be an alternative to a CHECK condition, which might prove to be overly restrictive. In most circumstances, it would not be acceptable to reject a valid payment simply because it is unusually high. On the other hand, management may be interested in reviewing or auditing these payments. In this respect, a trigger can be used in a way that is analogous to passively enforcing a CHECK constraint. Note that in Listing 20.16, the variable new is never declared. This is the default correlation name associated with the new row (which is valid for inserts and updates only). The name old is associated with the old row by default, and is valid for updates and deletes only. These default names can be reassigned using a REFERENCING clause. The REFERENCING clause should placed immediately before the FOR EACH ROW keyword (if it is used), as in Listing 20.17. Listing 20.17. This trigger uses a REFERENCING clause to rename new. CREATE OR REPLACE TRIGGER indiv_timestamp Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. BEFORE INSERT OR UPDATE ON individual REFERENCING new AS new_row FOR EACH ROW BEGIN :new_row.last_updt_user := user; :new_row.last_updt_date := sysdate; END indiv_timestamp; The REFERENCING clause is rarely used, but it is provided in order to allow the use of new and old as regular program variables. Triggers, when used with sequences, can also be used to enforce primary key constraints. Listing 20.18 creates a trigger that ensures that new rows in the individual table are assigned unique primary key values. The trigger also ensures that the sequence is used, by overriding any value specified in an insert statement with the next value in the sequence. Listing 20.18. This trigger enforces the primary key on the individual table. CREATE OR REPLACE TRIGGER indiv_get_key BEFORE INSERT ON individual FOR EACH ROW DECLARE new_id NUMBER; BEGIN SELECT individual_ids.nextval INTO new_id FROM dual; :new.id := new_id; END indiv_get_key; Unfortunately, this trigger cannot coexist with the trigger in Listing 20.17. For each table, only one trigger can exist for each operation. Listing 20.19 demonstrates how these can be implemented together, replacing the CHECK constraint on date_of_birth in the process. Listing 20.19. These triggers can be used to enforce several constraints on the individual table. CREATE OR REPLACE TRIGGER indiv_ins_trg BEFORE INSERT ON individual FOR EACH ROW DECLARE new_id NUMBER; BEGIN IF ((:new.date_of_birth < TO_DATE('01JAN1845', 'DDMONYYYY', Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. 'nls_date_language = American')) OR (:new.date_of_birth > sysdate)) THEN RAISE_APPLICATION_ERROR(20001, 'Invalid birth date.'); ELSE SELECT individual_ids.nextval INTO new_id FROM dual; :new.id := new_id; :new.last_updt_user := user; :new.last_updt_date := sysdate; END IF; END indiv_ins_trig; CREATE OR REPLACE TRIGGER indiv_updt_trg BEFORE UPDATE ON individual FOR EACH ROW BEGIN IF ((:new.date_of_birth < TO_DATE('01JAN1845', 'DDMONYYYY', 'nls_date_language = American')) OR (:new.date_of_birth > sysdate)) THEN RAISE_APPLICATION_ERROR(20001, 'Invalid birth date.'); ELSE :new.id := :old.id; :new.last_updt_user := user; :new.last_updt_date := sysdate; END IF; END indiv_updt_trg; In Listing 20.19, the PRIMARY KEY constraint is enforced for both inserts and updates. The UPDATE trigger completely prevents an ID from being changed, which might not be acceptable if this were not a generated key. The triggers also enforce a CHECK constraint on date_of_birth and the NOT NULL constraints on last_updt_user and last_updt_date. Triggers can be used to enforce foreign key constraints, as well. Refer to Listing 20.9. The REFERENCES constraints in the example both contained the ON DELETE CASCADE option. If the foreign keys integrity constraints are enforced by the triggers in Listing 20.20, the REFERENCES column constraints could be removed. Listing 20.20. These triggers can be used to enforce foreign key constraints. Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. CREATE OR REPLACE TRIGGER indiv_del_trg BEFORE DELETE ON individual FOR EACH ROW BEGIN DELETE FROM ind_co_rel WHERE individual_id = :old.id; END indiv_del_trg; CREATE OR REPLACE TRIGGER co_del_trg BEFORE DELETE ON company FOR EACH ROW BEGIN DELETE FROM ind_co_rel WHERE company_id = :old.id; END co_del_trg; CREATE OR REPLACE TRIGGER ind_co_trg BEFORE INSERT OR UPDATE ON ind_co_rel FOR EACH ROW DECLARE co_id NUMBER; indiv_id NUMBER; BEGIN SELECT ID INTO co_id FROM company WHERE ID = :new.company_id; SELECT ID INTO indiv_id FROM individual WHERE ID = :new.individual_id; EXCEPTION WHEN OTHERS THEN RAISE_APPLICATION_ERROR(20002, 'Invalid id.'); END ind_co_trg; As these examples demonstrate, triggers can be used to perform the same tasks as table and column constraints. In many cases, it may be preferable to use triggers because they are likely to provide better performance. This is particularly true in distributed environments, where it may not be possible to enforce foreign key constraints at all. When designing triggers, you should pay special attention to cascading triggers. Cascading occurs when a trigger on one table causes a trigger on another table to be fired. Codependencies, in particular, can be a problem. Note that in Listing 20.20, the individual and company tables both have DELETE triggers that delete corresponding rows from ind_co_rel. For the sake of example, assume that ind_co_rel has a DELETE trigger that deletes corresponding rows in address_rel and phone_rel, and that individual and company also include these deletions in their DELETE Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. [...]... the client application Table-Driven Application Security You can use information stored in Oracle tables to drive application security This solution is particularly useful when security restrictions are likely to change and flexibility is required As mentioned in the previous section, you can use a table in Oracle to determine the default application role of the current user The role can then be used... application security relates to databases that are accessed by multiple applications In this case, a single user might have multiple roles, of which only one applies to the specific application Use an Oracle table when there are different application roles that could apply For example, an order entry system might have three different roles: one for order entry, one for management reporting, and one... A billing system and a accounts receivable system might share common tables and be used by many of the same users These users may have slightly different role definitions for each application A simple Oracle table containing a user ID and a corresponding role can be used to determine the correct role to be used for the application at runtime The privileges of the appropriate role can then be used to... users from accessing them through SQL*Plus or one of the many desktop database or reporting tools that might enable them to modify the subprograms There are additional advantages to using packages An Oracle package encapsulates a group of variables, constants, cursors, and subprograms into a single logical unit This can greatly simplify the process of granting privileges, and improve overall performance... ,CONSTRAINT indco_co_fk FOREIGN KEY (company_id) REFERENCES company(ID) ON DELETE CASCADE EXCEPTIONS INTO ind_co_err_4 ,CONSTRAINT ind_co_rel_pk PRIMARY KEY(individual_id, company_id) USING INDEX TABLESPACE oracle_ unleashed STORAGE (INITIAL 10K NEXT 10K MAXEXTENTS 100 PCTINCREASE 10) EXCEPTIONS INTO ind_co_err_5 ); It would be useful if the application could insert an individual, a company, and a record relating... the process This should allow analysis of how the new additions will impact the system, or what processes the replacement must perform If the system was developed using the predecessor to Designer/2000, Oracle CASE, its design will be readily available to Designer/2000 Using the Legacy Led Development approach, existing processes are reverse engineered into Designer/2000 These definitions are stored in... www.verypdf.com to remove this watermark Previous TOC Page q Next Page Home 23 r Installing Designer/2000 s System Requirements s Client s Server s Back Up, Back Up, Back Up s Upgrading to Designer/2000 s Oracle CASE 5.1 s Designer/2000 version 6.0.0 to 6.0.4 s Designer/2000 6.0.5 to 6.06 s Client Installation s Complete Installation s Default Installation s Custom Installation/Deinstallation s Server Installation... product, you need to perform some tasks on the client (often an IBM PC or compatible) and perform server-specific tasks on the server (possibly a Windows NT server, a Dec Alpha, or other platform supporting Oracle) One of the most popular platforms on which to run the client side of Designer/2000 is Microsoft Windows In this chapter, you'll learn how to install Designer/2000 for Microsoft Windows As of this . INDEX TABLESPACE oracle_ unleashed STORAGE (INITIAL 10K NEXT 10K MAXEXTENTS 100 PCTINCREASE 10) EXCEPTIONS INTO ind_co_err_5 ) TABLESPACE oracle_ unleashed;. ind_co_rel_pk PRIMARY KEY(individual_id, company_id) USING INDEX TABLESPACE oracle_ unleashed STORAGE (INITIAL 10K NEXT 10K MAXEXTENTS 100 PCTINCREASE 10)

Ngày đăng: 28/10/2013, 23:15

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN