![]() |
|
Home | Contents | Index | Master Index | New Book | ![]() |
![]() |
Using ViewsA view is a synthetic table. You can query it as if it were a table, and in some cases, you can update it as if it were a table. However, it is not a table. It is a synthesis of the data that exists in real tables and other views.The basis of a view is a SELECT statement. When you create a view, you define a SELECT statement that generates the contents of the view at the time the view is accessed. A user also queries a view using a SELECT statement. The database server merges the SELECT statement of the user with the one defined for the view and then actually performs the combined statements. The result has the appearance of a table; it is similar enough to a table that a view even can be based on other views, or on joins of tables and other views. Because you write a SELECT statement that determines the contents of the view, you can use views for any of the following purposes:
The view exposes only three columns of the table. Because it contains no WHERE clause, the view does not restrict the rows that can appear.
The following example is based on the join of two tables: The table of state names reduces the redundancy of the database; it lets you store the full state names only once, which can be useful for long state names such as Minnesota. This full_addr view lets users retrieve the address as if the full state name were stored in every row. The following two queries are equivalent: However, be careful when you define views that are based on joins. Such views are not modifiable; that is, you cannot use them with UPDATE, DELETE, or INSERT statements. (Modifying through views is covered beginning on page 11-29.) The following example restricts the rows that can be seen in the view: This view exposes all columns of the customer table, but only certain rows. The following example is a view that restricts users to rows that are relevant to them: All the columns of the cust_calls table are available but only in those rows that contain the user IDs of the users who can execute the query.
You can prevent this problem in two ways. One way is to specify DISTINCT in the select list in the view. However, specifying DISTINCT makes it impossible to modify through the view. The alternative is to always select a column or group of columns that is constrained to be unique. (You can be sure that only unique rows are returned if you select the columns of a primary key or of a candidate key. Primary and candidate keys are discussed in Chapter 8, "Building Your Data Model.")
Because it must be merged with the user's query, the SELECT statement on which a view is based cannot contain any of the following clauses:
When a table or view is dropped, any views in the same database that depend on it are automatically dropped. The only way to alter the definition of a view is to drop and re-create it. Therefore, if you change the definition of a view on which other views depend, you must also re-create the other views (because they all have been dropped). When a table is renamed, any views in the same database that depend on it are modified to use the new name. When a column is renamed, views in the same database that depend on that table are updated to select the proper column. However, the names of columns in the views themselves are not changed. For an example of this, recall the following view on the customer table: Now suppose that the customer table is changed in the following way: To select last names of customers directly, you must now select the new column name. However, the name of the column as seen through the view is unchanged. The following two queries are equivalent: When you alter a table by dropping a column, views are not modified. If they are used, error -217 ( Column not found in any table in the query ) occurs. The reason views are not dropped is that you can change the order of columns in a table by dropping a column and then adding a new column of the same name. If you do this, views based on that table continue to work. They retain their original sequence of columns.Universal Server permits you to base a view on tables and views in external databases. Changes to tables and views in other databases are not reflected in views. Such changes might not be apparent until someone queries the view and gets an error because an external table changed.
The following statements create two typed views, name_age and name_salary, on the emp table: When you create a typed view, the data that the view displays is of a named row type. For example, the name_age and name_salary views contain VARCHAR and INTEGER data. Because the views are typed, a query against the name_age view returns a column view of type name_age whereas a query against the name_salary view returns a column view of type name_salary. Consequently, Universal Server is able to distinguish between rows that the name_age and name_salary views return. In some cases, a typed view has a distinct advantage over an untyped view. For example, suppose you have overloaded a function foo(). Depending on the argument types that you specify, the database server calls a different function foo(). (For more information about function overloading, see Extending INFORMIX-Universal Server: User-Defined Routines.) Because the name_age and name_salary views are typed views, the following statements resolve to the appropriate foo() function, according to the type of the view that is associated with the alias p: If two views that contain the same data types are not created as typed views, Universal Server cannot distinguish between the rows that the two views display.
No modification is possible on a view when its SELECT statement contains any of the following features:
When a view avoids all these things, each row of the view corresponds to exactly one row of one table. Such a view is modifiable. (Of course, particular users can modify a view only if they have suitable privileges. Privileges on views are discussed beginning on page 11-32.)
When a column is derived from a simple arithmetic combination of a column with a constant value (for example, The following example shows a modifiable view that contains a derived column and an UPDATE statement that can be accepted against it: The duration column of the view cannot be updated because it represents an expression (the database server cannot, even in principle, decide how to distribute an update value between the two columns named in the expression). But as long as no derived columns are named in the SET clause, the update can be performed as if the view were a table. A view can return duplicate rows even though the rows of the underlying table are unique. You cannot distinguish one duplicate row from another. If you update one of a set of duplicate rows (for example, by using a cursor to update WHERE CURRENT), you cannot be sure which row in the underlying table receives the update.
When a modifiable view contains no derived columns, you can insert into it as if it were a table. However, the database server uses null as the value for any column that is not exposed by the view. If such a column does not allow nulls, an error occurs, and the insert fails.
To avoid updating a row of a view so that it no longer satisfies the conditions of the view, you can add the WITH CHECK OPTION clause when you create the view. This clause asks the database server to test every inserted or updated row to ensure that it meets the conditions set by the WHERE clause of the view. The database server rejects the operation with an error if the conditions are not met. In the previous example, the view named call_response is defined as the following example shows: You can update the user_id column of the view, as the following example shows: The view requires rows in which user_id equals USER. If a user named tony performs this update, the updated rows vanish from the view. However, you can create the view as the following example shows: The preceding update by tony is rejected as an error. You can use the WITH CHECK OPTION clause to enforce any kind of data constraint that can be stated as a Boolean expression. In the following example, you can create a view of a table in which all the logical constraints on data are expressed as conditions of the WHERE clause. Then you can require all modifications to the table to be made through the view. Because of EXISTS and other tests, which are expected to be successful when retrieving existing rows, this view displays data from orders inefficiently. However, if insertions to orders are made only through this view (and you are not already using integrity constraints to constrain data), users cannot insert a back-dated order, an invalid customer number, or an excessive shipping weight and shipping charge.
|
![]() |
![]() |