<html>
<head>
<link rel="stylesheet" href="josh.css">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<div id="Description">
<table width="100%" cellspacing="0" cellpadding="0" border="0">
  <tr>
  <td valign="top" class="name">Command Reference</td>
  <td valign="top" nowrap class="compatibility"> </td>
        </tr>
        <tr>
           <td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
        </tr>
      </td>
    </tr>
  <tr>
  <tr>
    <td>
This chapter is the heart of "SQL in a Nutshell" : it is an alphabetical listing of SQL commands with detailed explanations and examples. Each command and function is identified in a master table as being "supported," "supported with variations," "supported with limitations," or "not supported," for each of the four SQL dialects covered in this book: SQL Server, MySQL, Oracle, and PostgreSQL. After a brief description of the SQL99 standard, each vendor application is discussed briefly but thoroughly, with supporting examples and sample coding.
    </td>
  </tr>
  </table>
</div>

<div id="ALTER PROCEDURE">
<table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td Width="50%"align="left" class="name" valign="top">ALTER PROCEDURE <td Width="50%" align="right" class="name"valign="top">SQL-schema&nbsp;&nbsp;</td></tr></table>
<table width="100%" cellspacing="0" cellpadding="0" border="0">

  <tr>
    <td><p>The  ALTER PROCEDURE statement allows changes to be made to an existing stored procedure. Depending on the vendor, the kind and degree of change varies widely. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>In SQL Server, this statement alters a previously created procedure (using the  CREATE PROCEDURE statement) but doesn't change permissions or affect dependent stored procedures or triggers. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>In Oracle, this command simply recompiles a PL/SQL stored procedure, but does not allow the code to be changed. Instead, use the Oracle command CREATE OR REPLACE PROCEDURE to achieve the same functionality. </p>
    </td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
  <td><table border="1" >
<tr><th>Vendor</th>
<th>Command</th></tr>
<tr><td>SQL Server</td><td>Supported, with variations</td></tr><tr><td>MySQL</td><td>Not supported</td></tr><tr><td>Oracle</td><td>Supported, with variations</td></tr><tr><td>PostgreSQL</td><td>Not supported</td></tr></table>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">SQL99 Syntax and Description</span><td></tr>
    <tr>
    <tr>
	    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
    <td>
<span class="programlisting"><pre>
ALTER PROCEDURE procedure_name {CASCADE | RESTRICT}
[LANGUAGE | PARAMETER STYLE | &lt;SQL data access&gt; | &lt;null clause behavior&gt; | DYNAMIC RESULT SETS | NAME]
[parameter datatype [,...n]
</pre></span></td>
</tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
<tr>
<td>
<p>As discussed under  CREATE PROCEDURE , the  LANGUAGE ,  PARAMETER STYLE , SQL data access method (i.e.,  NO SQL ,  CONTAINS SQL , etc.), null clause behavior (e.g.,  CALL ON NULL INPUT ),  DYNAMIC RESULT SET , and the procedure  NAME all may be altered. </p>
   <p>The  ALTER PROCEDURE command also may be used to alter the number or type of  input parameters. </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="description"><span class="title">
  Microsoft SQL Server Syntax and Variations</span></td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
  <td>
<span class="programlisting">
<pre>ALTER PROC[EDURE] procedure_name [;number]
[ {@parameter datatype } [VARYING] [= default] [OUTPUT] ][,...n]
[WITH { RECOMPILE | ENCRYPTION  | RECOMPILE , ENCRYPTION } ]
[FOR REPLICATION]
AS
T-SQL Block</pre>
</span></td>
</tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
<tr>
<td>
<p>In SQL Server, this command allows the change of any existing parameters for the previously created stored procedure. In effect, this command is just a shortcut around issuing a  DROP PROCEDURE statement, followed by a modified  CREATE PROCEDURE statement. Such grants or permissions to the stored procedure do not have to be reestablished. Review the command  CREATE PROCEDURE for a full explanation of the syntax. This command may be executed on SQL Server by the owner of the stored procedure or a member of the  <span class="emphasis">db_owner</span> and  <span class="emphasis">ddl_admin</span> fixed database roles. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="example"><span class="title">Oracle Syntax and Variations</span></td>
    </tr>
    <tr>
	    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
    <tr>
    <td>
<span class="programlisting">
<pre>ALTER PROCEDURE [user.] procedure_name COMPILE [DEBUG];</pre></span></td>
</tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
<tr>
<td>
 <p>In Oracle, the procedure or package name that needs to be compiled must be provided. The  COMPILE keyword is required. The  COMPILE [DEBUG] option regenerates PL/SQL information. This command may be executed only by the owner of the stored procedure or by those who have specific privileges to  ALTER ANY PROCEDURE . </p>
    </td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
    </tr>
    <tr>
    <td valign="top" colspan="2" class="example"><span class="title"> Example</span></td></tr>
   <tr>
    <td><p>This example using Microsoft SQL Server creates a procedure called  <span class="emphasis">get_next_br</span> that generates a unique CHAR(22) output string. Then, when the procedure must be changed to retrieve unique INT output value,  ALTER PROCEDURE is used to redefine the stored procedure: </p></td>
    </tr>
    <tr>
	    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
    </tr>
    <tr>
    <td>
<span class="programlisting">
<pre>  -- A Microsoft SQL Server stored procedure
CREATE PROCEDURE get_next_nbr
   @next_nbr CHAR(22) OUTPUT
AS
BEGIN
  DECLARE @random_nbr INT
  SELECT @random_nbr = RAND(  ) * 1000000

SELECT @next_nbr =
  RIGHT('000000' + CAST(ROUND(RAND(@random_nbr)*1000000,0))AS CHAR(6), 6) +
  RIGHT('0000' + CAST(DATEPART (yy, GETDATE(  ) ) AS CHAR(4)), 2) +
  RIGHT('000'  + CAST(DATEPART (dy, GETDATE(  ) ) AS CHAR(3)), 3) +
  RIGHT('00'   + CAST(DATEPART (hh, GETDATE(  ) ) AS CHAR(2)), 2) +
  RIGHT('00'   + CAST(DATEPART (mi, GETDATE(  ) ) AS CHAR(2)), 2) +
  RIGHT('00'   + CAST(DATEPART (ss, GETDATE(  ) ) AS CHAR(2)), 2) +
  RIGHT('000'  + CAST(DATEPART (ms, GETDATE(  ) ) AS CHAR(3)), 3)
END
GO

ALTER PROCEDURE get_next_nbr
   @next_nbr INT OUTPUT
AS
BEGIN
  DECLARE @convert_to_nbr CHAR(22)
  DECLARE @random_nbr INT
  SELECT  @random_nbr = RAND(  ) * 1000000

SELECT @convert_to_nbr =
  RIGHT('000000' + CAST(ROUND(RAND(@random_nbr)*1000000,0))AS CHAR(6), 6) +
  RIGHT('0000' + CAST(DATEPART (yy, GETDATE(  ) ) AS CHAR(4)), 2) +
  RIGHT('000'  + CAST(DATEPART (dy, GETDATE(  ) ) AS CHAR(3)), 3) +
  RIGHT('00'   + CAST(DATEPART (hh, GETDATE(  ) ) AS CHAR(2)), 2) +
  RIGHT('00'   + CAST(DATEPART (mi, GETDATE(  ) ) AS CHAR(2)), 2) +
  RIGHT('00'   + CAST(DATEPART (ss, GETDATE(  ) ) AS CHAR(2)), 2) +
  RIGHT('000'  + CAST(DATEPART (ms, GETDATE(  ) ) AS CHAR(3)), 3)

SELECT @next_nbr = CAST(@convert_to_nbr AS INT)

END
GO</pre></span></td>
  </tr>
</table>
</div>

<div id="ALTER TABLE"><table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td Width="50%"align="left" class="name" valign="top">ALTER TABLE <td Width="50%" align="right" class="name"valign="top">SQL-schema&nbsp;&nbsp;</td></tr></table>
<table width="100%" cellspacing="0" cellpadding="0" border="0">

  <tr>
    <td><p>The  ALTER TABLE statement allows an existing table to be modified without dropping the table or altering existing permissions on the table. In this way, certain incremental changes are performed easily on an existing table.</p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Both Oracle and Microsoft SQL Server support this command with a number of variations to service their differing physical file-allocation methods. </p>
    </td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
  <td>
  <table border="1" >
<tr><th>Vendor</th>
<th>Command</th></tr>
<tr><td>SQL Server</td><td>Supported, with variations</td></tr><tr><td>MySQL</td><td>Supported, with limitations</td></tr><tr><td>Oracle</td><td>Supported, with variations</td></tr><tr><td>PostgreSQL</td><td>Supported, with variations</td></tr></table>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>

<tr>

    <td valign="top" colspan="2" class="description"><span class="title">SQL99 Syntax and Description</span></td></tr>
    <tr>
	    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
    <tr>
    <td>
    <span class="programlisting">
     <pre>ALTER TABLE table_name
	 [ADD [COLUMN] column_name datatype attributes]
	 | [ALTER [COLUMN] column_name SET DEFAULT default_value]
	 | [ALTER [COLUMN] column_name DROP DEFAULT]
	 | [ALTER [COLUMN] column_name ADD SCOPE table_name
	 | [ALTER [COLUMN] column_name DROP SCOPE {RESTRICT | CASCADE}]
	 | [DROP [COLUMN] column_name {RESTRICT | CASCADE}]
	 | [ADD table_constraint_name]
     | [DROP CONSTRAINT table_constraint_name {RESTRICT | CASCADE}]</pre>
      </span>
      </td>
      </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The SQL99  ALTER TABLE statement allows many useful modifications to be made to an existing table. This versatile command allows users to  ADD COLUMN or table constraint; add or drop a  DEFAULT ; add or drop  SCOPE on  columns that are set up to reference a user-defined type; and  DROP both a column and a table constraint.  DROP RESTRICT tells the host DBMS to abort the command if it sees that other objects in the database depend on the column or table constraint.  DROP CASCADE tells the host DBMS to drop any database object that depends on the column or table constraint. Refer to the  CREATE TABLE statement for additional explanations of these elements of the command. </p>
    </td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
  <td valign="top" colspan="2" class="example"><span class="title">Microsoft SQL Server Syntax and Variations</span></td></tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
  <td>
  <span class="programlisting">
  <pre>ALTER TABLE table_name
[ALTER COLUMN column_name new_data_type attributes {ADD | DROP}
   ROWGUIDCOL]
| [ADD [COLUMN] column_name datatype attributes][,...n]
| [WITH CHECK | WITH NOCHECK] ADD table_constraint][,...n]
| [DROP { [ CONSTRAINT ] constraint_name | COLUMN column_name }] [,...n]
| [{ CHECK | NOCHECK } CONSTRAINT { ALL | constraint_name [,...n] }]
| [{ ENABLE | DISABLE } TRIGGER { ALL | trigger_name [,...n] }]</pre></span>
  </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Microsoft SQL Server offers many features in its implementation of  ALTER TABLE .  ALTER COLUMN allows the change of an existing column, such as datatype, nullability, identity functions, and so on.  ADD puts a new column, computed column, or constraint in the table in the very last column position. (There is, at present, no way to insert a column in the middle or in some other position of the table.) The optional word  COLUMN is provided for clarity, but is not necessary. The new column must be defined in the same way as using the  CREATE TABLE statement, including any constraints, defaults, and collations. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The  WITH CHECK and  WITH NOCHECK clauses tell SQL Server whether the data in the table should be validated against any newly added constraints or keys. When constraints are added with  WITH NOCHECK , the query optimizer ignores them until they are enabled via  ALTER TABLE table_name CHECK CONSTRAINT ALL . Constraints may be dropped with  DROP CONSTRAINT (though the  CONSTRAINT keyword is not necessary) and enabled/disabled with  CHECK CONSTRAINT and  NOCHECK CONSTRAINT , respectively. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Similarly, a named trigger on a table may be enabled or disabled using the  ENABLE TRIGGER and  DISABLE TRIGGER clauses. All triggers on a table may be enabled or disabled by substituting the keyword  ALL for the table name, as in  ALTER TABLE employee DISABLE TRIGGER ALL . </p>
    </td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
  <td valign="top" colspan="2" class="example"><span class="title">
  MySQL Syntax and Variations</span></td></tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
  <td>
  <span class="programlisting"><pre>
  ALTER [IGNORE] TABLE table_name
[ADD [COLUMN] column_name datatype attributes ]
   [FIRST | AFTER column_name]] [,...n]
| [ADD INDEX [index_name] (index_col_name,...)] [,...n]
| [ADD PRIMARY KEY (index_col_name,...)] [,...n]
| [ADD UNIQUE [index_name] (index_col_name,...)] [,...n]
| [ALTER [COLUMN] column_name {SET DEFAULT literal | DROP DEFAULT}] [,...n]
| [CHANGE [COLUMN] old_col_name create_definition] [,...n]
| [MODIFY [COLUMN] column_name datatype attributes] [,...n]
| [DROP [COLUMN] column_name] [,...n]
| [DROP PRIMARY KEY] [,...n]
| [DROP INDEX index_name] [,...n]
| [RENAME [AS] new_tbl_name] [,...n]
| [table_options]</pre></span>
  </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Refer to the  CREATE TABLE statement for more details on allowable column attributes and table constraints. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The  IGNORE option tells MySQL to delete duplicate rows when defining a new unique key. If  IGNORE is not specified, the operation aborts when duplicate records exist on the unique key. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The  FIRST option is used when adding a new column as the first column of the table. The  AFTER column_name may be to add a new column into a table after the specified <span class="emphasis">column_name</span> . </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>In addition, MySQL allows some additional flexibility in the  ALTER TABLE statement by allowing users to issue multiple  ADD ,  ALTER ,  DROP , and  CHANGE clauses in a single  ALTER TABLE statement. However, be aware that the  CHANGE column_name and  DROP INDEX clauses are MySQL extensions not found in SQL99. MySQL also supports the Oracle extension  MODIFY column_name . The  ALTER COLUMN clause allows a new default value for a column to be set or dropped. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>A  table may be renamed by using  RENAME AS, and a  column may be renamed using  CHANGE . For example, this code renames both a table and a column: </p>
    </td>
  </tr>
   <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
  <td>
  <span class="programlisting">
  <pre>ALTER TABLE employee RENAME AS emp;
  ALTER TABLE employee CHANGE employee_ssn emp_ssn INTEGER;</pre></span>
  </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Since MySQL allows the creation of indexes on a portion of a column (for example, on the first ten characters of a column), the  CHANGE or  MODIFY commands may not be used to create a column of less length than its indexes. When  DROP COLUMN is used, the column is removed from both the table and any indexes built with that column. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>DROP PRIMARY KEY does not automatically fail if there is no primary key on the table. Instead, MySQL will drop the first unique index on the table. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>MySQL allows a  datatype on an existing column to be redefined without losing any data. The values contained in the column must be compatible with the new datatype. For example, a date column could be redefined to a character datatype, but not a character datatype to an integer. Here's an example: </p>
    </td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
  <td>
  <span class="programlisting">
  <pre>ALTER TABLE mytable MODIFY mycolumn LONGTEXT</pre>
  </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>MySQL allows the  FOREIGN KEY ,  CHECK, and  REFERENCES clauses, but they are empty. Commands containing these clauses may be issued, but they do nothing. They are provided primarily for porting compatibility. </p>
    </td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
 <td valign="top" colspan="2" class="example"><span class="title">
  Oracle Syntax and Variations</span></td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
   <tr>
  <td>
  <span class="programlisting">
  <pre>ALTER TABLE [owner_name.]table_name
[ADD column_name datatype attributes]
| [MODIFY {column_name datatype
   | column_constraint
   | physical_storage_attributes [LOGGING | NOLOGGING]
   | nested_table_attributes}]
| [MODIFY CONSTRAINT {constraint_name {constraint_state}
   | drop_constraint_clause
   | drop_column_clause
   | [ALLOCATE | DEALLOCATE extent_clause]
   | [CACHE | NOCACHE]
   | [LOGGING | NOLOGGING]
   | [MONITORING | NOMONITORING] ]
| [DROP {[COLUMN] column_name | constraint_name}]
| [ALLOCATE EXTENT details]
| [DEALLOCATE UNUSED details]
| [RENAME TO new_table_name]
| [OVERFLOW physical_storage_attributes]
| [ADD OVERFLOW physical_storage_attributes]
| [{ADD | DROP | MODIFY | MOVE | TRUNCATE | SPLIT | EXCHANGE | MODIFY}
   PARTITION partition_details]</pre</span>
  </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The  ALTER TABLE statement details Oracle's multitude of powerful features for controlling the physical storage and manipulation of a  table, such as handling data extents, handling overflow extents, and partitioning tables to better handle extreme usage loads. Check Oracle's implementation of  CREATE TABLE to see the specific syntax allowed for some of the previous lines, such as  column_constraint ,  physical_storage_attributes, and  nested_table_attributes . </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>This command may be used to  ADD a new  column or constraint or  MODIFY and  DROP existing columns and constraints. When a new column is added, it should be defined as  NULL , unless the table has no rows. The  MODIFY keyword allows you to alter characteristics of a previously created table. The  MODIFY CONSTRAINT allows you to drop or alter constraints on a table, including whether  LOGGING ,  CACHE , or  MONITOR is activated, as well as whether to  ALLOCATE or  DEALLOCATE storage extents. It also utilizes the keywords  ENABLE and  DISABLE to activate or deactivate constraints on a table. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>
  Oracle's implementation of ALTER TABLE is very sophisticated and complex. Refer to the CREATE TABLE statement for complete discussions on subclauses to the commands that are held in common. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>For example, the following code adds a new column to a table in Oracle and adds a new, unique constraint to that table: </p>
    </td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
  <td>
  <span class="programlisting">
  <pre>ALTER TABLE titles
  ADD subtitle VARCHAR2(32) NULL
  CONSTRAINT unq_subtitle UNIQUE;</pre></span>
  </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>When a foreign key constraint is added to a table, the DBMS verifies that all existing data in the table meets that constraint. If they do not, the  <span class="emphasis">ALTER TABLE</span> fails. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>
  Any applications that use  SELECT *  return the new columns, even if this was not planned. On the other hand, precompiled objects, such as stored procedures, may not return any new columns.
  </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Oracle also allows multiple actions, such as  ADD or  MODIFY, to multiple  columns to be performed by enclosing the action within parentheses. For example, the following command adds several columns to a table with this single statement: </p>
    </td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
  <td>
   <span class="programlisting">
  <pre>ALTER TABLE titles
  ADD (subtitles VARCHAR2(32) NULL,
  year_of_copyright INT,
  date_of_origin DATE);</pre></span></td></tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="example"><span class="title">
  PostgreSQL Syntax and Variations</span></td></tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
  <td>
   <span class="programlisting">
  <pre>ALTER TABLE table [*]
[ADD [COLUMN] column_name datatype attributes]
| [ALTER [COLUMN] column_name {SET DEFAULT value | DROP DEFAULT}]
| [RENAME [COLUMN] column_name TO new_column_name]
| [RENAME TO new_table_name]</pre></span></td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>PostgreSQL's implementation of  ALTER TABLE allows the addition of extra  columns using the  ADD keyword. Existing columns may have new default values assigned to them using  ALTER COLUMN . . . SET DEFAULT , while  ALTER COLUMN . . . DROP DEFAULT allows the complete erasure of a column-based default. In addition, new defaults may be added to columns using the  ALTER clause, but only newly inserted rows will be affected by the default value.  RENAME allows new names for existing columns and tables. </p>
    </td>
  </tr>
</table>
</div>

<DIV id="ALTER TRIGGER">
<table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td Width="50%"align="left" class="name" valign="top">ALTER TRIGGER <td Width="50%" align="right" class="name"valign="top">SQL-schema&nbsp;&nbsp;</td></tr></table>
<table width="100%" cellspacing="0" cellpadding="0" border="0">

  <tr>
    <td><p>The  ALTER TRIGGER statement modifies a preexisting trigger definition without altering permissions or dependencies. </p>
    </td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
  <td>
  <table border="1" >
<tr><th>Vendor</th>
<th>Command</th></tr>
<tr><td>SQL Server</td><td>Supported, with variations</td></tr><tr><td>MySQL</td><td>Not supported</td></tr><tr><td>Oracle</td><td>Supported, with variations</td></tr><tr><td>PostgreSQL</td><td>Not supported</td></tr></table>
</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="description"><span class="title">SQL99 Syntax and Description</span></td></tr>

  <tr>
    <td>Currently, there is no SQL99 standard for this command.</td>
    </tr>
     <tr>
	    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
    <tr>
    <td valign="top" colspan="2" class="description"><span class="title">Microsoft SQL Server Syntax and Variations</span></td>
    </tr>
    <tr>
	    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
    <tr>
    <td>
    <span class="programlisting">
    <pre>ALTER TRIGGER trigger_name
ON {table_name | view_name}
[WITH ENCRYPTION]
{FOR | AFTER | INSTEAD OF} {[DELETE] [,] [INSERT] [,] [UPDATE]}
[WITH APPEND]
[NOT FOR REPLICATION]
AS
  T-SQL_block
| [FOR { [INSERT] [,] [UPDATE] }
[NOT FOR REPLICATION]
AS
{ IF UPDATE(column) [{AND | OR} UPDATE(column)] [...n]
|
IF (COLUMNS_UPDATED(  ) {bitwise_operator} updated_bitmask)
{ comparison_operator} column_bitmask [...n] }
T-SQL_block ] } ]</pre></span>
    </td>
    </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Microsoft SQL Server allows the specification of  FOR | AFTER | INSTEAD OF { [DELETE] [,] [UPDATE] [,][INSERT] } | { [INSERT] [,] [UPDATE] } to describe which data-modification statement trigger is affected by the command. At least one of these is required, but any combination is allowed with extra options separated by commas. The options  FOR and  AFTER are essentially the same, causing the trigger code to fire after the data-manipulation operation has completed. Alternately, the  INSTEAD OF key phrase tells SQL Server to substitute the data-manipulation operation completely with the code of the trigger. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The  WITH APPEND key phrase tells SQL Server to append an additional trigger of the specified type to the base table. This option is allowed only on  FOR triggers. The  NOT FOR REPLICATION key phrase tells SQL Server not to execute the trigger when the action is caused by a replication login, such as  sqlrepl . The  IF UPDATE (column) clause tests for an  INSERT or  UPDATE action (but not  DELETE ) on a specific column and is very useful when doing row-based operations using a cursor. The  {AND | OR} operators allow additional columns in the same phrase to be tested. The  IF (COLUMNS_UPDATED( )) test an  INSERT or  UPDATE trigger to see if the mentioned column(s) were affected. The results are returned as bitwise operators. </p>
    </td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
    </tr>
    <tr>
    <td valign="top" colspan="2" class="description"><span class="title">
  Oracle Syntax and Variations</span>
  </td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
  <td>
  <span class="programlisting">
  <pre>ALTER TRIGGER [user.] trigger_name   [ENABLE | DISABLE | COMPILE [DEBUG] ];</pre></span>
  </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Oracle does not allow the underlying code of the trigger to be completely altered using this command (although the same functionality can be attained using Oracle's implementation of  CREATE OR REPLACE TRIGGER ). Oracle's  ALTER TRIGGER allows a trigger to be enabled, disabled, or recompiled. The  COMPILE [DEBUG] option regenerates PL/SQL information. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>
  <span class="emphasis">Tip:</span> Oracle allows triggers
  <span class="emphasis">only</span>
  on tables (though
  INSTEAD OF triggers are allowed on views). Microsoft SQL Server allows triggers on tables and updateable views. </p>
    </td>
  </tr>
</table>
</div>

<DIV id="ALTER VIEW">
<table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td Width="50%"align="left" class="name" valign="top">ALTER VIEW <td Width="50%" align="right" class="name"valign="top">SQL-schema&nbsp;&nbsp;</td></tr></table>
<table width="100%" cellspacing="0" cellpadding="0" border="0">
<tr>
    <td><p>While there is currently no SQL99 standard for the  ALTER VIEW , it is important to note that this command behaves differently in each major vendor application that supports it. Oracle uses this command to recompile a view; Microsoft SQL Server uses this command to allow modifications to a  view without also updating any dependent stored procedures, triggers, or permissions. </p>
    </td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
  <td>
  <table border="1" >
<tr><th>Vendor</th>
<th>Command</th></tr>
<tr><td>SQL Server</td><td>Supported, with variations</td></tr><tr><td>MySQL</td><td>Not supported</td></tr><tr><td>Oracle</td><td>Supported, with variations</td></tr><tr><td>PostgreSQL</td><td>Not supported</td></tr></table>
</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
 </tr>

<tr>
    <td valign="top" colspan="2" class="description"><span class="title">SQL99 Syntax and Description</span></td>
 </tr>
   <tr>
    <td><p>Currently, there is no SQL99 standard for this command. </p>
    </td>
  </tr>
   <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
 <td valign="top" colspan="2" class="description"><span class="title">
  Microsoft SQL Server Syntax and Variations</span></td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
  <td>
  <span class="programlisting">
  <pre>ALTER VIEW  view_name
  [(
  column
  [,...n])] [WITH {ENCRYPTION | SCHEMABINDING | VIEW_METADATA] AS
  select_statement
  [WITH CHECK OPTION]</pre></span>
  </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>As with the  CREATE VIEW statement,  ALTER VIEW allows a programmer to specify the column aliases that the view uses to name the columns, as well as the entire  SELECT statement that is the core component of the view. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The other clauses of the  ALTER VIEW statement are described under the  CREATE VIEW statement. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Microsoft SQL Server can maintain the column permissions only if the column names remain the same after the command has been executed. The  ENCRYPTION keyword allows the encryption of the views code within the syscomments system table in SQL Server. The keywords  CHECK OPTION force all data modifications executed against the view to pass the criteria of its defining  select_statement . If the view previously contained either of these options, they must be enabled with the  ALTER VIEW statement to stay active. </p>
    </td>
     <tr>
	    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  </tr>
  <tr>
 <td valign="top" colspan="2" class="description"><span class="title">
  Oracle Syntax and Variations</span></td>
  </tr>
  <tr>
  	  <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
  <td>
  <span class="programlisting">
  <pre>ALTER VIEW [user.] view_name COMPILE</pre></span>
  </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The  ALTER VIEW statement  recompiles a view in Oracle. It is useful to validate a view after making changes to a base table. A view becomes invalid if its base tables have changed and it is not recompiled. </p>
    </td>
  </tr>
  <tr>
  	    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
  <td valign="top" colspan="2" class="description"><span class="title">
  Example</span></td>
  </tr>
  <tr>
    <td><p>This example from SQL Server creates a view called  <span class="emphasis">california_authors</span> that contains authors from California. Then,  ALTER VIEW is used to expand and replace the view: </p>
    </td>
  </tr>
  <tr>
    	    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td>
    <span class="programlisting">
<pre>CREATE VIEW california_authors
AS
SELECT au_lname, au_fname, city, state
FROM authors
WHERE state = 'CA'
WITH CHECK OPTION
GO

ALTER VIEW california_authors
AS
SELECT au_fname, au_lname, address, city, state, zip
FROM pubs..authors
WHERE state = "CA"
GO</pre></span>
    </td>
  </tr>
</table>
</div>

<DIV id="CALL">
<table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td Width="50%"align="left" class="name" valign="top">CALL <td Width="50%" align="right" class="name"valign="top">SQL-control&nbsp;&nbsp;</td></tr></table>
<table width="100%" cellspacing="0" cellpadding="0" border="0">

  <tr>
    <td><p>The  CALL statement invokes a stored procedure. </p>
    </td>
  </tr>
  <tr>
        <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
    </tr>
    <tr>
  <td>
  <table border="1" >
<tr><th>Vendor</th>
<th>Command</th></tr>
<tr><td>SQL Server</td><td>Not supported</td></tr><tr><td>MySQL</td><td>Not supported</td></tr><tr><td>Oracle</td><td>Supported</td></tr><tr><td>PostgreSQL</td><td>Supported</td></tr></table>
<tr>
        <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
    </tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">SQL99 Syntax and Description</span>
    </td>
    </tr>
    <tr>
	        <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
    </tr>
    <tr>
    <td>
    <span class="programlisting">
     <pre>CALL procedure_name [(parameter [,...n] )]</pre></span>
     </td>
     </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The  CALL statement makes it easy to invoke a stored procedure. Simply provide the name of the stored procedure and include any parameters used by the stored procedure, enclosing them within parentheses. If the stored procedure has only  OUT parameters, or has no parameters, empty parentheses may be included. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>
  Microsoft SQL Server does not support the
  CALL statement. However, nearly identical functionality can be achieved using the  EXECUTE  statement. Refer to the vendor documentation for a full explanation of this SQL Server extension.
  </p>
    </td>
  </tr>
  <tr>
          <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
      </tr>
  <tr>
    <td valign="top" colspan="2" class="description"><span class="title">
  Oracle Syntax and Variations</span>
    </td>
    </tr>
    <tr>
	        <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
    </tr>
    <tr>
    <td>
    <span class="programlisting">
  <pre>CALL [schema.][{type_name | package_name}.]procedure_name@dblink
[(parameter [,...n] )]
[INTO :variable_name [INDICATOR :indicator_name] ]</pre></span>
  </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Oracle allows the  CALL statement to invoke standalone stored procedures,  functions,  methods, as well as stored procedures and functions contained within a type or package. If the procedure or function resides in another database, simply declare the database via a  dblink statement, stating where the object resides, as part of the  CALL statement. dblink must refer to a previously created database link. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>If the called routine is a function, Oracle requires the  INTO clause. Conversely, INTO can be used only when invoking functions. The variable that will store the value returned by the function must be provided. Finally, an indicator also may be specified to retain the condition of the host variable, if the function is a precompiled Pro*C/C++ routine. </p>
    </td>
  </tr>
 <tr>
          <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
      </tr>
  <tr>
    <td valign="top" colspan="2" class="example"><span class="title">
  Example</span></td>
  </tr>
  <tr>
    <td><p>This example creates a simple stored procedure, then calls it independently: </p>
    </td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><span class="programlisting"><pre>CREATE PROCEDURE update_employee_salary
(emp_id NUMBER, updated_salary NUMBER)
IS
BEGIN
  UPDATE employee SET salary = updated_salary WHERE employee_id =emp_id ;
END;

CALL update_employee_salary(1517, 95000);</pre></span>
    </td>
  </tr>
</table>
</div>

<DIV id="CASE">
<table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td Width="50%"align="left" class="name" valign="top">CASE<td Width="50%" align="right" class="name"valign="top">SQL-data&nbsp;&nbsp;</td></tr></table>
<table width="100%" cellspacing="0" cellpadding="0" border="0">

  <tr>
    <td><p>The  CASE function provides  IF-THEN-ELSE functionality within a  SELECT or  UPDATE statement. It evaluates a list of conditions and returns one value out of several possible values. </p>
    </td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
  <table border="1" >
<tr><th>Vendor</th>
<th>Command</th></tr>
<tr><td>SQL Server</td><td>Supported</td></tr><tr><td>MySQL</td><td>Supported</td></tr><tr><td>Oracle</td><td>Not Supported (refer to the DECODE function in vendor documentation for similar functionality)</td></tr><tr><td>PostgreSQL</td><td>Supported</td></tr></table>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>CASE has two usages: simple and searched.  Simple  CASE expressions compare one value, the  input_value , with a list of other values, and return a result associated with the first matching value.  Searched  CASE expressions allow the analysis of several logical conditions and return a result associated with the first one that is true. </p>
    </td>
  </tr>
  <tr>
            <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
        </tr>
    <tr>
    <td valign="top" colspan="2" class="description"><span class="title">
  SQL99 Syntax and Description</span>
  </td>
  </tr>
   <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
      <td>
    <span class="programlisting">
 <pre>-- Simple comparison operation
CASE input_value
WHEN when_condition THEN resulting_value
[...n]
[ELSE else_result_value]
END

-- Boolean searched operation
CASE
WHEN Boolean_condition THEN resulting_value
[...n]
[ELSE else_result_expression]
END</pre></span>
  </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>In the simple  CASE function, the  input_value is evaluated against each  WHEN clause. The  <span class="emphasis">resulting_value</span> is returned for the first TRUE instance of  <span class="emphasis">input_value</span> =  <span class="emphasis">when_condition</span> . If no  <span class="emphasis">when_condition</span> evaluates as TRUE, the  <span class="emphasis">else_result_value</span> is returned. If no <span class="emphasis"> else_result_value </span>is specified, then NULL is returned. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>In the more elaborate Boolean searched operation, the structure is essentially the same as the simple comparison operation, except that each  WHEN clause has its own Boolean comparison operation. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>In either usage, multiple  WHEN clauses are used, although only one  ELSE clause is necessary. </p>
    </td>
  </tr>
  <tr>
          <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
      </tr>
  <tr>
    <td valign="top" colspan="2" class="example"><span class="title">
  Example</span></td>
  </tr>

  <tr>
    <td><p>Here is a simple comparison operation where the  CASE function alters the display of the contract column to make it more understandable: </p>
    </td>
  </tr>
   <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
  <td>
  <span class="programlisting">
  <pre>SELECT  au_fname,
          au_lname,
          CASE contract
              WHEN 1 THEN 'Yes'
              ELSE 'No'
          END 'contract'
  FROM    authors
  WHERE   state = 'CA'</pre>
  </span>
  </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Here is an elaborate searched  CASE function in a  SELECT statement that reports how many titles have been sold in different year-to-date sales ranges: </p>
    </td>
  </tr>
   <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
  <td>
  <span class="programlisting">
<pre>SELECT CASE
           WHEN ytd_sales IS NULL  THEN 'Unknown'
           WHEN ytd_sales &lt;=   200 THEN 'Not more than 200'
           WHEN ytd_sales &lt;=  1000 THEN 'Between  201 and  1000'
           WHEN ytd_sales &lt;=  5000 THEN 'Between 1001 and  5000'
           WHEN ytd_sales &lt;= 10000 THEN 'Between 5001 and 10000'
           ELSE 'Over 10000'
       END 'YTD Sales',
       COUNT(*) 'Number of Titles'
FROM   titles
GROUP BY CASE
           WHEN ytd_sales IS NULL  THEN 'Unknown'
           WHEN ytd_sales &lt;=   200 THEN 'Not more than 200'
           WHEN ytd_sales &lt;=  1000 THEN 'Between  201 and  1000'
           WHEN ytd_sales &lt;=  5000 THEN 'Between 1001 and  5000'
           WHEN ytd_sales &lt;= 10000 THEN 'Between 5001 and 10000'
           ELSE 'Over 10000'
         END
ORDER BY MIN( ytd_sales )</pre>

  </span>
  </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>This results in the following: </p>
    </td>
  </tr>
   <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
  <td>
  <span class="programlisting">
<pre>YTD Sales              Number of Titles
---------------------- ----------------
Unknown                2
Not more than 200      1
Between  201 and  1000 2
Between 1001 and  5000 9
Between 5001 and 10000 1
Over 10000             3</pre>
</span>
  </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Here is an  UPDATE statement that applies discounts to all the titles. The more complicated command that follows discounts all personal computer-related titles by 25%, all other titles by 10%, and applies only a 5% discount to titles with year-to-date sales exceeding 10,000 units. </p>
    </td>
  </tr>
  <tr>
    <td><p>The following  UPDATE query uses a searched  CASE expression to perform price adjustment: </p>
    </td>
  </tr>
   <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
  <td>
  <span class="programlisting">
<pre>UPDATE  titles
SET     price = price *
        CASE
            WHEN ytd_sales &gt; 10000     THEN 0.95  -- 5% discount
            WHEN type = 'popular_comp' THEN 0.75  -- 25% discount
            ELSE 0.9                              -- 10% discount
        END
WHERE   pub_date IS NOT NULL</pre>
</span>
  </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The update has now completed three separate update operations in a single statement. </p>
    </td>
  </tr>

</table>
</div>

<DIV id="CAST"><table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td Width="50%"align="left" class="name" valign="top">CAST <td Width="50%" align="right" class="name"valign="top">SQL-data&nbsp;&nbsp;</td></tr></table>
<table width="100%" cellspacing="0" cellpadding="0" border="0">


  <tr>
    <td><p>The  CAST command explicitly converts an expression of one datatype to another. </p>
    </td>
  </tr>
   <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
  <table border="1" >
<tr><th>Vendor</th>
<th>Command</th></tr><tr><td>SQL Server</td><td>Supported</td></tr><tr><td>MySQL</td><td>Not supported</td></tr><tr><td>Oracle</td><td>Not supported</td></tr><tr><td>PostgreSQL</td><td>Supported</td></tr></table></td>
</tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">SQL99 Syntax and Description</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
    <pre>CAST(expression AS data_type[(length)])</pre></span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The  CAST function converts any expression, such as a column value or variable, into another defined datatype. The length of the datatype may be supplied optionally for those datatypes (such as  CHAR or  VARCHAR ) that support lengths.
</td>
</tr>

  <tr>
    <td><p>Be aware that some conversions, such as DECIMAL values to INTEGER
 , result in rounding operations. Also, some conversion operations may result in an error if the new datatype does not have sufficient space to display the converted value. </p>
    </td>
  </tr>
</p>
    </td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="example"><span class="title">
  Example</span>
  </td>
  </tr>

  <tr>
    <td><p>This example retrieves the year-to-date sales as a  CHAR and concatenates it with a literal string and a portion of the book title. It converts  <span class="emphasis">ytd_sales</span> to  CHAR(5), plus it shortens the length of the <span class="emphasis"> title </span>to make the results more readable: </p>
    </td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
  <td>
  <span class="programlisting">
<pre>SELECT CAST(ytd_sales AS CHAR(5)) + "Copies sold of " + CAST(title AS
VARCHAR(30))
FROM titles
WHERE ytd_sales IS NOT NULL
  AND ytd_sales &gt; 10000
ORDER BY ytd_sales DESC</pre>
  </span>
  </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>This results in the following: </p>
    </td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
  <tr>
    <td>
    <span class="programlisting">
<pre>---------------------------------------------------
22246 Copies sold of The Gourmet Microwave
18722 Copies sold of You Can Combat Computer Stress
15096 Copies sold of Fifty Years in Buckingham Pala</pre>
</span>
    </td>
  </tr>
</table>
</div>

<DIV id="CLOSE CURSOR">
<table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td Width="50%"align="left" class="name" valign="top">CLOSE CURSOR<td Width="50%" align="right" class="name"valign="top">SQL-data&nbsp;&nbsp;</td></tr></table>
<table width="100%" cellspacing="0" cellpadding="0" border="0">

  <tr>
    <td><p>The  CLOSE CURSOR command closes a server-side cursor created with a  DECLARE CURSOR statement. MySQL does not support server-side cursors, but does support extensive C programming extensions. </p>
    </td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
  <table border="1" >
<tr><th>Vendor</th>
<th>Command</th></tr>
<tr><td>SQL Server</td><td>Supported</td></tr><tr><td>MySQL</td><td>Not supported</td></tr><tr><td>Oracle</td><td>Supported</td></tr><tr><td>PostgreSQL</td><td>Supported</td></tr></table>
</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">SQL99 Syntax and Description</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>CLOSE { cursor_name }</pre>
 </span>
 </td>
 </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The  cursor_name is the name of the cursor created with the  DECLARE CURSOR command. </p>
    </td>
  </tr><tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="example"><span class="title">
  Example</span></td>
  </tr>

  <tr>
    <td><p>This example from Microsoft SQL Server opens a cursor and fetches all the rows: </p>
    </td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
  <tr>
  <td>
  <span class="programlisting">
<pre>DECLARE employee_cursor CURSOR FOR
  SELECT lname, fname
  FROM pubs.dbo.authors
  WHERE lname LIKE 'K%'

OPEN employee_cursor

FETCH NEXT FROM employee_cursor

WHILE @@FETCH_STATUS = 0
BEGIN
  FETCH NEXT FROM Employee_Cursor
END

CLOSE employee_cursor

DEALLOCATE employee_cursor</pre>
</span>
  </td.
  ></tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>
  The  DEALLOCATE statement in Microsoft SQL Server releases the resources and data structures used by the cursor, but Oracle, PostgreSQL, and MySQL do not use it. </p>
    </td>
  </tr>

</table>
</div>

<DIV id="COMMIT TRANSACTION">
<table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td Width="50%"align="left" class="name" valign="top">COMMIT TRANSACTION<td Width="50%" align="right" class="name"valign="top">SQL-transaction&nbsp;&nbsp;</td></tr></table>
<table width="100%" cellspacing="0" cellpadding="0" border="0">

  <tr>
    <td><p>The  COMMIT TRANSATION statement explicitly ends an open transaction, whether explicitly opened with  BEGIN, or implicitly opened as part of an  INSERT ,  UPDATE, or  DELETE statement. This command allows the manual and permanent end to a  data-manipulation operation. </p>
    </td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
  <table border="1" >
<tr><th>Vendor</th>
<th>Command</th></tr>
<tr><td>SQL Server</td><td>Supported, with variations</td></tr><tr><td>MySQL</td><td>Not supported</td></tr><tr><td>Oracle</td><td>Supported</td></tr><tr><td>PostgreSQL</td><td>Supported</td></tr></table>
</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">SQL99 Syntax and Description</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
    <pre>COMMIT [WORK]</pre></span>
    </td>
    </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>In addition to finalizing a single or group of data-manipulation operation(s),  COMMIT has some interesting effects on other aspects of a transaction. First, it closes any associated open  cursors. Second, any temporary table(s) specified with  ON COMMIT DELETE ROWS are cleared of data. Third, all  locks opened by the transaction are released. Finally, all deferred constraints are checked. If the deferred constraints are violated, the transaction is rolled back. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Please note that SQL99 dictates that  transactions are  <span class="emphasis">implicitly opened </span>when one of these statements is executed:
<ul>
<li>ALTER</li>
<li>CLOSE</li>
<li>COMMIT AND CHAIN (new for SQL99)</li>
<li>CREATE</li>
<li>DELETE</li>
<li>DROP</li>
<li>FETCH</li>
<li>FREE LOCATOR</li>
<li>GRANT</li>
<li>HOLD LOCATOR</li>
<li>INSERT</li>
<li>OPEN</li>
<li>RETURN</li>
<li>REVOKE</li>
<li>ROLLBACK AND CHAIN (new for SQL99)</li>
<li>SELECT</li>
<li>START TRANSACTION (new for SQL99)</li>
<li>UPDATE</li>
</ul>
</p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>SQL99 offers the new, optional keywords  AND CHAIN . None of our vendors yet support this command. This new syntax is: </p>
    </td>
  </tr>
  <tr>
  <td>
  <span class="programlisting">
  <pre>COMMIT [WORK] [AND [NO] CHAIN]</pre>
  </span>
  </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The  AND CHAIN option tells the DBMS to treat the following transaction as if it were a part of the preceding. In effect, the two transactions are separate units of work, but they share a common transaction environment (such as transaction isolation level). The  AND NO CHAIN option simply ends the single transaction. The  COMMIT command is functionally equivalent to the command  COMMIT WORK AND NO CHAIN . </p>
    </td>
  </tr>
   <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="description"><span class="title">
  Microsoft SQL Server Syntax and Variations</span>
  </td>
  </tr>
   <tr>
        <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td>
  <span class="programlisting">
<pre>COMMIT [TRAN[SACTION] [transaction_name | @tran_name_variable] ]
|
COMMIT [WORK]
GO</pre>

  </span>
  </tr>
  </td>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Microsoft SQL Server allows a specific, named transaction to be made permanent. The  COMMIT command must be paired with a  BEGIN TRAN command. The  COMMIT TRANSACTION syntax allows programmers to specify an explicit transaction to close or to store a transaction name in a variable. Curiously, SQL Server still commits only the last open transaction, despite the name of the transaction that is specified. When using  COMMIT WORK , a transaction name or a variable containing a transaction name may not be specified. </p>
    </td>
  </tr>
   <tr>
    <td><p>However, this syntax is misleading in the event of nested named triggers, since it closes the outermost transaction. Transactions in SQL Server are identified numerically by the  @@TRANCOUNT global variable. All transactions are committed only when  @@TRANCOUNT equals 0. </p>
    </td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="description"><span class="title">
  Oracle Syntax and Variations</span></td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
  <pre>COMMIT [WORK];</pre>
  </span>
  </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Oracle does not allow specifically named transactions (but it does allow savepoints); thus, the  COMMIT command simply makes permanent all data-manipulation operations since the last implicit or explicit  COMMIT statement was executed. Oracle allows the  WORK keyword, but it is entirely optional. </p>
    </td>
    </tr>
    <tr>
	      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
	  </tr>
	  <tr>
    <td valign="top" colspan="2" class="description"><span class="title">
    PostgreSQL Syntax and Variations</span></td>
    </tr>
    <tr>
		      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
	  </tr>
  <tr>
   <td>
<span class="programlisting">
  <pre>COMMIT [WORK | TRANSACTION];</pre>
  </span>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>In PostgreSQL, both the  WORK and  TRANSACTION keywords are optional. The effect of the command is the same with or without either keyword. When completed, all committed transactions have been written to disk and are visible to other users. </p>
    </td>
  </tr>
  <tr>
 		  <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
     <td valign="top" colspan="2" class="example"><span class="title">Example</span>
     </td>
  </tr>
  <tr>
  		  <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  	  </tr>
    <tr>
     <td>
    <span class="programlisting">
<pre>INSERT INTO sales VALUES('7896','JR3435','Oct 28
1997',25,'Net
60','BU7832');

COMMIT WORK;</pre>
     </span>
     </td>
  </tr>
</table>
</div>

<DIV id="CONCATENATION OPERATORS">
<table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td Width="50%"align="left" class="name" valign="top">CONCATENATION OPERATORS<td Width="50%" align="right" class="name"valign="top">SQL-data&nbsp;&nbsp;</td></tr></table>
<table width="100%" cellspacing="0" cellpadding="0" border="0">

  <tr>
    <td><p>When it is necessary to combine the data of multiple columns into a single column in  SELECT result set, the  concatenation symbol supported by the DBMS may be used to achieve this result. </p>
    </td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
<tr>
<td>
  <table border="1" >
<tr><th>Vendor</th>
<th>Command</th></tr>
<tr><td>SQL Server</td><td>Supported, with variations</td></tr><tr><td>MySQL</td><td>Supported, with variations</td></tr><tr><td>Oracle</td><td>Supported</td></tr><tr><td>PostgreSQL</td><td>Supported</td></tr></table>
</td>
</tr>
<tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">Example and Description</span>
    </td>
    </tr>
 <tr>
       <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>

  <tr>
  <td>
  <span class="programlisting">
    <pre>SELECT lname || ', ' || fname FROM customers WHERE cust_id = 41;</pre>
  </span>
  </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The ANSI standard is a  double-pipe mark (  || ), as shown in the previous code example, and is supported by Oracle and PostgreSQL. </p>
    </td>
  </tr>
    <tr>
    <td><p>Microsoft SQL Server uses a  plus sign ( + ) as its concatenation symbol. </p>
    </td>
  </tr>
   <tr>
    <td><p>MySQL uses the  CONCAT(string1, numeric1, string2, numeric2 [,...n]) function to accomplish concatenation. </p>
    </td>
  </tr>

</table>
</div>
<DIV id="CONNECT">
<table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td Width="50%"align="left" class="name" valign="top">CONNECT<td Width="50%" align="right" class="name"valign="top">SQL-connection&nbsp;&nbsp;</td></tr></table>
<table width="100%" cellspacing="0" cellpadding="0" border="0">


  <tr>
    <td><p>The  CONNECT statement establishes a connection to the DBMS and to a specific database within the DBMS. </p>
    </td>
  </tr>
  <tr>
        <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
    </tr>
  <tr>
  <td>
    <table border="1" >
  <tr><th>Vendor</th>
<th>Command</th></tr>
<tr><td>SQL Server</td><td>Supported, with limitations</td></tr><tr><td>MySQL</td><td>Not supported</td></tr><tr><td>Oracle</td><td>Supported</td></tr><tr><td>PostgreSQL</td><td>Not supported</td></tr></table>
</td>
</tr>
 <tr>
        <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
    </tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">SQL99 Syntax and Description</td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>CONNECT [TO] DEFAULT
| {[server_specification] [AS connection_name] [USER user_name ] }</pre>

 </span>
 </td>
 </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>If the  CONNECT statement is invoked without explicitly disconnecting, the old session becomes dormant and the new session becomes active. The period between issuing the  CONNECT and  DISCONNECT statements is commonly called a  <span class="emphasis">session</span> . Typically, users complete all work on a DBMS during an explicitly invoked session. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>
  The Oracle tool SQL*Plus uses the CONNECT command somewhat differently: to connect a user to a specific schema.
  </p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The  CONNECT TO DEFAULT statement has somewhat variable results, since different vendors implement it differently. But according to the standard, this command should initiate a default session with the server where the user authorization is the default and the current database is the default. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>In contrast to  CONNECT TO DEFAULT ,  CONNECT TO server_name allows you to specify the server. Here, the connection is made to the server that is explicitly named. In addition, the connection may be declared using  AS and a specific  user with  USER . </p>
    </td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="description"><span class="title">
  Oracle Syntax and Variations</span>
  </td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
  <td>
  <span class="programlisting">
 <pre> CONN[ECT] [[username/password] [AS [SYSOPER | SYSDBA] ] ]</pre>
  </span>
  </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The  CONNECT clause allows a database connection as a specific username. Alternately, a connection can be established for special privileges with  AS SYSOPER or  AS SYSDBA . If another connection is already open,  CONNECT commits any open transactions, closes the current session, and opens the new one. </p>
    </td>
  </tr>

  <tr>
    <td><p>
  PostgreSQL does not explicitly support the
CONNECT command. However, it does support the statement SPI_CONNECT
  under the Server Programming Interface and
PG_CONNECT under the PG/tcl programming package.
  </p>
    </td>
  </tr>

 <tr>
       <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
   </tr>
   <tr>
     <td valign="top" colspan="2" class="example"><span class="title">
   Example</span>
 </td>
  </tr>

  <tr>
    <td><p>To connect under a specific user ID, a user or automated program might issue the command: </p>
    </td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
  <td>
<span class="programlisting">
  <pre>CONNECT TO USER pubs_admin</pre>
  </span>
  </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>If the DBMS requires named connections, then alternative syntax might be used: </p>
    </td>
  </tr>CONNECT TO USER pubs_admin AS pubs_administrative_session;

  <tr>
    <td><p>Microsoft SQL Server supports  CONNECT TO only within embedded SQL (ESQL): </p>
    </td>
  </tr>
  <tr>
    <td>EXEC SQL CONNECT TO new_york.pubs USER pubs_admin
    </td>
  </tr>
</table>
</div>

<DIV id="CREATE DATABASE">
<table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td Width="50%"align="left" class="name" valign="top">CREATE DATABASE<td Width="50%" align="right" class="name"valign="top">SQL-schema&nbsp;&nbsp;</td></tr></table>
<table width="100%" cellspacing="0" cellpadding="0" border="0">

  <tr>
    <td><p>SQL99 does not actually contain a  CREATE DATABASE statement. The closest SQL99 gets to the  CREATE DATABASE statement is the  CREATE SCHEMA and  CREATE CATALOG statements. ( CREATE SCHEMA is detailed later.) However, it is nearly impossible to operate a SQL database without this command. Almost all database vendors support some version of this command. </p>
    </td>
  </tr>
  <tr>
          <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
      </tr>
    <tr>
    <td>
      <table border="1" >
    <tr><th>Vendor</th>
<th>Command</th></tr>
<tr><td>SQL Server</td><td>Supported, with variations</td></tr><tr><td>MySQL</td><td>Supported</td></tr><tr><td>Oracle</td><td>Supported</td></tr><tr><td>PostgreSQL</td><td>Supported, with variations</td></tr></table>
</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">SQL99 Syntax and Description</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
    <pre>CREATE database_name</pre>
  </span>
  </td>
  </tr>
    <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>In this syntax,  database_name is the identifier of the new database to be created. This command creates a new, blank database with a specific name. Most vendors require a user to be in the root, master, or system database to create a new database. Once the new database is created, it can then be filled with database objects (such as tables, views, triggers, and so on), and the tables populated with data. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">Microsoft SQL Server Syntax and Variations</span></td></tr>
  <tr>
    <td><p>In SQL Server and Oracle, the database is instantiated in a  pre-created file structure. These files act as go-betweens for the database system and the operating system. As a result, the SQL Server and Oracle variants of  CREATE DATABASE are similarly more sophisticated. </p>
    </td>
  </tr>

  <tr>
    <td><p>The syntax for Microsoft SQL Server looks like this: </p>
    </td>
  </tr>
   <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
  <td>
<span class="programlisting">
<pre>CREATE DATABASE database_name
[ ON [PRIMARY]
[ &lt;file&gt; [,...n] ]
[, &lt;file_group&gt; [,...n] ]
]
[ LOG ON { &lt;file&gt; [,...n]} ]
[ FOR LOAD | FOR ATTACH ]
GO</pre>

  </span>
  </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>In this implementation, not only can the name of the  database be supplied, but the location where the  database is to be stored also can be specified. Both Oracle and SQL Server use  files (a predefined space created on the disk structure) to act as a repository for databases. The databases may be stored on one or more files or filegroups. SQL Server also allows the transaction log to be placed in a separate location from the database using the  LOG ON clause. These functions allow sophisticated file planning for optimal control of disk I/O. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The  FOR LOAD clauses specify that the database will be immediately loaded from a backup after creation, thus speeding up the initial creation. The  FOR ATTACH clause tells SQL Server that the database is attached from an existing operating-system file structure, such as a DVD-ROM, CD-ROM, or portable hard drive. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">MySQL and PostgreSQL Syntax and Variations</span></td>
  </tr>

  <tr>
    <td><p>In MySQL, CREATE DATABASE essentially creates a new directory that holds the database objects. So, with these vendors, creating a database is just a step above creating a filesystem directory. The database is created as a directory under the vendor's main directory, and any new objects created within the database are placed in that folder. PostgreSQL provides the same functionality, although PostgreSQL allows the database's location to be specified using the  WITH LOCATION option: </p>
    </td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
  <tr>
  <td>
<span class="programlisting">
 <pre> CREATE DATABASE name [ WITH LOCATION = 'dbpath' ];</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>For example, to create the database  <span class="emphasis">sales_revenue</span> in the  /home/teddy/private_db directory: </p>
    </td>
  </tr>
   <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
  <td>
<span class="programlisting">
 <pre> CREATE DATABASE sales_revenue WITH LOCATION = '/home/teddy/private_db';</pre>
</span>
</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">
  Oracle Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>CREATE DATABASE [database_name]
[CONTROLFILE REUSE]
[LOGFILE [GROUP1 integer] file1 integer [K | M] [,...n] [REUSE]]
   [MAXLOGFILES integer]
   [[MAXLOGMEMBERS] integer]
   [[MAXLOGHISTORY] integer]
[DATAFILE file1 [AUTOEXTEND [,...n] [ON | OFF]]
      [NEXT integer [K | M]]
      [MAXSIZE [UNLIMITED | integer [K | M]]
   [MAXDATAFILES integer]
   [,...n]]
[MAXINSTANCES integer]
[MAXDATAFILES integer]
[ARCHIVELOG | NOARCHIVELOG]
{CHARACTER SET charset}
{NATIONAL CHARACTER SET charset};</pre>
  </span>
  </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p> CREATE DATABASE
  is a very powerful command in Oracle and should be utilized only by experienced DBAs. Novices should be aware that the existing database can be destroyed using this command.
  </p>
    </td>
  </tr>

  <tr>
    <td><p>As with Microsoft SQL Server, Oracle provides an extraordinary level of control over the database file structures beyond merely naming the database and specifying a path for the database files. Also unique to the Oracle environment is the  INIT.ORA file, which specifies the database name and a variety of other options when creating and starting up the database. The  INIT.ORA file always must be used and point to the control files, or the database does not start up. </p>
    </td>
  </tr>

  <tr>
    <td><p>When  the file1 [,...n] option is available, the filename and file size may be specified in bytes, kilobytes, or megabytes in this format: </p>
    </td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
  <td>
<span class="programlisting">
  <pre>'file_path_and_name' SIZE bytes [K | M] REUSE</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The  [K | M] options multiply the file's byte size by 1024 and 1048576, respectively. While the  REUSE option creates the file if it does not exist, and reuses it if it does, the  CONTROLFILE REUSE option causes control files to be overwritten. Similarly,  LOGFILE . . . REUSE causes logfiles to be overwritten. </p>
    </td>
  </tr>

  <tr>
    <td><p>When a group of logfiles are listed, they are usually shown in parentheses. The parentheses aren't needed when creating a group with only one member, but this is seldom done. Here's an example of a parenthetical list of logfiles: </p>
    </td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
  <td>
<span class="programlisting">
<pre>CREATE DATABASE publications
LOGFILE ('/s01/oradata/loga01','/s01/oradata/loga02') SIZE 5M
DATAFILE</pre>
  </span>
  </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Additionally, the  LOGFILE and  DATAFILE options and suboptions allow precise control of the size and growth patterns of the database's redo logs and database files. The  MAXLOGFILES and  MAXDATAFILES define the absolute upper limit of files allowed for redo logs and database files, respectively. When  AUTOEXTEND is enabled, the datafile grows in increments of  NEXT until it reaches  MAXSIZE, unless it is set to  UNLIMITED .  MAXLOGMEMBERS controls the maximum number of copies of a redo log group.  MAXLOGHISTORY , used in Oracle Parallel Server, controls the maximum number of archived redo logs so that the right amount of space is recorded in the control file. </p>
    </td>
  </tr>

  <tr>
    <td><p>The  MAXINSTANCES parameter sets the maximum number of instances that may mount the database being created.  ARCHIVELOG |  NOARCHIVELOG are mutually exclusive options that define how redo logs operate.  ARCHIVELOG saves data to an additional archiving file, providing for media recoverability. Both options provide recoverability, although  NOARCHIVELOG (the default) usually does not provide media recovery.  CHARACTER SET , which is operating-system dependent, controls the language and character set in which the data is stored. </p>
    </td>
  </tr>
</table>
</div>

<DIV id="CREATE FUNCTION">
<table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td Width="50%"align="left" class="name" valign="top">CREATE FUNCTION<td Width="50%" align="right" class="name"valign="top">SQL-schema&nbsp;&nbsp;</td></tr></table>
<table width="100%" cellspacing="0" cellpadding="0" border="0">

  <tr>
    <td><p>The  CREATE FUNCTION statement creates a  user-defined function (UDF), which takes input arguments and returns a single value in the same way as  CAST( ) . A UDF can be called in a query just like any other system function. </p>
    </td>
  </tr>

  <tr>
    <td><p>See  Chapter 4 , for a full description of SQL functions and the individual vendor implementations. </p>
    </td>
  </tr>
  <tr>
          <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
      </tr>
    <tr>
    <td>
      <table border="1" >
    <tr><th>Vendor</th>
<th>Command</th></tr>
<tr><td>SQL Server</td><td>Supported, with variations</td></tr><tr><td>MySQL</td><td>Supported, with variations</td></tr><tr><td>Oracle</td><td>Supported, with variations</td></tr><tr><td>PostgreSQL</td><td>Supported, with variations</td></tr></table>
</td>
</tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The  CREATE FUNCTION statement allows database programmers to create user-defined functions. These functions, once created, can be called in queries and data-manipulation operations, such as  INSERT ,  UPDATE , and the  WHERE clause of  DELETE statements. Although the basic syntax for the statement was shown before, there is so much variety in how vendors have implemented the command that they are each described later in this section. </p>
    </td>
  </tr><tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">SQL99 Syntax and Description</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>CREATE FUNCTION function_name
[(parameter datatype attributes [,...n])]
RETURNS datatype

  [LANGUAGE {ADA | C | FORTRAN | MUMPS | PASCAL | PLI | SQL}]
  [PARAMETER STYLE {SQL | GENERAL}]
  [SPECIFIC specific_name]
  [DETERMINISTIC | NOT DETERMINISTIC]
  [NO SQL | CONTAINS SQL | READS SQL DATA | MODIFIES SQL DATA]
  [RETURNS NULL ON NULL INPUT | CALL ON NULL INPUT]
  [STATIC DISPATCH]

code block</pre>

</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The SQL99 standard for the  CREATE FUNCTION statement has a primary component and a more advanced component that is used less often. In most UDFs, users define the function name, any input parameters, and the value that the UDF returns. These form the basic uses of the command. </p>
    </td>
  </tr>

  <tr>
    <td><p>However, the SQL99 standard allows much more. The  LANGUAGE clause allows the language in which the function is written (e.g., PostgreSQL) to be declared. The  PARAMETER STYLE clause is used to declare a parameter style, other than the typical SQL style, via the  GENERAL keyword. (SQL is the default.) The  SPECIFIC declaration is used to further refine the function name in a user-defined type. The  DETERMINISTIC versus  NOT DETERMINISTIC clause tells the host DBMS whether the function will always return the same result when given the same input parameters (i.e., it is deterministic). Only deterministic functions may be used in constraints. </p>
    </td>
  </tr>

  <tr>
    <td><p>The SQL data access clause tells the host DBMS whether the function contains  NO SQL , contains SQL code with  CONTAINS SQL , uses the  SELECT or  FETCH statement with  READS SQL DATA , or uses any of the data-modification statements with  MODIFIES SQL DATA . The default is  CONTAINS SQL . </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>For host languages that cannot handle nulls,  RETURNS NULL ON NULL INPUT may be declared, telling the function to immediately return a null when handed a null. In contrast,  CALL ON NULL INPUT (the default) processes the null parameter normally with possible unknown results. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The  STATIC DISPATCH clause is used for non-SQL functions that contain parameters that use user-defined types or  ARRAYS . </p>
    </td>
  </tr><tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">Microsoft SQL Server Syntax and Variations</span>
    </td>
    </tr>
    <tr>
	    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
	</tr>
	<tr>
	<td>
<span class="programlisting">
<pre>CREATE FUNCTION [owner_name.]function_name
( [ {@parameter1 datatype [=default]} [,...n] ] )
RETURNS {datatype | TABLE]
[WITH {ENCRYPTION | SCHEMABINDING}]
AS &lt;Transact-SQL body&gt;
GO</pre>
    </span>
    </td>
    </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>SQL Server functions can return multiple values via the  TABLE datatype. The  TABLE datatype is considered  inline if it has no accompanying column list and is defined with a single  SELECT statement. If the  RETURN clause returns multiple values via the  TABLE datatype, and if the  TABLE has defined columns and their datatypes, this function is a  multistatement table-valued function. </p>
    </td>
  </tr>
  <tr>
  <tr>
    <td><p>SQL Server requires that one or more user-supplied parameters be declared for a given user-defined function. All SQL Server datatypes are supported as parameters, except  timestamp . Values returned by the function can be any datatype except  timestamp ,  text ,  ntext , or  image . If an inline table value is required, the  TABLE option without an accompanying column list may be used. </p>
    </td>
  </tr>

  <tr>
    <td><p>Microsoft SQL Server user-defined functions, like many other database objects in SQL Server, may be created with the  ENCRYPTION or  SCHEMABINDING option. The  ENCRYPTION option tells SQL Server to encrypt the system column table that stores the text of the function, thus preventing unwarranted review of the function code. The  SCHEMABINDING option specifies that the function is bound to a specific database object, such as a table or view. That database object cannot be altered or dropped as long as the function exists (or maintains the  SCHEMABINDING option). </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The Transact-SQL body of code is either a single  SELECT statement for an inline function, in the format  RETURN (SELECT . . . ) , or a series of Transact-SQL statements for a multistatement operation. The Transact-SQL body held within a  BEGIN . . . END block cannot make any permanent changes to data or cause other lasting side effects. The last statement of the block must be an unconditional  RETURN that returns a single datatype value or  TABLE value. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The Transact-SQL block may not contain any global variables that return a perpetually changing value, such as  @@CONNECTIONS or  GETDATE . But it may contain those that return a single unchanging value, such as  @@SERVERNAME . A number of other restrictions exist, since the code cannot make any permanent changes to data or cause other lasting side effects. For example,  INSERT ,  UPDATE , and  DELETE statements may modify only  TABLE variables local to the function. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The following is an example of a scalar function that returns a single value: </p>
    </td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
  <td>
<span class="programlisting">
<pre>CREATE FUNCTION metric_volume -- Input dimensions in centimeters.
   (@length decimal(4,1),
   @width decimal(4,1),
   @height decimal(4,1) )
RETURNS decimal(12,3) -- Cubic Centimeters.
AS BEGIN
      RETURN ( @length * @width * @height )
   END
GO</pre>
</td>
</tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>This user-defined function could then be utilized in a query or other operation just like any other function. For example, the project name and metric volume for all construction projects with more than 300,000 in metric volume can be found like this: </p>
    </td>
  </tr><tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>SELECT project_name,
   metric_volume(construction_height,
      construction_length,
      construction_width)
FROM housing_construction
WHERE metric_volume(construction_height,
      construction_length,
      construction_width) &gt;= 300000
GO</pre>
</span
</td>
</tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>User-defined functions that return a table value are often selected as a result set value or are used in the  FROM clause of a  SELECT statement, just as a regular table is used. In a  FROM clause, a table alias function can be assigned just like a regular table. For example: </p>
    </td>
  </tr><tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>SELECT co.order_id, co.order_price
FROM   construction_orders AS co,
       fn_construction_projects('Cancelled') AS fcp
WHERE  co.construction_id = fcp.construction_id
ORDER BY co.order_id
GO</pre>
</span>
</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr><tr>
    <td valign="top" colspan="2" class="description"><span class="title">
MySQL Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>CREATE [AGGREGATE] FUNCTION function_name
RETURNS {STRING | REAL | INTEGER}
SONAME shared_program_library_name ;</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>CREATE FUNCTION under MySQL aggregates user-defined functions, such as  SUM( ) and  COUNT( ), using the  AGGREGATE option. The type of value returned may be either  STRING for character data,  REAL for floating point numbers, or  INTEGER for whole numbers. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The implementation of  CREATE FUNCTION in MySQL differs dramatically from the other vendors, since the procedural code must be C/C++ under an operating system that supports dynamic loading. The C/C++ program is named in the  shared_program_library_name option. The function may be compiled either directly into the MySQL server, making the function permanently available, or as a dynamically callable program. Since the user-defined function is written as a C/C++ program, a full description of this implementation is beyond the scope of this book. </p>
    </td>
  </tr><tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">Oracle Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>CREATE [OR REPLACE] FUNCTION [owner_name.]function_name
[(parameter1 [IN | OUT | IN OUT] [NOCOPY] datatype][,...n)]]
RETURN datatype [DETERMINISTIC | AUTHID {CURRENT_USER | DEFINER} ]
  {IS | AS} {PL/SQL block | external program};</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>In Oracle,  user-defined functions and stored procedures are very similar in composition and structure. The primary difference is that stored procedures cannot return a value to the invoking process, while a function may return a single value to the invoking process. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>In Oracle user-defined functions, the arguments and parameters specified include  IN ,  OUT , and  IN OUT . The  IN qualifier is provided when invoking the function, and it passes a value to the function;  OUT arguments pass a value back to the invoking process. In other words, the  IN qualifier is supplied by the user or process that calls the function, while the  OUT argument is returned by the function.  IN OUT arguments perform both  IN and  OUT functionality. The NOCOPY keyword is used to speed up performance when an  OUT or  IN OUT argument is very large, as with a varray or record datatype. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The  RETURN keyword specifies the datatype of the return value provided by the function. The  DETERMINISTIC keyword is used to speed processing by functions that have been declared explicitly as deterministic. The stored returning value might come from a materialized view, another concurrent function call to the same function, or a function-based index. The function also may be forced to run in the permission context of either the current user or the person who owns the function, using the  AUTHID CURRENT_USER or  AUTHID DEFINER phrases, respectively. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>For example, a construction project's profit can be determined by passing in the name of the project in this function: </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
 </tr>
<tr>
<td>
<span class="programlisting">
<pre>CREATE FUNCTION project_revenue (project IN varchar2)
RETURN NUMBER
AS
   proj_rev NUMBER(10,2);
BEGIN
   SELECT SUM(DECODE(action,'COMPLETED',amount,0)) -
          SUM(DECODE(action,'STARTED',amount,0))   +
          SUM(DECODE(action,'PAYMENT',amount,0))
   INTO proj_rev
   FROM construction_actions
   WHERE project_name = project;
   RETURN (proj_rev);
END;</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>In this example, the user-defined function accepts the project name as an argument. Then, it processes the project revenue, behind the scenes, by subtracting the starting costs from the completion payment and adding any other payments into the amount. The  RETURN(proj_rev); line returns the amount to the invoking process. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">PostgreSQL Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>CREATE FUNCTION name ( [ parameter1 [,...n] ] )
RETURNS datatype
AS {definition | object_file, link_symbol}
LANGUAGE {'C' | 'SQL' | 'PLPGSQL' | 'PLTCL' | 'PLTCLU' | 'PLPERL'
   | 'internal'}
[WITH ISCACHABLE];</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The PostgreSQL variation of  CREATE FUNCTION is among the most flexible implementations of the command. As with the other implementations,  parameters are invoked and return a value of datatype. PostgreSQL also allows  function  overloading where the same function name is allowed for different functions, as long as they accept distinct input parameters. </p>
    </td>
  </tr>
  <tr>
    <td><p>The  WITH ISCACHABLE datatype attribute optimizes PostgreSQL performance by indicating that the function always returns the same values when provided with the same parameter values. This setting then allows the optimizer to preevaluate the call of the function. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The  definition can be a string defining the  function (dependent on the language in which the function is written), such as an internal function name, the path and name of an object file, SQL query, or the text of a procedural language. The definition also can be an  object file and  link symbol to a C-language function. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Here's an example of a simple SQL function in PostgreSQL: </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>CREATE FUNCTION max_project_nbr
RETURNS int4
AS "SELECT MAX(project_ID) FROM housing_construction AS RESULT"
LANGUAGE 'sql';</pre>
</span>
</td>
</tr>
 <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The  LANGUAGE keyword allows the PostgreSQL function to call an external program. Since these are programs compiled in other languages, they are beyond the scope of this book. However, the  LANGUAGE `sql' clause should be used when writing SQL user-defined functions. </p>
    </td>
  </tr>

</table>
</div>
<DIV id="CREATE INDEX">
<table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td Width="50%"align="left" class="name" valign="top">CREATE INDEX<td Width="50%" align="right" class="name"valign="top">SQL-schema&nbsp;&nbsp;</td></tr></table>
<table width="100%" cellspacing="0" cellpadding="0" border="0">

  <tr>
    <td><p>Indexes are special objects built on top of tables that speed many  data-manipulation operations, such as  SELECT ,  UPDATE , and  DELETE statements. When an index is created, the location and spread of values (called  statistics) are built for the column that is indexed. The selectivity of a given  WHERE clause is usually based upon the quality of indexes that have been placed on the table. </p>
    </td>
  </tr><tr>
          <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
      </tr>
    <tr>
    <td>
      <table border="1" >
    <tr><th>Vendor</th>
<th>Command</th></tr>
<tr><td>SQL Server</td><td>Supported, with variations</td></tr><tr><td>MySQL</td><td>Supported, with variations</td></tr><tr><td>Oracle</td><td>Supported, with variations</td></tr><tr><td>PostgreSQL</td><td>Supported, with variations</td></tr></table>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The  CREATE INDEX command varies greatly among vendors. One reason is that some DBMS vendors use the  CREATE INDEX command to direct how the data in a given table is physically sorted and arranged on disk. </p>
    </td>
  </tr><tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">SQL99 Syntax and Description</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting"><pre>CREATE INDEX index_name ON table_name (column_name [, ...n])</pre></span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>All major vendors support  composite indexes , also known as  concatenated indexes . These indexes are used when two or more columns are best searched as a unit  for example, last name and first name. </p>
    </td>
  </tr><tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">Microsoft SQL Server Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>CREATE [UNIQUE] [CLUSTERED | NONCLUSTERED] INDEX <replaceable>index_name</replaceable>
ON {<replaceable>table | view}</replaceable> <replaceable>(column [ASC | DESC]</replaceable> [,...n])
[WITH [PAD_INDEX]
   [[,] FILLFACTOR = fillfactor]
   [[,] IGNORE_DUP_KEY]
   [[,] DROP_EXISTING]
   [[,] STATISTICS_NORECOMPUTE] ]
[ON filegroup]
GO</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Microsoft SQL Server has some important options. For example, ascending or descending indexes can be created on  tables, as can indexes on  views and calculated  columns (such as  UPPER(book_name) or  ((qty * amt) / royalty) ). SQL Server also allows specification of several optional arguments:  UNIQUE ,  CLUSTERED , or  NONCLUSTERED (the default).  Unique indexes require that no two values in the indexed column(s) are identical. Any attempt to insert or update a value so that there are duplicate values within the index will fail with an error.  Clustered indexes specify the physical sort order of the data on the disk.  Nonclustered indexes create a logical ordering of the table, which is used to speed data-manipulation operations. </p>
    </td>
  </tr>
   <tr>
    <td><p>SQL Server allows some additional syntax: </p>
    </td>
  </tr>
<tr>
<td>
<ul>
 <li>PAD_INDEX
  specifies that space should be left open on each index data page, according
   to the value established by the FILLFACTOR
  setting. </li>
  <li>FILLFACTOR
  is a percentage value (from 1 to 100) and tells SQL Server how much of its
    8K data page should be filled at the time the index is created. This is useful
    to reduce page splits when an 8K data page fills up, thus reducing I/O-intensive
    disk operations. Creating a clustered index with an explicitly defined fillfactor
    can increase the size of the index and speed up processing in certain circumstances.

  </li>
 <li>
  <filename>IGNORE_DUP_KEY</filename>
  controls what happens when a duplicate record is placed into a unique index through an insert or update operation. If this value is set for a column, only the duplicate row is excluded from the operation. If this value is not set, then all records in the operation (even nonduplicate records) are rolled back.
  </para>
  </li>
 <li>
<para>
  <filename>DROP_EXISTING</filename>
  is a helpful feature that tells SQL Server to drop any preexisting indexes
  and rebuild the specified index.
  </para>
  </li>
<li><para>
  <filename>STATISTICS_NORECOMPUTE</filename>
  stops SQL Server from recomputing index statistics. This can speed the
  <filename>CREATE INDEX</filename>
  operation, but it may mean that the index is less valuable.
  </para>
  </li>
<li><para>
  ON
  <filename>filegroup</filename>
  creates the index on a given preexisting filegroup. This creates the capability of placing indexes on a specific hard disk or RAID device.
  </para>
  </li>
  </ul>
  </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p> <span class="emphasis">Tip: </span>
  Creating an index usually takes 1.2 to 1.5 times more
  space than the table currently occupies. Most of that space is released after the index has been created.
  </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">
  MySQL Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr><tr>
<td>
<span class="programlisting"><pre>CREATE [UNIQUE] INDEX index_name ON table_name (column_name(length) [,...n])</pre></span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>MySQL supports the basic ANSI standard for the  CREATE INDEX statement, including the ability to build an  index upon multiple columns. An index may be defined further as  UNIQUE , forcing that index to accept only unique values. Any insertion of a non-unique value to the table with a  UNIQUE index is rejected. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Interestingly, MySQL also lets you build an index on the first  (length) characters of a  CHAR or  VARCHAR column. This can be useful when selectivity is sufficient in the first, say, 10 characters of a column, and in those situations where saving disk space is very important. </p>
    </td>
  </tr><tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">Oracle Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr><tr>
<td>
<span class="programlisting">
<pre>CREATE [UNIQUE | BITMAP] INDEX [owner_name.]index_name
ON [schema.]{table ({column | expression} [ASC | DESC] [,...n])
   | CLUSTER cluster_name}
[physical_attributes_clause | {LOGGING | NOLOGGING} |
  | [ONLINE] | [COMPUTE [STATISTICS] ]
  | {TABLESPACE tablespace_name | DEFAULT}
  | {COMPRESS int | NOCOMPRESS}
  | {NOSORT |REVERSE} ],...
 [GLOBAL PARTITION BY RANGE (column_list)
   (PARTITION [partition_name] VALUES LESS THAN (value_list)
   [physical_attributes_clause | {LOGGING | NOLOGGING} ] ,...n )
| LOCAL [ (PARTITION [partition_name]
   [physical_attributes_clause | {LOGGING | NOLOGGING} ] ,...n ) ] ]
[PARALLEL [int] | NOPARALLEL]</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Oracle allows the creation of indexes that are based not only on column values, but also on calculated expressions, such as  UPPER(book_name) or  ((qty * amt) / royalty) . Indexes may be  UNIQUE or non-unique. Oracle also allows the creation of a  BITMAP index, which is useful for columns that have few distinct values. In addition, Oracle allows the construction of both ascending ( ASC ) and descending ( DESC ) indexes. However, be aware Oracle treats  DESC indexes as function-based indexes. There is some difference in functionality between  ASC indexes and  DESC indexes. A cluster key also may be specified for the index using the  CLUSTER option. (Clusters are created with the Oracle-specific command  CREATE CLUSTER. ) </p>
    </td>
  </tr>
   <tr>
    <td><p>
  Oracle and SQL Server differ significantly in their definition of a clustered index. In SQL Server, a
  clustered index
  designates the physical sort order of the data held in a table. In Oracle, a cluster
  is a special index between two or more tables that greatly speeds join operations.
  </p>
    </td>
  </tr>
  <tr>
    <td><p>The  physical_attributes_clause refers to the settings that can be established for the following: </p>
    </td>
  </tr><tr>
<td>
<span class="programlisting">
<pre>[ PCTFREE int
| PCTUSED int
| INITRANS int
| MAXTRANS int
| STORAGE storage...]</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>PCTFREE is similar to SQL Server's  FILLFACTOR ; that is, it designates the percentage of free space to leave in the index for new entries and updates.  PCTFREE can be used only for indexes that are not  UNIQUE .  PCTUSED is the percentage of space available in a block that must exist before Oracle will allow insertions to that block.  PCTUSED is allowable for tables, but may not be used for indexes.  STORAGE ,  INITRANS, and  MAXTRANS are discussed in the  CREATE TABLE statement topic, in  Section . </p>
    </td>
  </tr>
  <tr>
    <td><p>The  TABLESPACE clause assigns the index to a specific tablespace. Leaving out the  TABLESPACE clause places the index on the default tablespace, or the  DEFAULT keyword achieves the same results. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>LOGGING tells Oracle to log the creation of the index on the redo log file, while  NOLOGGING prevents such logging. This keyword also sets the default behavior for subsequent bulk loads using Oracle Direct Loader. When building index partitions, there are some special behaviors for these keywords, so refer to the vendor documentation when attempting such activities. </p>
    </td>
  </tr>
  <tr>
    <td><p>ONLINE tells Oracle to allow data manipulations on the table while the index
  is being created. The COMPUTE STATISTICS command collects statistics while
  the index is created. The statistics are collected at relatively little cost.<filename>COMPRESS</filename>
  activates key compression on nonpartitioned indexes, which frees space by eliminating repeated key values. The integer value that accompanies
  <filename>COMPRESS</filename>
  gives the number of prefix columns to compress.
  <filename>NOCOMPRESS</filename>
  , the default, disables compression.
</p>
    </td>
  </tr>
  <tr>
    <td><p>
Oracle allows the creation of
  partitioned indexes and tables with the
  <filename>PARTITION</filename>
  clause. Consequently, Oracle's indexes also support partitioned tables. The
  <filename>LOCAL</filename>
  clause tells Oracle to create separate indexes for each partition of a table. The
  <filename>GLOBAL</filename>
  clause tells Oracle to create a common index for all the partitions, though specific index value ranges may differ from the ranges stored by the partitions.
</p>
    </td>
  </tr>
  <tr>
    <td><p>  The
  <filename>NOSORT</filename>
  option allows an index to be created quickly for a column that is already sorted in ascending order. If the values of the column are not in perfect ascending order, the operation aborts, allowing a retry without the
  <filename>NOSORT</filename>
  option.
  <filename>REVERSE</filename>
  , by contrast, places the index blocks in storage by reverse order (excluding rowed).
  <filename>REVERSE</filename>
  is mutually exclusive of
  <filename>NOSORT</filename>
  and cannot be used on a bitmap index or an index-organized table. </p>
    </td>
  </tr>
  <tr>
    <td><p>  The
  <filename>PARALLEL</filename>
  clause allows for the parallel creation of the index by distinct CPUs to speed the operation. An optional integer value may be supplied to define the exact number of parallel threads used in the operation.
  <filename>NOPARALLEL</filename>
  , the default, causes the index to be created serially. </p>
    </td>
  </tr><tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">
    PostgreSQL Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>CREATE [UNIQUE] INDEX index_name ON table
[USING [BTREE | RTREE | HASH] ]
(function_name (column [operator_class] [, ...] ))</pre>
</span>
</td>
</tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>
  PostgreSQL allows the creation of standard ascending-order
  indexes, as well as
  <filename>UNIQUE</filename>
  indexes. Its implementation also includes a performance enhancement under the
  <filename>WITH access_method</filename>
  clause. This clause allows one of three dynamic access methods to optimize performance:
</p>
    </td>
  </tr>
  <tr>
  <td>
<ul>
<li> <filename>BTREE</filename>
  <para>This is the default method when no other is specified. This method utilizes Lehman-Yao high-concurrency btrees.</para>
</li>
<li>  <filename>RTREE</filename>
  <para>This method utilizes standard rtrees using Guttman's quadratic-split algorithm.</para>
</li>
  </varlistentry>
<li>  <filename>HASH</filename>
  </term>
 </li>
  <para>This method is an implementation of Litwin's linear hashing.</para>

  </li>

  </ul>
  </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>

  In PostgreSQL, columns also may have an associated
  <filename>operator class</filename>
  based on the datatype of the column. An operator class specifies the operators for a particular index. Although users are free to define any valid operator class for a given column, the default operator class is the appropriate operator class for that field type.
  </p>
    </td>
  </tr>
  <tr>
    <td><p>
 PostgreSQL also allows users to define an index using a function, a user-defined function, or an expression. For example, an index could be defined on
  <filename>UPPER(book_name)</filename>
  to speed a transformation operation that is regularly applied to the base data of the index.
</p>
    </td>
  </tr>

<tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="example"><span class="title">
  Example</span>
</td>
</tr>

  <tr>
    <td><p>
  This example in MySQL creates a simple ascending index on the
  <span class="emphasis">au_id</span>
  column of the
  <span class="emphasis">authors</span>
  table:
  </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>CREATE INDEX au_id_ind
ON authors (au_id);</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>
  This example creates a
  <span class="emphasis">housing_construction</span>
  table (as used in the
  <filename>CREATE FUNCTION</filename>
  topic) and places a clustered index on it. This index physically orders the data on disk because the
  <filename>CLUSTERED</filename>
  clause is specified:
  </p>
  </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>CREATE TABLE housing_construction
   (project_number      INT NOT NULL,
   project_date         DATETIME NULL,
   project_name         VARCHAR(50)
       COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
   construction_color   NCHAR(20)
       COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
   construction_height  DECIMAL(4, 1) NULL ,
   construction_length  DECIMAL(4, 1) NULL ,
   construction_width   DECIMAL(4, 1) NULL ,
   construction_volume  INT NULL
GO

CREATE UNIQUE CLUSTERED INDEX project_id_ind
ON housing_construction(project_id)
GO</pre>
</span>
</td>
</tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>
  It is often necessary to build
  indexes that span several columns  i.e., a
  <span class="emphasis">concatenated key</span>
  . Here is an example:
  </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>CREATE UNIQUE INDEX project2_ind
ON housing_construction(project_name, project_date)
WITH PAD_INDEX, FILLFACTOR = 80
GO</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>
  Adding the
  <filename>PAD_INDEX</filename>
  clause and setting the
  <filename>FILLFACTOR</filename>
  to 80 tells SQL Server to leave the index and data pages 80% full, rather than 100% full.
  </p>
    </td>
  </tr>
  <tr>
    <td><p>The following example constructs the same index in Oracle on a specific tablespace with specific instructions for how the data is to be stored:</p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>CREATE UNIQUE INDEX project2_ind
ON housing_construction(project_name, project_date)
STORAGE (INITIAL 10M NEXT 5M PCTINCREASE 0)
TABLESPACE construction;</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>
  If the
  <span class="emphasis">housing_construction</span>
  table is created as a partitioned table on an Oracle server, a partitioned index should also be created:
  </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>CREATE UNIQUE CLUSTERED INDEX project_id_ind
ON housing_construction(project_id)
GLOBAL PARTITION BY RANGE (project_id)
   (PARTITION part1 VALUES LESS THAN ('K')
      TABLESPACE construction_part1_ndx_ts,
   PARTITION part2 VALUES LESS THAN (MAXVALUE)
      TABLESPACE construction_part2_ndx_ts);</pre>
</span>
    </td>
  </tr>
</table>
</div>
<div id="CREATE PROCEDURE"><table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td Width="50%" align="left" class="name" valign="top">CREATE PROCEDURE<td Width="50%" align="right"class="name" valign="top">SQL-schema&nbsp;&nbsp;</td></tr></table>
<table width="100%" cellspacing="0" cellpadding="0" border="0">
  <tr>
    <td><p>Stored procedures provide conditional processing and programmatic capabilities in the database-server environment. Stored procedures are capsules of programming code that may accept passed parameters and accomplish complicated tasks. Stored procedures also are very valuable because they are precompiled: they execute their tasks quickly and efficiently because the database optimizer has already built an execution plan for the code. </p>
    </td>
  </tr><tr>
          <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
      </tr>
    <tr>
    <td>
      <table border="1" >
    <tr><th>Vendor</th>
<th>Command</th></tr>
<tr><td>SQL Server</td><td>Supported</td></tr><tr><td>MySQL</td><td>Not supported (see the CREATE FUNCTION command)</td></tr><tr><td>Oracle</td><td>Supported</td></tr><tr><td>PostgreSQL</td><td>Not supported</td></tr></table></td>
</tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Like many of the other CREATE statements, the vendors have built a great deal of variety into this command. </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">SQL99 Syntax and Description</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>CREATE PROCEDURE procedure_name
[parameter data_type attributes ][,...n]
AS
code block</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>For a more complete listing of the SQL99 syntax, refer to CREATE FUNCTION . The advanced features of CREATE FUNCTION also apply to CREATE PROCEDURE . </p>
    </td>
  </tr>
   <tr>
    <td><p>Because each vendor has implemented his own procedural extensions to the SQL language, a broad discussion about coding stored procedures is not appropriate for this book. However, the basics of stored-procedure programming is discussed. Other O'Reilly books, such as Transact-SQL Programming, by Kevin Kline, Lee Gould & Andrew Zanevsky (1999), and Oracle PL/SQL Programming, Second Edition, by Steven Feuerstein with Bill Pribyl (1997), provide excellent discussions about their respective programming languages. </p>
    </td>
  </tr>

<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">Microsoft SQL Server Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>CREATE PROC[EDURE] procedure_name [;<replaceable>number</replaceable>]
[{@<replaceable>parameter_name datatype</replaceable>}<replaceable> </replaceable>[VARYING] [<userinput>= </userinput><replaceable>default</replaceable>] [OUTPUT]][,...<replaceable>n</replaceable>]
[WITH {RECOMPILE | ENCRYPTION | RECOMPILE, ENCRYPTION}]
[FOR REPLICATION]
AS
Transact-SQL_block
GO</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>In addition to a procedure name, Microsoft SQL Server also lets you specify a version number in the format procedure_name;1, where 1 is an integer indicating the version number. This allows multiple versions of a single stored procedure to be accessed. </p>
    </td>
  </tr>
    <tr>
    <td><p>Like tables (see CREATE TABLE ), local and global temporary procedures may be declared by prefixing a pound symbol (#) and double-pound symbol (##) to the name of the procedure, respectively. Temporary procedures exist only for the duration of the user or process session that created them. When that session ends, the temporary procedure automatically deletes itself. </p>
    </td>
  </tr>

    <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
   <tr>
    <td><p>A SQL Server stored procedure may have as many as 1024 input parameters, specified by the "at" symbol (@) and any acceptable SQL Server datatype. (Parameters of cursor datatype must be both VARYING and OUTPUT. ) The VARYING keyword is used only with parameters of the cursor datatype to indicate that the result set is constructed dynamically by the procedure. </p>
    </td>
  </tr>

    <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The values for input parameters must be supplied by the user or calling process. However, a default value can be supplied to allow the procedure to execute without a user- or process-supplied value. The default must be a constant or NULL, but it may contain wildcard characters, as discussed under the topic LIKE . </p>
    </td>
  </tr>

    <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Similarly, a parameter may be declared a return parameter by using the OUTPUT keyword. The value stored in the return parameter is passed back to any calling procedure through the return variables of the SQL Server EXEC[UTE] command. Output parameters can be any datatype except TEXT and IMAGE . </p>
    </td>
  </tr>
   <tr>
    <td><p>The options WITH RECOMPILE , WITH ENCRYPTION , and WITH RECOMPILE, ENCRYPTION are as follows: </p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>WITH
  RECOMPILE:<br>
Tells SQL Server not to store a cache plan for the stored procedure,
but instead to recompile the cache plan each time it is executed. This is useful
when using atypical or temporary values in the procedure.</p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>WITH ENCRYPTION:<br>
  Encrypts the code of the stored procedure in the SQL Server syscomments
table. </p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>WITH RECOMPILE, ENCRYPTION:<br>
Allows both options at one time. <br>
</p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The FOR REPLICATION clause, which is mutually exclusive of WITH RECOMPILE
  , disables execution of the stored procedure on a subscribing server. It is
  used primarily to create a filtering stored procedure that is executed only
  by SQL Server's built-in replication engine. </p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The AS Transact-SQL_block clause contains one or more Transact-SQL commands, up to a maximum size of 128 MB. Microsoft SQL Server allows most valid Transact-SQL statements, but SET SHOWPLAN_TEXT and SET SHOWPLAN_ALL are prohibited. Some other commands have restricted usages within stored procedures, including ALTER TABLE , CREATE INDEX , CREATE TABLE , all DBCC statements, DROP TABLE , DROP INDEX , TRUNCATE TABLE , and UPDATE STATISTICS . </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>SQL Server allows deferred name resolution, meaning that the stored procedure compiles without an error even though it references an object that has not yet been created. It creates an execution plan and fails only at execution time, if the object still doesn't exist. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Stored procedures can be nested easily in SQL Server. Whenever a stored procedure invokes another stored procedure, the system variable @@NESTLEVEL is incremented by 1. It is decreased by 1 when the called procedure completes. SELECT @@NESTLEVEL is specified to find how many layers of nesting occur in the current session. </p>
    </td>
  </tr>

<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">Oracle Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>CREATE [OR REPLACE] PROCEDURE [owner_name.]procedure_name
[(parameter1 [IN | OUT | IN OUT] [NOCOPY] datatype][,...n)]]
[AUTHID {CURRENT_USER | DEFINER} ]
{IS | AS} {PL/SQL block | LANGUAGE {java_spec | C_spec}};</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>In Oracle, user-defined functions and stored procedures are very similar in composition and structure. The primary difference is that stored procedures cannot return a value to the invoking process, while a function may return a single value to the invoking process. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>In an Oracle stored procedure, the specified arguments and parameters include IN , OUT , or IN OUT . The IN qualifier is provided when invoking the function and passes a value in to the function, while OUT arguments pass a value back to the invoking process. In other words, the IN qualifier is supplied by the user or process that calls the function, while the OUT argument is returned by the function. IN OUT arguments perform both IN and OUT functionality. The NOCOPY keyword is used to speed performance when an OUT or IN OUT argument is very large, like a varray or record datatype. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The function also may be forced to run in the permission context of either the current user or the person who owns the function, using the AUTHID CURRENT_USER or AUTHID DEFINER phrases, respectively. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Oracle also allows the procedure to call external programs through the LANGUAGE keyword. The external programs must be C or Java programs; the specific syntax for calling external programs is beyond the scope of this book. Refer to the vendor documentation for more information on this capability. </p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>
<span class="emphasis">Tip:</span> Microsoft SQL Server stored procedures <span class="emphasis">can</span> be used to return result sets, while Oracle stored procedures <span class="emphasis">cannot</span> return a result set to the calling process.
</p>
    </td>
  </tr>

<tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="example"><span class="title">
  Example</span>
</td>
</tr>
  <tr>
    <td><p>This Microsoft SQL Server stored procedure generates a unique 22-digit value (based on elements of the system date and time) and returns it to the calling process: </p>
    </td>
  </tr>
  <tr>
        <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><span class="programlisting">
<pre>-- A Microsoft SQL Server stored procedure
CREATE PROCEDURE get_next_nbr
   @next_nbr CHAR(22) OUTPUT
AS
BEGIN
  DECLARE @random_nbr INT
  SELECT @random_nbr = RAND(  ) * 1000000

SELECT @next_nbr =
  RIGHT('000000' + CAST(ROUND(RAND(@random_nbr)*1000000,0))AS CHAR(6), 6) +
  RIGHT('0000' + CAST(DATEPART (yy, GETDATE(  ) ) AS CHAR(4)), 2) +
  RIGHT('000'  + CAST(DATEPART (dy, GETDATE(  ) ) AS CHAR(3)), 3) +
  RIGHT('00'   + CAST(DATEPART (hh, GETDATE(  ) ) AS CHAR(2)), 2) +
  RIGHT('00'   + CAST(DATEPART (mi, GETDATE(  ) ) AS CHAR(2)), 2) +
  RIGHT('00'   + CAST(DATEPART (ss, GETDATE(  ) ) AS CHAR(2)), 2) +
  RIGHT('000'  + CAST(DATEPART (ms, GETDATE(  ) ) AS CHAR(3)), 3)
END
GO</pre>
</span>
    </td>
  </tr>
</table>
</div>

<div id="CREATE ROLE"><table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td Width="50%" align="left" class="name" valign="top">CREATE ROLE<td Width="50%" align="right"class="name" valign="top">SQL-schema&nbsp;&nbsp;</td></tr></table>
<table width="100%" cellspacing="0" cellpadding="0" border="0">
  <tr>
    <td><p>CREATE ROLE allows the creation of a named set of privileges that may be assigned to users of a database. When a user is granted a role, that user also gets all the privileges and permissions of that role. </p>
    </td>
  </tr><table border="1" >
<tr><td>SQL Server</td><td>Not supported</td></tr><tr><td>MySQL</td><td>Not supported</td></tr><tr><td>Oracle</td><td>Supported, with variations</td></tr><tr><td>PostgreSQL</td><td>Not supported</td></tr></table>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Microsoft SQL Server does not support the CREATE ROLE command, but has the equivalent capability via the system stored procedure sp_add_role . </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">SQL99 Syntax and Description</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>CREATE ROLE role_name [WITH ADMIN {CURRENT_USER | CURRENT_ROLE}]</pre></span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>This statement creates a new role, and differentiates that role from a host-DBMS user. The WITH ADMIN clause allows assigns a role immediately to the currently active user or currently active role. By default, the statement defaults to WITH ADMIN CURRENT_USER . </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">
Oracle Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>CREATE ROLE role_name [NOT IDENTIFIED | IDENTIFIED
   {BY password | EXTERNALLY | GLOBALLY}]</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>In Oracle, the role is created first, then granted privileges and permissions as if it is a user via the GRANT command. When users want to get access to the permissions of a role protected by a password, they use the SET ROLE command. If a password is placed on the role, any user wishing to access it must provide the password with the SET ROLE command. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Oracle ships with several preconfigured roles. CONNECT , DBA , and RESOURCE are available in all versions of Oracle. EXP_FULL_DATABASE and IMP_FULL_DATABASE are newer roles used for import and export operations. </p>
    </td>
  </tr>
<tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="example"><span class="title">
  Example</span>
</td>
</tr>
   <tr>
    <td><p>The following example uses CREATE to specify a new role in Oracle, GRANT it privileges, assign it a password with ALTER ROLE , and GRANT that role to a couple of users: </p>
    </td>
  </tr>
   <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><span class="programlisting">
    <pre>CREATE ROLE boss;

GRANT ALL ON employee TO boss;
GRANT CREATE SESSION, CREATE DATABASE LINK TO boss;

ALTER ROLE boss IDENTIFIED BY le_grande_fromage;

GRANT boss TO nancy, dale;</pre>
</span>
    </td>
  </tr>
</table>
</div>

<div id="CREATE SCHEMA"><table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td Width="50%" align="left" class="name" valign="top">CREATE SCHEMA<td Width="50%" align="right"class="name" valign="top">SQL-schema&nbsp;&nbsp;</td></tr></table>
<table width="100%" cellspacing="0" cellpadding="0" border="0">
  <tr>
    <td><p>This statement creates a schema  i.e., a named group of related objects. A schema is a collection of tables, views, and their associated permissions. The schema is associated with an existing, valid user ID (called the owner ). </p>
    </td>
  </tr><tr>
          <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
      </tr>
    <tr>
    <td>
      <table border="1" >
    <tr><th>Vendor</th>
<th>Command</th></tr>
<tr><td>SQL Server</td><td>Supported</td></tr><tr><td>MySQL</td><td>Not supported</td></tr><tr><td>Oracle</td><td>Supported, with variations</td></tr><tr><td>PostgreSQL</td><td>Not supported</td></tr></table>
</td></tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">SQL99 Syntax and Description</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>CREATE SCHEMA [schema_name] [AUTHORIZATION owner_name]
[DEFAULT CHARACTER SET char_set_name]
[PATH schema_name [,...n] ]

   [ &lt;create_table_statement1&gt; [...n] ]
   [ &lt;create_view_statement1&gt;  [...n] ]
   [ &lt;grant statement1&gt; [...n] ]</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The CREATE SCHEMA statement is a container that can hold many other CREATE and GRANT statements. As an option, a DEFAULT CHARACTER SET names the schema's default character set. The PATH also may be declared for any objects in the schema that reside on the filesystem. </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">
Microsoft SQL Server and Oracle Syntax</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>CREATE SCHEMA AUTHORIZATION owner_name
   [ &lt;create_table_statement1&gt; [...n] ]
   [ &lt;create_view_statement1&gt;  [...n] ]
   [ &lt;grant statement1&gt; [...n] ]</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>If any statement fails within the CREATE SCHEMA statement, then the entire statement fails. One good thing about CREATE SCHEMA is that the objects within do not need to be organized according to any dependency. For example, a GRANT statement normally could not be issued for a table that does not exist yet. However, all the GRANT statements first could be placed in the CREATE SCHEMA statement, followed by the CREATE statements where the grants are being given. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Many implementations do not explicitly support the CREATE SCHEMA command. However, they implicitly create a schema when a user creates database objects. On the other hand, Oracle creates a schema whenever a user is created. The CREATE SCHEMA command is simply a single-step method of creating all the tables, views, and other database objects along with their permissions. </p>
    </td>
  </tr>

<tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="example"><span class="title">
  Example</span>
</td>
</tr>
  <tr>
    <td><p>In Oracle, the CREATE SCHEMA does not create a schema  only CRE ATE USER does that. CREATE SCHEMA allows a user to perform multiple steps in one SQL statement. The following Oracle example places the permissions before the objects within the CREATE SCHEMA statement: </p>
    </td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
  <tr>
    <td><span class="programlisting">
    <pre>CREATE SCHEMA AUTHORIZATION emily
   GRANT SELECT, INSERT ON view_1 TO sarah
   GRANT ALL ON table_1 TO sarah

   CREATE VIEW view_1 AS
      SELECT column_1, column_2
      FROM table_1
      ORDER BY column_2

   CREATE TABLE table_1(column_1 INT, column_2 CHAR(20));</pre>
</span>
    </td>
  </tr>
</table>
</div>

<div id="CREATE TABLE"><table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td Width="50%" align="left" class="name" valign="top">CREATE TABLE<td Width="50%" align="right"class="name" valign="top">SQL-schema&nbsp;&nbsp;</td></tr></table>
<table width="100%" cellspacing="0" cellpadding="0" border="0">
  <tr>
    <td><p>The CREATE TABLE statement does what it says: create a table. However, most vendors also allow a wide variety of other functions to be exercised through the CREATE TABLE statement, such as the assignment of keys, cascading referential integrity, constraints, and default values. </p>
    </td>
  </tr><tr>
          <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
      </tr>
    <tr>
    <td>
      <table border="1" >
    <tr><th>Vendor</th>
<th>Command</th></tr>
<tr><td>SQL Server</td><td>Supported, with variations</td></tr><tr><td>MySQL</td><td>Supported, with variations</td></tr><tr><td>Oracle</td><td>Supported, with variations</td></tr><tr><td>PostgreSQL</td><td>Supported, with variations</td></tr></table>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>This command defines a table name, its constituent columns, and any properties to the columns and/or table. Typically, a great deal of consideration goes into the design and creation of a table. This discipline is known as <span class="emphasis">database design</span> . The discipline of analyzing the relationship of a table to its own data and to other tables within the database is known as <span class="emphasis">normalization</span> . </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p><span class="emphasis">Tip:</span>It is strongly recommended that programmers and developers study both database design and normalization principles thoroughly before issuing CREATE TABLE commands. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>In general, the table name always starts with an alphabetic character. The allowable length of the name varies by vendor; Oracle allows only 30 characters, but it can be much bigger than 30 characters when necessary. Numbers may be used in the name of the table, but do not use any symbol other than the underscore ( _ ). Some vendors allow many other symbols in the name of a table, but it's good practice not to use them since they can create confusing identifiers. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>When defining column characteristics, all vendors support the NULL and NOT NULL options. (A bare NULL is not a requirement of SQL99.) When a column is defined as NULL , regardless of its datatype, that column may contain null values. Typically, nullable columns consume an extra bit of space per record. If NOT NULL is specified, the column can never contain null values. Any INSERT operation that attempts to insert a null value or any UPDATE operation that attempts to modify a value to null on a NOT NULL column fails and is rolled back. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>All vendors also support the PRIMARY KEY declaration, at both the column- and table-level. A primary key is a special designation that describes how each row of a table is uniquely identified. The primary key is composed of one or more columns in the table that provide each row with a unique identity. A table may have only one primary key. All values in the primary key must be unique and may not be null. Foreign keys then can be declared on a table that establishes a direct relationship to the primary key of another table. In this way, parent/child or master/detail relationships among tables may be created. A cascading action may further augment this action. For example, a user may wish to prevent the deletion of a customer record from the <span class="emphasis">customer</span> table, if sales records exist for that customer in the <span class="emphasis">sales</span> table. The syntax for a foreign key varies among the vendors. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Most vendors also support a DEFAULT value for a given column. Any time a record is inserted in a table and no value is provided for the column, its default value is inserted. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The basic syntax for CREATE TABLE is shown here; this is enough to get started building tables and populating them with data: </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><span class="programlisting">
    <pre>CREATE TABLE table_name
   (
   column_name datatype[(length)] [NULL | NOT NULL],...n
   )</pre>
</span>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Here's a simple example: </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><span class="programlisting"><pre>CREATE TABLE housing_construction
   (project_number      INT NOT NULL,
   project_date         DATETIME NOT NULL,
   project_name         VARCHAR(50) NOT NULL,
   construction_color   NCHAR(20) NULL,
   construction_height  DECIMAL(4,1) NULL,
   construction_length  DECIMAL(4,1) NULL,
   construction_width   DECIMAL(4,1) NULL,
   construction_volume  INT NULL)
GO</pre>
</span>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>In Microsoft SQL Server, this statement defines a table called <span class="emphasis">housing_construction</span> that contains eight columns. Each column is defined as NULL or NOT NULL , with a datatype appropriate for the type of information it contains. Notice that the list of column definitions is always encapsulated in parentheses and that a comma closes each column definition when another definition follows it. </p>
    </td>
  </tr>
</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">SQL99 Syntax and Description</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>CREATE [GLOBAL TEMPORARY | LOCAL TEMPORARY] TABLE table_name
[ON COMMIT {PRESERVE ROWS | DELETE ROWS}
(column_name datatype attributes [,...n]
 | [LIKE  table_name]
 | [table_constraint][,...n] ]</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The SQL99 CREATE TABLE statement creates TEMPORARY tables that are instantiated when the table is created and are automatically dropped when the current user session ends. Temporary tables may be GLOBAL and available to all active user sessions, or LOCAL and available only to the user session that created it. An ON COMMIT value for the temporary table also may be specified. ON COMMIT PRESERVE ROWS preserves any data modifications to the temporary table on a COMMIT , while ON COMMIT DELETE ROWS flushes the table after a COMMIT . </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The LIKE table_name option creates a new table with the same column definitions and table constraints as a preexisting table. When using LIKE , column or table constraints do not need to be defined. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Because the implementation of CREATE TABLE varies so widely and the command is such an important one, each vendor implementation is dealt with separately and in detail. </p>
    </td>
  </tr>

<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">Microsoft SQL Server Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>CREATE TABLE [<replaceable>database_name</replaceable>.[<replaceable>owner</replaceable>]. | <replaceable>owner</replaceable>.] <replaceable>table_name</replaceable>
({column_name datatype [ [DEFAULT default_value]
   | {IDENTITY [(seed,increment) [NOT FOR REPLICATION]]]
   [ROWGIDCOL] ]
   [NULL | NOT NULL]
   | [{PRIMARY KEY | UNIQUE}
        [CLUSTERED | NONCLUSTERED]
        [WITH FILLFACTOR = int] [ON {filegroup | DEFAULT}] ]
   | [[FOREIGN KEY]
        REFERENCES reference_table[<span class="emphasis">(</span>reference_column[,...n])]
        [ON DELETE {CASCADE | NO ACTION}]
        [ON UPDATE {CASCADE | NO ACTION}]
        [NOT FOR REPLICATION]
   | [CHECK [NOT FOR REPLICATION] (expression)
   | [COLLATE collation_name]
|column_name AS computed_column_expression
[,...n]
|[table_constraint][,...n] )
[ON {filegroup | DEFAULT} ]
[TEXTIMAGE_ON {filegroup | DEFAULT} ]</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>SQL Server offers a plethora of options when defining a table, its columns, and its table-level constraints. SQL Server allows any column-level constraint to be named by specifying CONSTRAINT constraint_name . . ., and then the text of the constraint. Several constraints may be applied to a single column, as long as they are not mutually exclusive (for example, PRIMARY KEY and NULL ). </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>SQL Server also allows a local temporary table to be created, which is stored in the tempdb database, by prefixing a single pound sign (#) to the name of the table. The local temporary table is usable by the person or process that created it, and is deleted when the person logs out or the process terminates. A global temporary table, which is usable to all people and processes that are currently logged in, can be established by prefixing two pound signs (##) to the name of the table. The global temporary table is deleted when its process terminates or its creator logs out. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Since SQL Server supports built-in replication, many of the properties of a column can be set to NOT FOR REPLICATION , meaning that the values of an IDENTITY or FOREIGN KEY is not replicated to subscribing servers. This helps in situations in which different servers require the same table structures, but not the exact same data. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Also useful for replication is ROWGUIDCOL . This identifies a column as a global unique identifier, which ensures no two values are ever repeated across any number of servers. Only one such column may be identified per table. It does not, however, create the unique values itself. They must be inserted using the NEWID function. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The IDENTITY property, when applied to an integer column, is similar to MySQL's AUTO_INCREMENT , automatically creating and populating the column with a monotonically increasing number. However, it is more versatile and flexible. Where AUTO_INCREMENT always starts at 1, the IDENTITY starts counting at the value of seed . Where AUTO_INCREMENT increases by 1 each time a new row is inserted, IDENTITY increases by the value of increment . </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>In SQL Server, DEFAULT can be applied to any column except those with a timestamp datatype or an IDENTITY property. The DEFAULT must be a constant value such as a character string or a number, and a system function such as GETDATE( ) or NULL . </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>One PRIMARY KEY called name per table also may be specified, and multiple UNIQUE or FOREIGN KEY columns may be specified per table. They may be clustered or nonclustered, and may be defined with a starting fillfactor. Refer to the topic CREATE INDEX for more information. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>When specifying a FOREIGN KEY , the table and columns that maintain referential integrity may be specified using the REFERENCES clause. It can only reference columns that are defined as a PRIMARY KEY or UNIQUE index on the referencing table. A referential action may be specified to take place on the reference_table when the record is deleted or updated. If NO ACTION is specified, then nothing happens on the referring table when a record is deleted or updated. If CASCADE is specified, then the delete or update also takes place on the referring table to any records dependent on the value of the FOREIGN KEY . </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The CHECK constraint ensures that a value inserted into the specified column of the table is a valid value based on the CHECK expression. For example, the following shows a table with several column-level constraints: </p>
    </td>
  </tr>
  <tr><<td><span class="programlisting">
  <pre>CREATE TABLE people
    (people_id     CHAR(4)
        CONSTRAINT pk_dist_id PRIMARY KEY CLUSTERED
        CONSTRAINT ck_dist_id CHECK (dist_id LIKE '[A-Z][A-Z][A-Z][A-Z]'),
     people_name   VARCHAR(40) NULL,
     people_addr1  VARCHAR(40) NULL,
     people_addr2  VARCHAR(40) NULL,
     city          VARCHAR(20) NULL,
     state         CHAR(2)     NULL
        CONSTRAINT def_st DEFAULT ("CA")
        CONSTRAINT chk_st REFERENCES states(state_ID),
     zip           CHAR(5)     NULL
        CONSTRAINT ck_dist_zip
        CHECK(zip LIKE '[0-9][0-9][0-9][0-9][0-9]'),
     phone         CHAR(12)    NULL,
     sales_rep     empid       NOT NULL DEFAULT USER)
GO</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The CHECK constraint on the <span class="emphasis">people_id</span> ensures an all-alphabetic ID, while the one on <span class="emphasis">zip</span> ensures an all-numeric value. The <span class="emphasis">REFERENCES</span> constraint on <span class="emphasis">state</span> performs a look-up on the <span class="emphasis">states</span> table. The REFERENCES constraint is essentially the same as a CHECK constraint, except that it derives its list of acceptable values from the values stored in another column. This example illustrates how column-level constraints are named using the CONSTRAINT constraint_name. . . syntax. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Also new to SQL Server 2000 is the COLLATE column-level property. This feature allows programmers to change, on a column-by-column basis, the sort order and character set that is used by the column. Since this is an advanced technique, refer to the vendor documentation if the default sort order or character set of a given column needs to be changed. The CREATE FUNCTION topic shows an example of this syntax. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>SQL Server also allows the creation of tables with columns that contain a computed value. The column does not actually contain data. Instead, it is a virtual column containing an expression using other columns already in the table. For example, a computed column could have an expression, such as order_cost AS (price * qty) . Computed columns also can be a constant, function, variable, noncomputed column, or any of these combined with each other with operators. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Any of the column-level constraints shown earlier also may be declared at the table level. That is, PRIMARY KEY constraints, FOREIGN KEY constraints, CHECK constraints, and others may be declared after all the columns have been defined in the CREATE TABLE statement. This is very useful for constraints that cover more than one column. For example, when declaring a column-level UNIQUE constraint, it can be applied only to that column. However, declaring the constraint at the table level allows it to span several columns. Here is an example of both column-level and table-level constraints: </p>
    </td>
  </tr><tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
<td>
<span class="programlisting">
<pre>-- Creating a column-level constraint
CREATE TABLE favorite_books
    (isbn          CHAR(100)    PRIMARY KEY NONCLUSTERED,
     book_name     VARCHAR(40)  UNIQUE,
     category      VARCHAR(40)  NULL,
     subcategory   VARCHAR(40)  NULL,
     pub_date      DATETIME     NOT NULL,
     purchase_date DATETIME     NOT NULL)
GO

-- Creating a table-level constraint
CREATE TABLE favorite_books
    (isbn          CHAR(100)    NOT NULL,
     book_name     VARCHAR(40)  NOT NULL,
     category      VARCHAR(40)  NULL,
     subcategory   VARCHAR(40)  NULL,
     pub_date      DATETIME     NOT NULL,
     purchase_date DATETIME     NOT NULL,
        CONSTRAINT pk_book_id   PRIMARY KEY NONCLUSTERED (isbn)
           WITH FILLFACTOR=70,
        CONSTRAINT unq_book     UNIQUE CLUSTERED (book_name,pub_date))
GO</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>These two commands provide nearly the same results, except that the table-level UNIQUE constraint has two columns, whereas only one column is included in the column-level UNIQUE constraint. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Finally, Microsoft SQL Server has two separate clauses controlling how the table (or primary key or unique indexes) are to be physically placed: [ON {filegroup | DEFAULT} ] and [TEXTIMAGE_ON {filegroup | DEFAULT}] . The ON filegroup clause stores the table or index within the named file group, as long as it exists within the database. If ON DEFAULT is specified or the ON clause is not used at all, the table or index is stored in the default filegroup for the database. The TEXTIMAGE clause works in very much the same way, except that it controls the placement of <span class="emphasis">text</span> , <span class="emphasis">ntext</span> , and <span class="emphasis">image</span> columns. These columns are normally stored in the default filegroup with all other tables and database objects. </p>
    </td>
  </tr>

<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">MySQL Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>CREATE [TEMPORARY] TABLE [IF NOT EXISTS] table_name
<emphasis role="bold">(</emphasis>column_name datatype [NULL | NOT NULL] [DEFAULT default_value]
   [AUTO_INCREMENT]
   [PRIMARY KEY] [reference_definition] |
   [CHECK (expression) |
   [INDEX [index_name] index_col_name1[(length)],...n)] |
   [UNIQUE [INDEX] [index_name] (index_col_name1,...n)] |
   [CONSTRAINT symbol] FOREIGN KEY index_name (index_col_name1,...n)
      [REFERENCES table_name [(index_col_name,...)]
      [MATCH FULL | MATCH PARTIAL]
      [ON DELETE {RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT}]
      [ON UPDATE {RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT}])
{[TYPE = {ISAM | MYISAM | HEAP} |
   AUTO_INCREMENT = int |
   AVG_ROW_LENGTH = int |
   CHECKSUM = {0 | 1} |
   COMMENT = "string" |
   DELAY_KEY_WRITE = {0 | 1} |
   MAX_ROWS = int |
   MIN_ROWS = int |
   PACK_KEYS = {0 | 1} |
   PASSWORD = "string" |
   ROW_FORMAT= { default | dynamic | static | compressed }] }
[[IGNORE | REPLACE] SELECT_statement]</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>MySQL allows a great many options when creating a table. The TEMPORARY option creates a table that persists for the duration of the connection under which it was created. Once that connection closes, the temporary table is automatically deleted. The IF NOT EXISTS option prevents an error if the table already exists. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>When a table is created in MySQL, three operating-system files are typically created: a table definition file with the extension .frm , a datafile with the extension .myd , and an index file with the extension .myi . </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The AUTO_INCREMENT clause sets up an integer column so that it automatically increases its value by 1 (starting with a value of 1). MySQL only allows one AUTO_INCREMENT column per table. When the max value is deleted, the value is reused. When all records are deleted, the values start over. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>A PRIMARY KEY column or columns may be defined, as long as they also are defined as NOT NULL . When an INDEX characteristic is assigned to a column, a name for the index also can be included. (A MySQL synonym for INDEX is KEY. ) If a name is not assigned, MySQL assigns a name of index_column_name plus a numeric suffix ( _2, _3,. . . ) to make it unique. Only the MyISAM table type supports indexes on NULL columns or on BLOB or TEXT datatype columns. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The FOREIGN KEY , CHECK , and REFERENCES clauses do nothing. They add no functionality to the table and are supported only to improve compatibility with other SQL databases. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The table TYPE options describe how the data should be physically stored. ISAM is the original table definition. MyISAM is a newer, binary, more portable storage structure. HEAP stores the table in memory. Other options exist to optimize performance for the table: </p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>AUTO_INCREMENT:<br>
Sets the <span class="emphasis">auto_increment</span>
value for the table (MyISAM only). </p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p> AVG_ROW_LENGTH:<br>
 Sets an approximate average row length for tables with variable-size records.
  MySQL uses avg_row_length *  max_rows
to decide how big a table may be. </p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>CHECKSUM:<br>
When set to 1, maintains a checksum for all rows in the table (MyISAM
only). Makes processing slower, but less prone to corruption.</p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p> COMMENT:<br>
Allows a comment of up to 60 characters.</p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p> DELAY_KEY_WRITE:<br>
When set to 1, delays key table updates until the table is closed
(MyISAM only).</p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>MAX_ROWS:<br>
Sets a maximum number of rows to store in the table. The default
max is 4 GB of space.
</p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>MIN_ROWS:<br>
Sets a minimum number of rows to store in the table.
</p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>PACK_KEYS:<br>
When set to 1, compacts the indexes of the table, making reads faster
but updates slower (MyISAM and ISAM only). By default, only strings are packed.
When set to 1, both strings and numeric values are packed.
</p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>PASSWORD:<br>
Encrypts the .frm
file with a password, but not the table.
</p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>ROW_FORMAT:<br>
Determines how future rows should be stored in the table.
</p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The SELECT _ statement clause creates a table whose fields are based upon
    the elements in the SELECT statement. If it does not, as some implementations
    do, then the table can be populated with the results of the SELECT statement.
    For example: </p>
    </td>
  </tr>CREATE TABLE test_example (column_a INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(column_a), INDEX(column_b)) TYPE=HEAP SELECT column_b,column_c FROM samples;
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>This creates a heap table with three columns: column_a , column_b , and column_c . </p>
    </td>
  </tr>

<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">Oracle Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>CREATE TABLE test_example
  (column_a INT NOT NULL AUTO_INCREMENT,
  PRIMARY KEY(column_a),
  INDEX(column_b))
TYPE=HEAP
SELECT column_b,column_c FROM samples;</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>This simple and small block of code is deceptive! Oracle's extremely sophisticated implementation of the CREATE TABLE statement has the potential to become one of the most complex single commands in just about any programming language under the sun. </p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p><span class="emphasis">Tip:</span>
  The code for Oracle's CREATE TABLE
  clause contains many subclauses. Rather than show them all in one command, the command is broken out into subclauses that in turn contain other subclauses. The average SQL programmer might never use some of these subclauses.
</p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>To explain the most immediate differences between the SQL99 version of CREATE TABLE and Oracle's version, note that tables created as GLOBAL TEMPORARY must be basic tables. Global temporary tables cannot possess most of the special features that Oracle allows for regular tables, such as partitioning, index organizing, or clustering tables. A global temporary table is available to all sessions, but the data stored within a global temporary table is visible only to the session that inserted it. The ON COMMIT clause, which is allowed only when creating temporary tables, tells Oracle either to truncate the table after each commit against the table ( DELETE ROWS ) or to truncate the table when the session terminates ( PRESERVE ROWS ). For example: </p>
    </td>
  </tr><tr>
<td>
<span class="programlisting">
<pre>CREATE [GLOBAL TEMPORARY] TABLE [schema.]table_name
( column_name datatype [DEFAULT] {column_constraint [...]} [,...n]
| table_constraint [,...n] } )
[ON COMMIT {DELETE | PRESERVE} ROWS]
( physical_characteristics )
( table_characteristics )</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The CREATE TABLE statement shown earlier creates a global temporary table, <span class="emphasis">shipping_schedule</span> , that retains inserted rows across multiple sessions. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The physical characteristics of an Oracle table are defined using the next several blocks of code and their subblocks of code: </p>
    </td>
  </tr><tr>
<td>
<span class="programlisting">
<pre>CREATE GLOBAL TEMPORARY TABLE shipping_schedule
  (ship_date DATE,
   receipt_date DATE,
   received_by VARCHAR2(30),
   amt NUMBER)
ON COMMIT PRESERVE ROWS;</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The <span class="emphasis">physical_characteristics</span> clause controls how data is stored physically on the disk subsystem. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The TABLESPACE clause assigns the table to a specific, preexisting tablespace. The TABLESPACE clause can be left out, which places the index on the default tablespace, or DEFAULT keyword can be used to achieve the same results. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The LOGGING and NOLOGGING clauses define whether the table, large object (LOB), or partition is logged in the redo log. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The <span class="emphasis">ORGANIZATION HEAP</span> clause tells Oracle to physically place the rows of the table in any order. It may optionally be associated with a <span class="emphasis">segment_characteristic</span> clause. Alternately, the rows of the table may be physically ordered according to a named index using <span class="emphasis">ORGANIZATION INDEX index_name</span> . </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The physical_attributes clause (as shown in the following code block) defines storage characteristics for the entire table, or if the table is partitioned, for a specific partition (discussed later): </p>
    </td>
  </tr><tr>
<td>
<span class="programlisting">
<pre>-- physical_characteristics
{[{[physical_attributes]
| TABLESPACE tablespace_name
| {LOGGING | NOLOGGING} }]
| {ORGANIZATION {HEAP [{[physical_attributes]
   | TABLESPACE tablespace_name
   | {LOGGING | NOLOGGING} }]
| INDEX indexed_table_clause)}
| CLUSTER cluster_name (column [,...n]) }
[special_storage_clause]</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>PCTFREE defines the percentage of free space reserved for each data block in the table. For example, a value of 10 reserves 10% of the data space for new rows to be inserted. PCTUSED defines the minimum percentage of space allowed in a block before it can receive new rows. For example, a value of 90 means new rows are inserted in the data block when the space used falls below 90%. The sum of PCTFREE and PCTUSED cannot exceed 100. INITRANS is rarely tinkered with; it defines the allocation of from 1 to 255 initial transactions to a data block. MAXTRANS defines the maximum number of concurrent transactions on a data block. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The storage_clause controls a number of attributes governing the physical storage of data: </p>
    </td>
  </tr><tr>
<td>
<span class="programlisting">
<pre>-- physical_attributes
[{PCTFREE int | PCTUSED int | INITRANS int | MAXTRANS int | storage_
    clause}]</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>When delineating the storage clause attributes, enclose them in parentheses and separate them with spaces  for example, (INITIAL 32M NEXT8M) . INITIAL int [K | M] sets the initial extent size of the table in bytes, kilobytes (K), or megabytes (M). NEXT int [K | M] tells how much additional space to allocate after INITIAL is filled. PCTINCREASE int controls the growth rate of the object after the first growth. The initial extent gets allocated as specified. The second extent is the size specified by NEXT . The third extent is NEXT + (NEXT * PCTINCREASE). When PCTINCREASE is set to 0, NEXT is always used. Otherwise, each added extent of storage space is PCTINCREASE larger than the previous extent. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>MINEXTENTS int tells Oracle to create a minimum number of extents. By default, only 1 is created, but more can be created when the object is initialized. MAXEXTENTS int tells Oracle the maximum extents allowed. It may be set to UNLIMITED . (Note that UNLIMITED should be used with caution. There are situations in which it can cause database damage.) FREELISTS int establishes the number of freelists for each group, defaulting to 1. FREELIST GROUPS int sets the number of groups of freelists, defaulting to 1. For example: </p>
    </td>
  </tr><tr>
<td>
<span class="programlisting">
<pre>-- storage_clause
STORAGE ( [ {INITIAL int [K | M]
            | NEXT int [K | M]
            | MINEXTENTS int
            | MAXEXTENTS {int | UNLIMITED}
            | PCTINCREASE int
            | FREELISTS int
            | FREELIST GROUPS int
            | OPTIMAL [{int [K | M] | NULL}]
            | BUFFER_POOL {KEEP | RECYCLE | DEFAULT} ] [...] )</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The table <span class="emphasis">books_sales</span> is defined on the <span class="emphasis">sales </span>tablespace as consuming an initial 8 MB of space, to grow by no less than 8 MB when the first extent is full. The table has no less than 1 and no more than 8 extents, limiting its maximum size to 64 MB. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The <span class="emphasis">ORGANIZATION HEAP</span> clause tells Oracle to physically place the rows of the table in any order. It may be optionally associated with a <span class="emphasis">segment_characteristic_clause</span> . Alternately, the rows of the table may be physically ordered according to a named INDEX . </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The CLUSTER clause includes the table in an existing cluster based upon a clustered key. (Refer to Oracle's CREATE CLUSTER command.) All tables in the cluster must possess columns that correspond to the columns of the clustered key. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The special_storage_clause details three special types of data storage possible within an Oracle table: LOB (large object, such as image files), varrays, and nested tables: </p>
    </td>
  </tr><tr>
<td>
<span class="programlisting">
<pre>CREATE TABLE book_sales
  (qty NUMBER,
   period_end_date DATE,
   period_nbr NUMBER)
TABLESPACE sales
STORAGE (INITIAL 8M NEXT 8M MINEXTENTS 1 MAXEXTENTS 8);</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The LOB clause defines the storage attributes of LOB data segment. The LOB item is the name of the LOB column or columns declared in the table. The LOB objects may be stored within the row if they are less than 4000 bytes in length, using the ENABLE STORAGE IN ROW clause, or they may be stored outside the row regardless of size, using the DISABLE STORAGE IN ROW clause. Refer to the Oracle documentation for more information about the LOB storage using the <span class="emphasis">LOB_storage_clause</span> . For example: </p>
    </td>
  </tr><tr>
<td>
<span class="programlisting">
<pre>{LOB { (LOB_item [,n]) STORE AS {ENABLE | DISABLE} STORAGE IN ROW
      | (LOB_item) STORE AS
           {LOB_segment_name ({ENABLE | DISABLE} STORAGE IN ROW)
           | LOB_segment_name
           | ({ENABLE | DISABLE} STORAGE IN ROW)}
  | VARRAY varray_item STORE AS
  | NESTED TABLE nested_item STORE AS storage_table
      [(physical_characteristics)]
      [RETURN AS {LOCATOR | VALUE}] }</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The <span class="emphasis">large_objects</span> table is used to store pictures and text. The storage characteristics, as well as logging and caching characteristics, are also detailed. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>A varray is a special Oracle object. Oracle allows distinct storage parameters for LOBs stored in a varray, using essentially the same syntax as the LOB clause. Refer to the vendor documentation for more information for varrays. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Oracle allows declaration of a NESTED TABLE clause in which a table is virtually stored within a column of another table. The STORE AS clause enables a proxy name for the table within a table, but the nested table must be created initially as a user-defined datatype. This capability is valuable for sparse arrays of values, but it is not a generally recommended approach for day-to-day tasks. For example: </p>
    </td>
  </tr><tr>
<td>
<pre>CREATE TYPE prop_nested_tbl AS TABLE OF props_nt;

CREATE TABLE proposal_types
   (proposal_category VARCHAR2(50),
   proposals          PROPS_NT)
NESTED TABLE props_nt STORE AS props_nt_table;</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Oracle allows a wide variety of table characteristics to be defined for a given table. Some of those characteristics are shown in the following list: </p>
    </td>
  </tr><tr>
<td>
<span class="programlisting">
<pre>-- table_characteristics
{ PARTITION characteristics }
[CACHE | NOCACHE] [MONITORING | NOMONITORING]
[{NOPARALLEL | PARALLEL [int] }]
[{ENABLE | DISABLE} [VALIDATE | NOVALIDATE]
  {UNIQUE (column [,...n] )
  | PRIMARY KEY
  | CONSTRAINT constraint_name}
[index_clause]
[EXCEPTION INTO [schema.]table_name]
[CASCADE] ]
[AS select_statement]</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Oracle uses the PARTITION clause as a performance enhancement by spreading the table across multiple partitions. However, the full syntax describing all permutations of a table partition would be prohibitively long. Furthermore, it is not used by most beginning SQL programmers. Refer to the Oracle vendor documentation for more information on table partitioning. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>CACHE buffers a table for rapid reads, while NOCACHE turns off this behavior. Index-organized tables offer CACHE behavior. MONITORING collects statistics on a table for added performance, while NOMONITORING turns this function off. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>For the CREATE TABLE statement, the INDEX clause is just for primary key and unique indexes that are created along with the table. Refer to the Oracle documentation for a full discussion on the available means of manipulating an index using the CREATE TABLE command. For most purposes, the CREATE INDEX command is the recommended approach. (Note that Oracle automatically creates an index when creating a table with a primary key constraint. There is no need for the user to create an index in that situation.) </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The PARALLEL clause allows for the parallel creation of the table by distinct CPUs to speed the operation. It also enables parallelism for queries and other data-manipulation operations against the table after its creation. An optional integer value may be supplied to define the exact number of parallel threads used in the operation, as well as the parallel threads allowed to service the table in the future. (Oracle calculates the best number of threads to use in a given parallel operation, so this is an optional feature.) NOPARALLEL , the default, creates the table serially and disallows future parallel queries and data-manipulation operations. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The DISABLE and ENABLE clauses deactivate or activate constraints on a table, respectively. Basically, the DISABLE clause can deactivate any active integrity constraint or trigger. Conversely, ENABLE can activate any disabled integrity constraint or trigger. The syntax for this clause is: </p>
    </td>
  </tr><tr>
<td>
<span class="programlisting">
<pre>DISABLE | ENABLE {{UNIQUE(column[,...n] |
   PRIMARY KEY |
   CONSTRAINT constraint_name}
      [CASCADE]}
      [EXCEPTIONS INTO [owner.]table_name]
      [USING INDEX [INITRANS int][MAXTRANS int]
         [TABLESPACE tablespace_name][storage_characteristics]
         [PCTFREE int] |</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The CASCADE keyword, usable only with DISABLE , does not disable a cascading constraint or trigger. Instead, it cascades the disablement/enablement to any integrity constraints that depend on the constraint named in the clause. The EXCEPTIONS INTO clause, usable only with ENABLE , tells Oracle to store the information of any integrity-constraint violation in an existing exceptions table. The USING INDEX clause, also usable only with ENABLE , provides a mechanism to specify different storage characteristics for the named index, particularly primary and unique keys. The default is for all constraints to be enabled. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The AS SELECT_statement clause populates the new table with records from a valid SELECT statement. Unlike PostgreSQL's implementation of CREATE . . . AS SELECT , the columns of the CREATE TABLE statement must match those in the SELECT statement. Logging of CREATE . . . AS SELECT may be turned off by using the NOLOGGING keyword. Logging to the redo log is the default behavior. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Oracle supports a number of object-oriented features that are beyond the scope of this book. </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">PostgreSQL Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>CREATE [TEMPORARY | TEMP] TABLE table <span class="emphasis">(</span>
column_name datatype [NULL | NOT NULL] [DEFAULT value] <
<span class="emphasis">|</span>[UNIQUE] <span class="emphasis">|</span> [PRIMARY KEY (column[,...n])]
| [CHECK (expression) ]
| REFERENCES reference_table (reference_column)
   [MATCH {FULL | PARTIAL |    default}]
   [ON DELETE {CASCADE | NO   ACTION | RESTRICT | SET NULL | SET
      DEFAULT}]
   [ON UPDATE {CASCADE | NO ACTION | RESTRICT | SET NULL | SET
   DEFAULT}]
   [[NOT] DEFERRABLE] [INITIALLY {DEFERRED| IMMEDIATE}] }    [,...n]
|[table_constraint][,...n]
[INHERITS (inherited_table [,...n])]
| [ON COMMIT {DELETE | PRESERVE} ROWS] |
AS SELECT _statement</pre></span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Using a syntax similar to MySQL, PostgreSQL allows the creation of a TEMPORARY table. Temporary tables exist only for the session in which they were created and automatically drop themselves when the session ends. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Constraints such as UNIQUE , PRIMARY KEY , and CHECK are essentially the same as in Microsoft SQL Server. However, unique to PostgreSQL is the ability to create column-level constraints with multiple columns. Since PostgreSQL also supports standard table-level constraints, the ANSI-standard approach is still the recommended approach. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The REFERENCES constraint is similar to a CHECK constraint, except that it checks a value against the values of another column in another table. It also can be used as part of a FOREIGN KEY declaration. The MATCH options are FULL , PARTIAL, and default (where MATCH has no other keyword). Full match forces all columns of a multicolumn foreign key either to be null or to contain a valid value. The default allows mixed nulls and values. Partial matching is a valid syntax, but is not supported. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The REFERENCES clause also allows several different behaviors to be declared for ON DELETE and/or ON UPDATE referential integrity: </p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>NO ACTION
 <br> Produces an error when the foreign key is violated (the default)</p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>RESTRICT<br>
 A synonym for NO ACTION</p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>CASCADE<br>
 Sets the value of the referencing column to the value of the
   referenced column
 </p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>SET NULL<br>
Sets the referencing column value to NULL
 </p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>SET DEFAULT <br>
 Sets the referencing column to its declared default value or
   null, if no default value exists</p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The DEFERRABLE option of the REFERENCES clause tells PostgreSQL to defer all constraints to the end of a transaction. NOT DEFERRABLE is the default behavior for the REFERENCES clause. Similar to the DEFERRABLE clause is the INITIALLY clause. Specifying INITIALLY DEFERRED checks constraints at the end of a transaction; INITIALLY IMMEDIATE checks constraints after each statement (the default). </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Note that, like Microsoft SQL Server, all column-level constraints may be declared as table-level constraints. Importantly, the FOREIGN KEY constraint can be declared only as a table-level constraint and not as a column-level constraint. All options for the REFERENCES clause are supported as part of the FOREIGN KEYS clause. The syntax follows: </p>
    </td>
  </tr><tr>
<td>
<span class="programlisting">
<pre>[FOREIGN KEY (column[,...n]) REFERENCES...]</pre></span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The INHERITS inherited_table clause specifies a table or tables from which this table inherits all columns. The newly created table also inherits functions attached to tables higher in the hierarchy. If any inherited column appears more than once, the statement fails. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>If a temporary or global temporary table is created in PostgreSQL, the ON COMMIT clause also may be appended to the command. This clause controls the behavior of the temporary table after records are committed to the table. ON COMMIT DELETE ROWS clears the temporary table of all rows after each commit. This is the default. ON COMMIT PRESERVE ROWS saves the rows in the temporary table after the transaction has committed. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The AS SELECT_statement clause enables a programmer to create and populate a table with data from a valid SELECT statement. The columns, datatypes, or constraints do not need to be defined, since they are inherited from the query. It is similar in functionality to SELECT . . . INTO , but its syntax seems more readable. </p>
    </td>
  </tr>

<tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="example"><span class="title">
  Example</span>
</td>
</tr>

 <tr>
    <td><p>This example adds a foreign key to the example table: </p>
    </td>
  </tr>
  <tr>
            <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
      </tr>
  <tr>
<td>
<span class="programlisting">
<pre>-- Creating a column-level constraint
CREATE TABLE favorite_books
   (isbn         CHAR(100)    PRIMARY KEY NONCLUSTERED,
   book_name     VARCHAR(40)  UNIQUE,
   category      VARCHAR(40)  NULL,
   subcategory   VARCHAR(40)  NULL,
   pub_date      DATETIME     NOT NULL,
   purchase_date DATETIME     NOT NULL,
      CONSTRAINT fk_categories FOREIGN KEY (category)
         REFERENCES category(cat_name));</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The foreign key on the <span class="emphasis">categories</span> column relates it to the <span class="emphasis">cat_name</span> table in the <span class="emphasis">category</span> table. This syntax is supported by all the vendors mentioned in this book. Similarly, the foreign key could have been declared as a multicolumn key including both the <span class="emphasis">category</span> and <span class="emphasis">subcategory</span> columns: </p>
    </td>
  </tr>
  <tr>
            <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
      </tr>
  <tr>
<td>
<span class="programlisting">
<pre>...
CONSTRAINT fk_categories FOREIGN KEY (category, subcategory)
         REFERENCES category(cat_name, subcat_name));</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Listed here are two more full examples from the <span class="emphasis">pubs </span>database ( <span class="emphasis">jobs</span> and <span class="emphasis">employee</span> ): </p>
    </td>
  </tr>
  <tr>
         <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
<td>
<span class="programlisting">
<pre>-- For a Microsoft SQL Server database
CREATE TABLE jobs
   (job_id  SMALLINT IDENTITY(1,1) PRIMARY KEY CLUSTERED,
   job_desc VARCHAR(50) NOT NULL DEFAULT 'New Position',
   min_lvl  TINYINT NOT NULL CHECK (min_lvl &gt;= 10),
   max_lvl  TINYINT NOT NULL CHECK (max_lvl &lt;= 250))

-- For a MySQL  database
CREATE TABLE employee
   (emp_id INT AUTO_INCREMENT CONSTRAINT PK_emp_id PRIMARY KEY,
   fname VARCHAR(20) NOT NULL,
   minit CHAR(1) NULL,
   lname VARCHAR(30) NOT NULL,
   job_id SMALLINT NOT NULL DEFAULT 1
      REFERENCES jobs(job_id),
   job_lvl TINYINT DEFAULT 10,
   pub_id CHAR(4) NOT NULL DEFAULT ('9952')
      REFERENCES publishers(pub_id),
   hire_date DATETIME NOT NULL DEFAULT (CURRENT_DATE(  ));

CREATE TABLE publishers
   (pub_id char(4) NOT NULL
      CONSTRAINT UPKCL_pubind PRIMARY KEY CLUSTERED
      CHECK (pub_id IN ('1389', '0736', '0877', '1622', '1756')
      OR pub_id LIKE '99[0-9][0-9]'),
   pub_name varchar(40) NULL,
   city varchar(20) NULL,
   state char(2) NULL,
   country varchar(30) NULL DEFAULT('USA'))</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The following is an example of an Oracle CREATE TABLE statement with many storage properties: </p>
    </td>
  </tr>
  <tr>
    <td>
    <tr>
	      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
    </tr>
    <tr>
<td>
<span class="programlisting">
<pre>CREATE TABLE classical_music_cds
   (music_id        INT,
   composition      VARCHAR2(50),
   composer         VARCHAR2(50),
   performer        VARCHAR2(50),
   performance_date DATE DEFAULT SYSDATE,
   duration         INT,
   cd_name          VARCHAR2(100),
CONSTRAINT pk_class_cds PRIMARY KEY (music_id)
   USING INDEX TABLESPACE index_ts
   STORAGE (INITIAL 100K NEXT 20K),
CONSTRAINT uq_class_cds UNIQUE (composition, performer, performance_date)
   USING INDEX TABLESPACE index_ts
   STORAGE (INITIAL 100K NEXT 20K))
TABLESPACE tabledata_ts;</pre>
</span>
</td>
</tr>
</table>
</div>

<div id="CREATE TRIGGER"><table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td Width="50%" align="left" class="name" valign="top">CREATE TRIGGER<td Width="50%" align="right"class="name" valign="top">SQL-schema&nbsp;&nbsp;</td></tr></table>
<table width="100%" cellspacing="0" cellpadding="0" border="0">
   <tr>
    <td><p>A trigger is a special kind of stored procedure that fires automatically (hence, the term trigger) when a data-modification statement is executed. Triggers are associated with a specific data-modification statement ( INSERT , UPDATE , or DELETE ) on a specific table. </p>
    </td>
  </tr><tr>
          <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
      </tr>
    <tr>
    <td>
      <table border="1" >
    <tr><th>Vendor</th>
<th>Command</th></tr>
<tr><td>SQL Server</td><td>Supported, with variations</td></tr><tr><td>MySQL</td><td>Not supported</td></tr><tr><td>Oracle</td><td>Supported, with variations</td></tr><tr><td>PostgreSQL</td><td>Supported, with variations</td></tr></table>
</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">SQL99 Syntax and Description</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>CREATE TRIGGER trigger_name
{BEFORE | AFTER} {[DELETE] | [INSERT] | [UPDATE] [OF column [,...n]}
ON table_name
[REFERENCING {OLD [ROW] [AS] old_name | NEW [ROW] [AS] new_name
  OLD TABLE [AS] old_name | NEW TABLE [AS] new_name}]
[FOR EACH { ROW | STATEMENT }]
[WHEN (conditions)]
code block</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Triggers, by default, fire once at the <span class="emphasis">statement level</span> . That is, a single INSERT statement might insert 500 rows into a table, but an insert trigger on that table fires only one time. Some vendors allow a trigger to fire for each row of the data-modification operation. So, a statement that inserts 500 rows into a table that has a row-level insert trigger fires 500 times, once for each inserted row. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>In addition to being associated with a specific data-modification statement ( INSERT , UPDATE , or DELETE ) on a given table, triggers are associated with a specific time of firing. In general, triggers can fire BEFORE the data-modification statement is processed, AFTER it is processed, or (when supported by the vendor) INSTEAD OF processing the statement. Triggers that fire before or instead of the data-modification statement do not see the changes that the statement renders, while those that fire afterwards can see and act upon the changes that the data-modification statement renders. </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">
Microsoft SQL Server Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>CREATE TRIGGER trigger_name
ON {table_name | view_name}
[WITH ENCRYPTION]
{FOR | AFTER | INSTEAD OF} {[DELETE] [,] [INSERT] [,] [UPDATE]}
[WITH APPEND]
[NOT FOR REPLICATION]
AS
  {
  T-SQL_block
  |
  { IF UPDATE(column) [{AND | OR} UPDATE(column)] [...n]
    |
    IF (COLUMNS_UPDATED(  ) {bitwise_operator} updated_bitmask)
    { comparison_operator} column_bitmask [...n] }
    T-SQL_block [...n]
   }</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Microsoft SQL Server supports a number of interesting features in its CREATE TRIGGER statement. First, SQL Server allows multiple triggers for a given data-manipulation operation on a table or <span class="emphasis">view</span> . Thus, three UPDATE triggers are possible on a single table. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The WITH ENCRYPTION clause encrypts the text of the trigger where it is stored in the <span class="emphasis">syscomments</span> system table. The WITH APPEND clause adds an additional trigger of an existing type to a table or view. This clause is added for backward compatibility with earlier versions of the product and can be used only with FOR triggers. The NOT FOR REPLICATION clause disables the trigger on data-manipulation operations invoked through SQL Server's built-in replication capabilities. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The
  FOR , AFTER , and INSTEAD OF clauses tell SQL Server when the trigger should
  fire. The FOR and AFTER keywords are synonymous and serve the same function.
  In effect, they specify that the trigger fire only after the triggering data-modification
  statement (and any cascading actions and constraint checks) have completed
  successfully. Many AFTER triggers are possible on a given table. Their order
  is undefined, though the first and last triggers can be specified using the
  sp_settriggerorder system stored procedure. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p> </p>
    </td>
  </tr><span class="emphasis">Warning: </span>AFTER
triggers cannot be defined on views. <br>
</p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The INSTEAD OF clause is functionally equivalent to Oracle's BEFORE trigger. It specifies that the trigger fire before (and thus, instead of ) the triggering data-modification statement, but only one INSTEAD OF trigger is possible per INSERT , UPDATE , or DELETE statement on a given table (though multiple AFTER triggers are possible). This kind of trigger is usable on views, but only if they do not use the WITH CHECK OPTION clause. INSTEAD OF DELETE triggers cannot be used when there is a cascading action on the delete. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The DELETE , INSERT , and UPDATE specifications identify the data-modification statement that fires the trigger. In SQL Server, any combination of these are made possible in a trigger definition by separating each option with a comma. (When doing so, the same code fires for each statement in the combination definition.) </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The AS T-SQL_block clause contains the procedural code that the trigger fires whenever the data-manipulation operation is performed. This section should be enclosed within the Transact-SQL BEGIN and END clauses. Traditionally, this section contains control-of-flow commands and checks against the type and amount of data changed. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>SQL Server instantiates two important pseudo-tables when a trigger is fired: <span class="emphasis">deleted</span> and <span class="emphasis">inserted</span> . These tables are identical in structure to the table on which the triggers are defined, except that they contain the old data before the data-modification statement fired ( <span class="emphasis">deleted </span>) and the new values of the table after the data-modification statement fired ( <span class="emphasis">inserted </span>). </p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p><span class="emphasis">Warning</span>: Only INSTEAD OF triggers can access <span class="emphasis">text </span>, <span class="emphasis">ntext </span>, or <span class="emphasis">image </span>columns. <br>
</p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The AS IF UPDATE(column) clause tests specifically for INSERT or UPDATE actions on a given column or columns. Multiple columns may be specified by adding separate UPDATE(column) clauses after the first; follow the clause with a Transact-SQL BEGIN . . . END block to allow multiple Transact-SQL operations to fire when the condition is met. This clause is functionally equivalent to the IF . . . THEN . . . ELSE operation. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The AS IF (COLUMNS_UPDATE( )) clause is similar to the AS IF UPDATE( ) clause in that it fires only on an INSERT or UPDATE operation against the column specified. It returns a <span class="emphasis">varbinary</span> bit pattern that tells which columns were inserted or updated and allows bitwise operations that compare the column values in various ways. The comparison operators are the equal sign (=), used to check if all columns specified in the updated bitmask were changed, and the greater-than sign (>), used to check whether one or some of the columns were changed. </p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p><span class="emphasis">Tip</span>: Triggers are used often to control declarative referential integrity.
  However, primary and foreign key declarations via a CREATE TABLE or ALTER TABLE statement are preferable. <br>
</p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>SQL Server <span class="emphasis">does not</span> allow the following statements within the Transact-SQL block of a trigger: ALTER , CREATE , DROP , DENY , GRANT , REVOKE , LOAD , RESTORE , RECONFIGURE , or TRUNCATE . In addition, it does not allow any DISK statements or the UPDATE STATISTICS command. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>SQL Server also allows triggers to fire recursively using the recursive triggers setting of the sp_dboption system stored procedure. Recursive triggers, by their own action, cause themselves to fire again. For example, if an INSERT trigger on table <span class="emphasis">T1</span> performs an INSERT operation on table <span class="emphasis">T1</span> , it might perform a recursive operation. Since recursive triggers can be dangerous, this functionality is disabled by default. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Similarly, SQL Server allows nested triggers up to 32 levels deep. If any one of the nested triggers performs a ROLLBACK operation, no further triggers execute. An example of nested triggers is a trigger on table <span class="emphasis">T1</span> firing an operation against table <span class="emphasis">T2 </span>, which also has a trigger that fires an operation against table <span class="emphasis">T3</span>. The triggers cancel if an infinite loop is encountered. Nested triggers are enabled with the nested triggers setting of the system stored procedure sp_configure . If nested triggers are disabled, recursive triggers are disabled as well, despite the recursive triggers' setting of sp_dboption . </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>SQL Server CREATE statements allow <span class="emphasis">deferred name resolution </span>, meaning that the command is processed even if it refers to a database object that does not yet exist in the database. </p>
    </td>
  </tr>

<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">Oracle Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>CREATE [OR REPLACE] TRIGGER [owner.]trigger_name
{BEFORE | AFTER | INSTEAD OF}
{[DELETE] [OR] [INSERT] [OR] [UPDATE [OF column [,...n] ]] [...n]}
ON {table_name | view_name}
[REFERENCING {OLD [AS] old_name | NEW [AS] new_name}]
[FOR EACH { ROW | STATEMENT }]
[WHEN (conditions)]
PL/SQL block</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>As is typical of the CREATE TRIGGER statement, the command specifies the data-modification operation ( INSERT , UPDATE , or DELETE ) that fires the PL/SQL block of code and when it is fired ( BEFORE , AFTER , or INSTEAD OF the data-modification operation). On UPDATE operations, an UPDATE OF a column or columns may be specified to indicate that the update trigger should fire only when those specific column(s) are changed. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Oracle allows INSTEAD OF triggers to process only against views, not tables. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Oracle also allows triggers to fire on certain database events, such as DROP TABLE or SHUTDOWN . </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The REFERENCING clause specifies a name for the pseudo-tables that hold the OLD and NEW versions of the table. (SQL Server automatically names these pseudo-tables <span class="emphasis">inserted</span> and <span class="emphasis">deleted</span>. ) In Oracle, the default name for these pseudo-tables is <span class="emphasis">OLD </span>and <span class="emphasis">NEW</span>, respectively. These pseudo-tables compare record values before they are altered by the data-manipulation operation (via the <span class="emphasis">OLD </span>pseudo-table) and compared to the values after the data-manipulation operation (via the <span class="emphasis">NEW </span>pseudo-table). Pseudo-tables also perform conditional operations on the PL/SQL_block . </p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p><span class="emphasis">Tip:</span> When
  referencing values in the <span class="emphasis">OLD</span>
and <span class="emphasis">NEW</span>
pseudo-tables, the value must be prefaced with a colon (:), except in the trigger's
WHEN clause, where no colons are used. <br>
</p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The FOR EACH ROW clause tells the trigger to operate on each individual row (firing
  once for each row affected by the operation), rather than operate as an implicit
  statement trigger (firing once for the entire transaction). The WHEN clause specifies
  a SQL condition that restricts the execution of the trigger to happen only when
  the condition is met. The WHEN clause also allows comparisons of the OLD and
  NEW tables without having to build a PL/SQL block to compare them. </p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Multiple trigger types may be combined into a single trigger command if they are of the same level (row or statement) and they are on the same table. When triggers are combined in a single statement, the clauses IF INSERTING THEN , IF UPDATING THEN , and IF DELETING THEN may be used in the PL/SQL block to break the code logic into distinct segments. An ELSE clause also can be used in this structure. </p>
    </td>
  </tr>

<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">PostgreSQL Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>CREATE TRIGGER trigger_name
{ BEFORE | AFTER }
{ {[DELETE] [OR | ,] [INSERT] [OR | ,] [UPDATE]} [OR ...] }
ON table_name
FOR EACH { ROW | STATEMENT }
EXECUTE PROCEDURE function_name (parameters)</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The PostgreSQL implementation of CREATE TRIGGER functions in a similar manner to that of the other vendors. It may fire BEFORE the data-modification operation is attempted on the record and before any constraints are fired. Or it may fire AFTER the data-manipulation operation has processed (and after constraints have been checked), making all operations involved in the transaction visible to the trigger. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Rather than process a block of procedural code (as Oracle and SQL Server do), PostgreSQL executes a function via the EXECUTE PROCEDURE clause created using the CREATE FUNCTION . Also, other vendors implicitly process upon all rows in the transaction. PostgreSQL executes the trigger on each row or once for the entire transaction, using the FOR EACH ROW and FOR EACH STATEMENT clauses, respectively. </p>
    </td>
  </tr>

<tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="example"><span class="title">
  Example</span>
</td>
</tr>
  <tr>
    <td><p>Following is an example of a PostgreSQL BEFORE trigger that checks at a row level to ensure that the specified distributor code exists in the distributors table before inserting or updating a row in the sales table: </p>
    </td>
  </tr>
  <tr>
  	      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
    </tr>
  <tr>
<td>
<span class="programlisting">
<pre>CREATE TRIGGER if_dist_exists
BEFORE INSERT OR UPDATE ON sales
FOR EACH ROW
EXECUTE PROCEDURE check_primary_key ('did', 'distributors', 'did');</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>BEFORE triggers alter the values committed to a table by a data-modification operation, since the processing on the affected records happens before they are changed in the table. AFTER triggers are used often for auditing processes, since they cannot fire until after the row has been changed in the table. INSTEAD OF completely skips the data-modification operation in favor of code that the user provides for the transaction. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Here is an Oracle BEFORE trigger that uses the <span class="emphasis">OLD </span>and <span class="emphasis">NEW </span>pseudo-tables to compare values. (By way of comparison, SQL Server uses the <span class="emphasis">DELETED </span>and <span class="emphasis">INSERTED </span>pseudo-tables in the same way.) This trigger creates an audit record before changing an employee's pay record: </p>
    </td>
  </tr>CREATE TRIGGER if_emp_changes BEFORE DELETE OR UPDATE ON employee FOR EACH ROW WHEN (new.emp_salary <> old.emp_salary) BEGIN INSERT INTO employee_audit VALUES ('old', :old.emp_id, :old.emp_salary, :old.emp_ssn); END;
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The following example builds an Oracle insert and update trigger that uses the IF INSERTED THEN clauses: </p>
    </td>
  </tr>
  <tr>
  	      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
    </tr>
  <tr>
<td>
<span class="programlisting">
<pre>CREATE TRIGGER if_emp_changes
BEFORE DELETE OR UPDATE ON employee
FOR EACH ROW
WHEN (new.emp_salary &lt;&gt; old.emp_salary)
BEGIN
  INSERT INTO employee_audit
  VALUES ('old', :old.emp_id, :old.emp_salary, :old.emp_ssn);
END;</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>This SQL Server example adds a new table called <span class="emphasis">contractor </span>to the database. All records in the <span class="emphasis">employee </span>table that indicate that the employee is a contractor were moved into the <span class="emphasis">contractor</span> table. Now all new employees inserted into the <span class="emphasis">employee </span>table will go into the <span class="emphasis">contractor </span>table instead through an INSTEAD OF trigger: </p>
    </td>
  </tr>
  <tr>
    <td>
    <tr>
		      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
    </tr>
    <tr>
<td>
<span class="programlisting">
<pre>CREATE TRIGGER if_emp_changes
BEFORE DELETE OR UPDATE ON employee
FOR EACH ROW
BEGIN
  IF DELETING THEN
    INSERT INTO employee_audit
    VALUES ('DELETED', :old.emp_id, :old.emp_salary, :old.emp_ssn);
  ELSE
    INSERT INTO employee_audit
    VALUES ('UPDATED', :old.emp_id, :new.emp_salary, :old.emp_ssn);
  END IF;
END;</pre>
</span>
 </td>
  </tr>
</table>
</div>

<div id="CREATE VIEW"><table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td Width="50%" align="left" class="name" valign="top">CREATE VIEW<td Width="50%" align="right"class="name" valign="top">SQL-schema&nbsp;&nbsp;</td></tr></table>
<table width="100%" cellspacing="0" cellpadding="0" border="0">
  <tr>
    <td><p>This statement creates a view , also known as a virtual table . A view acts just like a table but is actually defined as a query. Almost any valid SELECT statement can define the contents of a view, though an ORDER BY clause is usually prohibited. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>When a view is referenced in a statement, the result set of the query becomes the content of the view for the duration of that statement. In some cases, views can be updated, causing the view changes to be translated to the underlying data in the base tables. </p>
    </td>
  </tr><tr>
          <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
      </tr>
    <tr>
    <td>
      <table border="1" >
    <tr><th>Vendor</th>
<th>Command</th></tr>
<tr><td>SQL Server</td><td>Supported, with variations</td></tr><tr><td>MySQL</td><td>Not supported</td></tr><tr><td>Oracle</td><td>Supported, with variations</td></tr><tr><td>PostgreSQL</td><td>Supported, with variations</td></tr></table>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p><span class="emphasis">Warning:</span> Views even can be built upon other views, but this is inadvisable and usually considered bad practice. </p>
    </td>
  </tr>

<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">SQL99 Syntax and Description</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>CREATE TRIGGER if_emp_is_contractor
INSTEAD OF INSERT ON employee
BEGIN
  INSERT INTO contractor
  SELECT * FROM inserted WHERE status = 'CON'

  INSERT INTO employee
  SELECT * FROM inserted WHERE status = 'FTE'
END
GO</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Views are usually as effective as the query upon which they are based. That is why it is important to be sure that the defining SELECT statement is speedy and well-written. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>A column list also may be specified after the view name. The optional column list contains aliases serving as names for each element in the result set of the SELECT statement. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The WITH CHECK OPTION clause is used only on views that allow updates to the base table. It ensures that only data that may be read by the view may be inserted, updated, or deleted by the view. For example, if a view of employees showed only salaried employees, but not hourly employees, it would be impossible to insert, update, or delete hourly employees through that view. The CASCADE and LOCAL options of the CHECK OPTION clause are used for nested views. The CASCADE option performs the check option for the current view and all views it is built on top of. The LOCAL option performs the check option only for the current view, even when it is built upon other views. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>ANSI SQL99 views can update the base table(s) they are based upon if they meet the following conditions: </p>
    </td>
  </tr>
  <tr>
  <td>
<ul>
<li> The defining SELECT
statement is based upon one table. </li>
<li>   The view does not have UNION, MINUS , or INTERSEC
operators. </li>
<li>The defining SELECT
statement does not contain GROUP BY or HAVING clauses.
</li>
<li>The defining SELECT
  statement does not contain any reference to pseudo-columns such as <span class="emphasis">ROWNUM </span>or <span class="emphasis">ROWGUIDCOL</span>.
</li>
<li>The defining SELECT
  statement does not contain any group functions.</li>
<li> The defining SELECT
statement does not contain the DISTINCT clause. </li>
</ul>
</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">Microsoft SQL Server Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>CREATE VIEW view_name [(column list)]
AS
(SELECT_statement
[WITH [CASCADED | LOCAL] CHECK OPTION] )</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Microsoft SQL Server allows two new options not in SQL99: ENCRYPTION and SCHEMABINDING . The ENCRYPTION option encrypts the text of the view in the <span class="emphasis">syscomments</span> table. The SCHEMABINDING option binds the view to a specific schema, meaning that all objects in the view must be referenced by their full name (both owner and object name). Views created with SCHEMABINDING (and tables referenced by these views) must have the schema binding dropped (via ALTER VIEW ) before they may be dropped or altered. VIEW_METADATA specifies that SQL Server returns metadata about the view (rather than the base table) to calls made from DBLIB and OLEDB APIs. Views created or altered with VIEW_METADATA enable their columns to be updated by INSERT and UPDATE INSTEAD OF triggers. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>SQL Server allows indexes to be created on views (see CREATE INDEX ). By creating a unique, clustered index on a view, a SQL Server essentially stores a physical copy of the view on the database. Changes to the base table are automatically updated in the indexed view. </p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p> <span class="emphasis">Warning</span>: Indexed views should be built on base tables using only the SCHEMABINDING
clause. This is an advanced technique and should be used only by experts. Refer
to the vendor documentation for more information on this technique. </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">Oracle Syntax and Variations
</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>CREATE [OR REPLACE] [FORCE | NO FORCE] VIEW [owner_name.]view_name
  [(column [,...n])]
AS
SELECT_statement
[WITH [READ ONLY | CHECK OPTION [CONSTRAINT constraint_name] ] ]</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The OR REPLACE clause tells Oracle that any existing view with the same name should be replaced by the new view. The FORCE clause creates the view regardless of whether the base tables exist or the user creating the view has privileges to the base tables. The NO FORCE clause creates the view only if the base tables and proper privileges are in place. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Oracle allows the use of the CHECK OPTION , including the ability to name the constraint using the CONSTRAINT clause. The CHECK OPTION clause may be used on nested views, but only if the top level view's CHECK OPTION is enforced. If the constraint is not named, Oracle names the constraint SYS_C <span class="emphasis">n </span>, where <span class="emphasis">n </span>is an integer. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Oracle allows data-manipulation operations through views, as long as they meet the SQL99 requirements, and the added requirement does not contain any expressions. The WITH READ ONLY clause ensures the view is used only to retrieve data. </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">PostgreSQL Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>CREATE VIEW view_name AS SELECT_statement</pre></span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>PostgreSQL's CREATE VIEW does not support some of the more complex options that other vendors do. However, it does allow views to be built on tables and other defined class objects. PostgreSQL views are typically built only upon other tables, not upon other views, and are not used to perform data modifications on the underlying base tables. </p>
    </td>
  </tr>
<tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="example"><span class="title">
  Example</span>
</td>
</tr>
  <tr>
    <td><p>The simplest view is based on the entire contents of a single table: </p>
    </td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
<td>
<span class="programlisting">
<pre>CREATE VIEW employees
AS
SELECT *
FROM employee_tbl;</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>This example shows a view named california_authors that allows data modifications to apply only to authors within the state of California: </p>
    </td>
  </tr>
  <tr>
    <td><tr>
<td>
<span class="programlisting">
<pre>CREATE VIEW california_authors
AS
SELECT au_lname, au_fname, city, state
FROM authors
WHERE state = 'CA'
WITH CHECK OPTION
GO</pre>
</span>
    </td>
  </tr>
</table>
</div>

<div id="DECLARE CURSOR"><table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td Width="50%" align="left" class="name" valign="top">DECLARE CURSOR<td Width="50%" align="right"class="name" valign="top">SQL-data&nbsp;&nbsp;</td></tr></table>
<table width="100%" cellspacing="0" cellpadding="0" border="0">
   <tr>
    <td><p>The DECLARE CURSOR command enables the retrieval and manipulation of records from a table one row at a time. This provides row-by-row processing, rather than the traditional set processing offered by SQL. To use this procedure properly, you should: </p>
    </td>
  </tr>
<ol>
<li>DECLARE the cursor</li>
<li>OPEN the cursor</li>
<li>FETCH rows from the cursor</li>
<li>When finished, CLOSE the cursor</li>
</ol>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>MySQL does not support server-side cursors in the ANSI SQL style, but does support extensive C-programming extensions that provide the same functionality. </p>
    </td>
  </tr>
   <tr>
       <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
      </tr>
    <tr>
    <td>
      <table border="1" >
    <tr><th>Vendor</th>
<th>Command</th></tr>
<tr><td>SQL Server</td><td>Supported</td></tr><tr><td>MySQL</td><td>Not supported</td></tr><tr><td>Oracle</td><td>Supported</td></tr><tr><td>PostgreSQL</td><td>Supported</td></tr></table>
</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">SQL99 Syntax and Description</span></td>
  </tr>
  <tr>
    <td><p>The DECLARE CURSOR command works by specifying a SELECT statement. Each row returned by the SELECT statement may be individually retrieved and manipulated. The DECLARE CURSOR command also defines the characteristics of a server-side cursor. The characteristics might include how the cursor scrolls and the SELECT statement used to retrieve a result set. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Microsoft SQL Server allows the INSENSITIVE and SCROLL options to be identified. The INSENSITIVE keyword specifies that the cursor build a temporary copy of the result set used by the cursor. All requests to the cursor are answered from the temporary table, not the base table. The cursor does not allow modifications. Subsequent fetches by the cursor do not reflect any changes made by the cursor. The SCROLL keyword enables all FETCH options for the cursor ( FIRST , LAST , PRIOR , NEXT , RELATIVE , and ABSOLUTE ). Refer to the FETCH command for more details. If SCROLL is not declared, only NEXT is available as a FETCH option. A read-only cursor also can be declared using the FOR READ ONLY clause. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>In Oracle, variables are not allowed in the WHERE clause of the SELECT statement unless they are first declared as variables. The parameters are not assigned at the DECLARE ; instead, they are assigned values at the OPEN command. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>PostgreSQL has an implementation that is very similar to Microsoft SQL Server, except that it allows a BINARY option. BINARY forces the cursor to retrieve binary-formatted data rather than text-formatted data. </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">Microsoft SQL Server Syntax

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><span class="programlisting">
    <pre>DECLARE cursor_name [INSENSITIVE] [SCROLL] CURSOR
    FOR select_statement
    [FOR {READ ONLY | UPDATE [OF column_name [,...n]]}]</pre>
</span>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">Oracle Syntax
  </span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>DECLARE CURSOR cursor_name [parameter1 datatype1 [,...parameterN datatypeN]
IS select_statement
[FOR UPDATE [OF column_name [,...n]]}]</pre>
</span>
    </td>
  </tr>

<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">PostgreSQL Syntax</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>DECLARE cursor_name [BINARY] [INSENSITIVE] [SCROLL] CURSOR
FOR select_statement
[FOR {READ ONLY | UPDATE [OF column_name [,...n]]}]</pre>
</span>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">Microsoft SQL Server Syntax and Variations</span></td>
  </tr>
  <tr>
    <td><p>Microsoft SQL Server supports the standard format described previously in this chapter, but also has a more elaborate extension. The syntax for this is: </p>
    </td>
  </tr><tr>
<td>
<span class="programlisting">
<pre>DECLARE cursor_name CURSOR
[LOCAL | GLOBAL] [FORWARD_ONLY | SCROLL]
[STATIC | KEYSET | DYNAMIC | FAST_FORWARD]
[READ_ONLY | SCROLL_LOCKS | OPTIMISTIC]
[TYPE_WARNING]
FOR select_statement
[FOR UPDATE [OF column_name [,...n]]]</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>This syntax works in the same way as the ANSI-standard cursor declaration, but it offers many new functionalities. First, the scope of the cursor may be declared as LOCAL or GLOBAL . If LOCAL , the cursor is available only within the current Transact-SQL batch, stored procedure, or trigger in which it was declared. If GLOBAL , the cursor is available as the OPEN and FETCH commands throughout the connection. </p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p> <span class="emphasis">Warning</span>: Transact-SQL notation should not be mixed with the ANSI-standard
  cursor declaration in Microsoft SQL Server.</p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The next several options determine how the cursor searches through the record set. FORWARD_ONLY , as opposed to SCROLL , specifies that the cursor can scroll only from the first record to the last. It cannot be used in conjunction with STATIC , KEYSET , or DYNAMIC . It acts as a DYNAMIC cursor. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>STATIC functions similarly to the keyword INSENSITIVE . KEYSET is similar to STATIC and INSENSITIVE , except that it allows modifications to the result set. The keyset is unaware of records inserted by other users once the cursor has been opened, though records deleted by other users produce an @@FETCH_STATUS of -2. New values are made visible when updates are done by specifying WHERE CURRENT OF . DYNAMIC reflects all data changes made to the result set during work with the cursor. The result set can change during any FETCH . FETCH ABSOLUTE is not supported by DYNAMIC cursors. FAST_FORWARD is shorthand for FORWARD_ONLY , READ_ONLY , but it also enables extra functionality. FAST_FORWARD is mutually exclusive of SCROLL , FOR_UPDATE , SCROLL_LOCKS , OPTIMISTIC , and FORWARD_ONLY . </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Two other options also are allowed for READ_ONLY : SCROLL_LOCKS and OPTIMISTIC . SCROLL_LOCKS forces a record-level lock whenever a new record is fetched, ensuring that updates and deletes made through the cursor succeed. OPTIMISTIC specifies that positioned updates and deletes made through the cursor fail if the row is changed by another user. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Finally, the TYPE_WARNING option tells SQL Server that a warning message should be sent to the client if it is transformed from one type to another (for example, KEYSET to DYNAMIC) . </p>
    </td>
  </tr>
<tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="example"><span class="title">
  Example</span>
</td>
</tr>
  <tr>
    <td><p>In this simple example from Microsoft SQL Server, a cursor from the <span class="emphasis">publishers</span> table is declared and opened. The cursor takes the first record from <span class="emphasis">publisher</span> that matches the SELECT statement and inserts it into another table; it then moves to the next record and the next, until all records are processed. Finally, the cursor is closed and deallocated ( deallocate is only used in Microsoft SQL Server): </p>
    </td>
  </tr>
    <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
<td>
<span class="programlisting">
<pre>DECLARE @publisher_name VARCHAR(20)

DECLARE pub_cursor CURSOR
FOR SELECT pub_name FROM publishers
    WHERE country &lt;&gt; 'USA'

OPEN pub_cursor
FETCH NEXT FROM pub_cursor INTO @publisher_name
WHILE @@FETCH_STATUS = 0
BEGIN
    INSERT INTO foreign_publishers VALUES(@publisher_name)
END

CLOSE pub_cursor
DEALLOCATE pub_cursor</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>In this Oracle example, the cursor is declared in the declaration block along with some other variables, and the rest of the cursor is then processed: </p>
    </td>
  </tr>
    <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
<td>
<span class="programlisting">
<pre>DECLARE
   new_price NUMBER(10,2);
   CURSOR title_price_cursor IS
      SELECT title, price
      FROM titles
      WHERE price IS NOT NULL;
   title_price_val title_price_cursor%ROWTYPE;
BEGIN
   OPEN title_price_cursor;
   FETCH title_price_cursor INTO title_price_val;
   new_price := "title_price_val.price" * 1.25
   INSERT INTO new_title_price VALUES (title_price_val.title, new_price)
   CLOSE title_price_cursor;
END;</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Because this example uses a lot of PL/SQL, much of the code is beyond the scope of this book. However, the DECLARE block clearly shows that the cursor is declared. In the PL/SQL execution block, the cursor is initialized with the OPEN command, values are retrieved with the FETCH command, and the cursor finally is terminated with the CLOSE command. </p>
    </td>
  </tr>
</table>
</div>

<div id="DELETE">
<table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td Width="50%" align="left" class="name" valign="top">DELETE<td Width="50%" align="right"class="name" valign="top">SQL-data&nbsp;&nbsp;</td></tr></table>
<table width="100%" cellspacing="0" cellpadding="0" border="0">

  <tr>
    <td><p>The DELETE statement erases records from a specified table or tables. It is a logged operation, meaning that it can be undone with a ROLLBACK command. </p>
    </td>
  </tr><tr>
          <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
      </tr>
    <tr>
    <td>
      <table border="1" >
    <tr><th>Vendor</th>
<th>Command</th></tr>
<tr><td>SQL Server</td><td>Supported, with variations</td></tr><tr><td>MySQL</td><td>Supported, with variations</td></tr><tr><td>Oracle</td><td>Supported</td></tr><tr><td>PostgreSQL</td><td>Supported</td></tr></table>
</td>
</tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p><span class="emphasis">Warning: </span>It is rare to issue a DELETE statement without a WHERE clause,
  because this results in deleting all rows from the affected table. </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">SQL99 Syntax and Description</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>DELETE [FROM] [owner.]table_name [WHERE clause]</pre></span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>If it becomes necessary to remove all the rows in a table, it is preferable to use the TRUNCATE TABLE statement. In those databases that support the command, this is usually a faster method to physically remove all rows. TRUNCATE TABLE is faster than DELETE because TRUNCATE is not logged, making rollback impossible. The reduction of logging overhead saves considerable time when erasing a large number of records. </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">Microsoft SQL Server Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>DELETE [FROM] [owner.] {table_name | view_name}
[WITH (query_hint[,...n]]
[FROM table_source[,...n]]
[WHERE clause | [CURRENT OF [GLOBAL] cursor_name]]
[OPTION (query_hint[,...n])]</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Microsoft SQL Server allows records to be deleted both from tables and from views that describe a single table. (There are some other special rules that allow deletion from a multitable view, but they are quite complex and beyond the scope of this book.) At two points in the command, after the first FROM and at the end of the statement, SQL Server's default optimizer behavior can be overridden, but this should be done only by experts. These hints are not a part of the ANSI standard, but they are part of most vendor documentation. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Additionally, SQL Server allows a second FROM clause. The second FROM allows the use of the JOIN statement and makes it quite easy to delete rows from the table in the first FROM (based on corresponding rows of a table declared in the second FROM) . </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The WHERE CURRENT OF clause is used for positioned deletes through a cursor. In conjunction with a cursor, this form of DELETE erases only the row that currently is opened by the cursor. </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">MySQL Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>DELETE [LOW_PRIORITY] FROM table_name [WHERE clause] [LIMIT rows]</pre></span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>MySQL is optimized for speed. With that in mind, it allows the option of specifying LOW PRIORITY , which delays the execution of DELETE until no other clients are reading from the table. MySQL also can place an arbitrary cap on the number of records deleted before control is passed back to the client using the LIMIT nbr_of_rows clause. </p>
    </td>
  </tr>

<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">Oracle Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>DELETE FROM [schema.]{table_name | view_name | snapshot_name}
   {PARTITION (partition_name) | SUBPARTITION (subpartition_name)} |
[WHERE clause]
[subquery WITH {READ ONLY | CHECK OPTION [CONSTRAINT constraint_name]} ]
[RETURNING expression[,...] INTO variable[,...]</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Oracle allows you to delete rows from tables, views, and partitioned views and tables. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>PARTITION and SUBPARTITION specify the name of the partition or subpartition within the table that should be deleted. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The WITH clause is used in conjunction with a subquery. It restricts the actions of the DELETE statement. The WITH READ ONLY option specifies that any subquery used in the command cannot be updated. WITH CHECK OPTION tells Oracle to DELETE any rows that are not in the subquery. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>RETURNING retrieves the rows affected by the command. When used for a single-row delete, the values of the row are stored in PL/SQL variables and bind variables. When used for a multirow delete, the values of the rows are stored in bind arrays. The INTO keyword specifies that the deleted values should be stored in the variables list. </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">PostgreSQL Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>DELETE FROM [ONLY] <replaceable>table</replaceable>
[WHERE {clause | CURRENT OF cursor_name}]</pre>
</span>
</td>
</tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>PostgreSQL uses the DELETE command to remove rows from the table and any defined subclasses from the table. When deleting rows from only the table specified, use the ONLY clause. The WHERE CURRENT OF clause tells PostgreSQL to delete only the currently open row of the named, open cursor. </p>
    </td>
  </tr>

<tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="example"><span class="title">
  Example</span>
</td>
</tr>
   <tr>
    <td><p>To delete all records from the <span class="emphasis">titles</span> table: </p>
    </td>
  </tr><tr>
<td>
<span class="programlisting">DELETE titles</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>To delete all records in the <span class="emphasis">authors </span>table where the last name starts with `Mc': </p>
    </td>
  </tr><tr>
<td>
<span class="programlisting"><pre>DELETE FROM authors
WHERE au_lname LIKE 'Mc%'</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>To delete all titles with an old ID number: </p>
    </td>
  </tr><tr>
<td>
<span class="programlisting">DELETE titles WHERE title_id >= 40</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>To delete all titles that have no sales: </p>
    </td>
  </tr><tr>
<td>
<span class="programlisting">DELETE titles WHERE ytd_sales IS NULL</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>To delete all records in one table based on the results of a subquery against another table (in this case, the records are erased in the <span class="emphasis">titleauthor</span> table that have a match concerning `computers' in the <span class="emphasis">titles</span> table): </p>
    </td>
  </tr>
  <tr>
    <td><tr>
<td>
<span class="programlisting">
<pre>DELETE FROM titleauthor
WHERE title_id IN
  (SELECT title_id
  FROM titles
  WHERE title LIKE '%computers%')</pre>
</span>
    </td>
  </tr>
</table>
</div>

<div id="DISCONNECT"><table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td Width="50%" align="left" class="name" valign="top">DISCONNECT
  <td Width="50%" align="right"class="name" valign="top">SQL-connection&nbsp;&nbsp;</td>
</tr></table>
<table width="100%" cellspacing="0" cellpadding="0" border="0">
   <tr>
    <td><p>The DISCONNECT statement terminates a connection to the DBMS. </p>
    </td>
  </tr><table border="1" >
<tr><th>Vendor</th>
<th>Command</th></tr>
<tr><td>SQL Server</td><td>Supported, with limitations</td></tr><tr><td>MySQL</td><td>Not supported</td></tr><tr><td>Oracle</td><td>Supported, with variations</td></tr><tr><td>PostgreSQL</td><td>Not supported</td></tr></table>
</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">SQL99 Syntax and Description</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
DISCONNECT {CURRENT | ALL | connection_name}</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>This command ends one or more connections created between the current SQL process and the database server. The CURRENT clause closes the currently active user connection. The ALL clause closes all open connections for the current user. Alternately, it's possible to close only a specific connection. </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">Microsoft SQL Server Syntax and Variations</span></td>
  </tr>
  <tr>
    <td><p>Microsoft SQL Server supports DISCONNECT in Embedded-SQL (ESQL) only, not within its ad hoc querying tool, SQL Query Analyzer. It supports the full SQL99 syntax. When disconnecting from Microsoft SQL Server in an ESQL program, the DISCONNECT ALL command should be used to disconnect cleanly from the database server. </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">Oracle Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
DISC[ONNECT]</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>In contrast to SQL Server, Oracle allows DISCONNECT only in its ad hoc query tool, SQL*Plus. In this usage, the command ends the current session with the database server but otherwise allows work in SQL*Plus to continue. For example, a programmer can continue to edit the buffer, save run files, and so on. However, a reconnection must be established to issue any SQL commands. Exiting SQL*Plus and returning to the filesystem requires the EXIT or QUIT commands. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Oracle also supports this functionality with the command ALTER SYSTEM DISCONNECT SESSION . However, this is a privileged command available only to the DBA for forcibly disconnecting a session (usually a rogue session) from the database. </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">PostgreSQL/span></td>
  </tr>
  <tr>
    <td><p>PostgreSQL does not explicitly support the DISCONNECT command. However, every programming interface does support a disconnect operation; for example, SPI_FINISH is available under the Server Programming Interface, and PG_CONNECT is available under the PL/tcl programming package. </p>
    </td>
  </tr>
<tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="example"><span class="title">
  Example</span>
</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>End the current connection with an Oracle server: </p>
    </td>
  </tr><tr>
<td>
<span class="programlisting">DISCONNECT;</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Microsoft SQL Server supports DISCONNECT within ESQL programs only: </p>
    </td>
  </tr>
  <tr>
    <td><tr>
<td>
<span class="programlisting">EXEC SQL DISCONNECT new_york;</span>
</td>
</tr>
    </td>
  </tr>
</table>
</div>

<div id="DROP DATABASE"><table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td Width="50%" align="left" class="name" valign="top">DROP DATABASE<td Width="50%" align="right"class="name" valign="top">SQL-schema&nbsp;&nbsp;</td></tr></table>
<table width="100%" cellspacing="0" cellpadding="0" border="0">
  <tr>
    <td><p>DROP DATABASE undoes all the work done by the CREATE DATABASE command. It drops all existing database objects and releases the space used by them. With most vendors this command cannot be executed while users (including the owner) are active in the database. </p>
    </td>
  </tr><table border="1" >
<tr><th>Vendor</th>
<th>Command</th></tr>
<tr><td>SQL Server</td><td>Supported</td></tr><tr><td>MySQL</td><td>Supported</td></tr><tr><td>Oracle</td><td>Not supported</td></tr><tr><td>PostgreSQL</td><td>Supported</td></tr></table>
</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">SQL99 Syntax and Description</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
DROP DATABASE database_name</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Like CREATE DATABASE , DROP DATABASE is supported by ANSI SQL only as an extension and not as a core command. SQL99 prefers commands relating to SCHEMA and DOMAIN to cover areas that roughly correspond to what most implementations would consider "database" issues. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The system databases created by the database vendor should never be dropped. Dropping a database requires explicit permissions, unless performed by the database owner or the system administrator. </p>
    </td>
  </tr>


<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">Microsoft SQL Server Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
DROP DATABASE database_name [,...n]</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>In SQL Server, multiple databases may be dropped in the same command by adding a comma between each database name. A database may be dropped only by a user in the master database, a user who has sys admin privileges, or the database owner. The database must be ONLINE to be dropped. </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">PostgreSQL Syntax and Variations</span></td>
  </tr>
  <tr>
    <td><p>In MySQL and PostgreSQL, this command removes an entire database and all associated files. The DB sends a message indicating how many files were deleted. A database that is open and in use under the PostgreSQL implementation may not be dropped. </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">Oracle Syntax and Variations</span></td>
  </tr>
  <tr>
    <td><p>Oracle does not support DROP DATABASE . A database may be destroyed by issuing the command CREATE DATABASE database_name (without parameters), using the same name as the database to be destroyed. </p>
    </td>
  </tr>
</table>
</div>

<div id="DROP FUNCTION"><table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td Width="50%" align="left" class="name" valign="top">DROP FUNCTION<td Width="50%" align="right"class="name" valign="top">SQL-schema&nbsp;&nbsp;</td></tr></table>
<table width="100%" cellspacing="0" cellpadding="0" border="0">
  <tr>
    <td><p>This command removes a user-defined function from the current database. </p>
    </td>
  </tr><table border="1" >
<tr><th>Vendor</th>
<th>Command</th></tr>
<tr><td>SQL Server</td><td>Supported, with variations</td></tr><tr><td>MySQL</td><td>Supported, with variations</td></tr><tr><td>Oracle</td><td>Supported, with variations</td></tr><tr><td>PostgreSQL</td><td>Supported, with variations</td></tr></table>
</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">SQL99 Syntax and Description</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
DROP FUNCTION function_name {RESTRICT | CASCADE}</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>This command permanently destroys a function. The RESTRICT clause ensures that the command fails if other database objects, such as a view, depend upon the function. On the other hand, the CASCADE option drops the function, any grants based on the function, and any dependent database objects! </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">Microsoft SQL Server Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
DROP FUNCTION [owner_name.]function_name [,...n]</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>As with other SQL Server DROP commands, more than one database object of the same type may be dropped by placing a comma between the names of each database object. </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">MySQL Syntax and Variations</span></td>
  </tr>
 <tr>
    <td><p>This command does not actually delete the file containing the function. Instead, it deletes the function reference from the system table, which can be added back by using the CREATE FUNCTION statement. </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">Oracle Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">DROP FUNCTION [owner_name.]function_name</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>As with other Oracle DROP commands, the name of the function owner may be specified. Otherwise, Oracle assumes the current-user context, and only functions owned by the current user to be dropped. Alternately, those users with DROP ANY FUNCTION system privilege are allowed to drop any function anywhere. </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">PostgreSQL Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
DROP FUNCTION name ( [ type [,...n] ] )</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>PostgreSQL allows functions declared in any programming language to be dropped. Type is the input argument of the function to be dropped. Type must be specified, since only the function with the given name and parameter types is destroyed. </p>
    </td>
  </tr>
</table>
</div>

<div id="DROP INDEX"><table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td Width="50%" align="left" class="name" valign="top">DROP INDEX<td Width="50%" align="right"class="name" valign="top">SQL-schema&nbsp;&nbsp;</td></tr></table>
<table width="100%" cellspacing="0" cellpadding="0" border="0">
   <tr>
    <td><p>The DROP INDEX command destroys one or more indexes within the current database. When an index is dropped, all the space it previously consumed is immediately regained. DROP INDEX does not, however, destroy PRIMARY KEY or UNIQUE constraints, which must be done with the ALTER TABLE . . . DROP command. Refer to the CREATE TABLE command for more information about primary key and unique constraints. </p>
    </td>
  </tr><table border="1" >
<tr><th>Vendor</th>
<th>Command</th></tr>
<tr><td>SQL Server</td><td>Supported, with variations</td></tr><tr><td>MySQL</td><td>Supported, with variations</td></tr><tr><td>Oracle</td><td>Supported, with variations</td></tr><tr><td>PostgreSQL</td><td>Supported, with variations</td></tr></table>
</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">SQL99 Syntax and Description</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
DROP INDEX table_name.index_name</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>PostgreSQL follows the SQL99 standard, with variations. </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">Microsoft SQL Server Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
DROP INDEX {table_name | view_name}.index_name [,...n]</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Microsoft SQL Server allows indexes created on both tables and views to be dropped. If a clustered index on a table that contains nonclustered indexes is dropped, all nonclustered indexes are rebuilt and assigned new pointers. </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">MySQL Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
DROP INDEX table_name.index_name [,...n]</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Older versions of MySQL include this command only for compatibility reasons; however, newer versions actually destroy the specified index. The statement is functionally equivalent to the MySQL statement ALTER TABLE . . . DROP INDEX . </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>MySQL allows multiple indexes to be dropped by separating each table and index name with a comma. </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">Oracle Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
DROP INDEX [owner_name.]index_name</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Oracle allows indexes to be dropped directly by name without providing the table name. Oracle also allows the index to be dropped based on the owner name. </p>
    </td>
  </tr>
</table>
</div>


<div id="DROP PROCEDURE"><table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td Width="50%" align="left" class="name" valign="top">DROP PROCEDURE<td Width="50%" align="right"class="name" valign="top">SQL-schema&nbsp;&nbsp;</td></tr></table>
<table width="100%" cellspacing="0" cellpadding="0" border="0">
  <tr>
    <td><p>This command destroys an existing stored procedure in the current user database. </p>
    </td>
  </tr><table border="1" >
<tr><th>Vendor</th>
<th>Command</th></tr>
<tr><td>SQL Server</td><td>Supported</td></tr><tr><td>MySQL</td><td>Not supported</td></tr><tr><td>Oracle</td><td>Supported</td></tr><tr><td>PostgreSQL</td><td>Not supported</td></tr></table>
</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">SQL99 Syntax and Description</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">DROP PROCEDURE procedure_name {RESTRICT | CASCADE}</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>This command is essentially the same as DROP FUNCTION , except that it acts upon stored procedures rather than functions. </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">Microsoft SQL Server Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
DROP PROCEDURE [owner_name.]procedure_name [,...n]</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Microsoft SQL Server allows the removal of multiple stored procedures by placing a comma between the name of each one. Individual versions of stored procedures cannot be dropped. The entire group of stored-procedure versions must be dropped. </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">Oracle Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
DROP PROCEDURE [owner_name.]procedure_name</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Oracle also allows any procedure to be dropped based on the owner name. Users with the system privilege, DROP ANY PROCEDURE , may drop procedures owned by other users. </p>
    </td>
  </tr>
</table>
</div>

<div id="DROP ROLE"><table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td Width="50%" align="left" class="name" valign="top">DROP ROLE<td Width="50%" align="right"class="name" valign="top">SQL-schema&nbsp;&nbsp;</td></tr></table>
<table width="100%" cellspacing="0" cellpadding="0" border="0">
  <tr>
    <td><p>This command destroys a named set of user privileges in the current user database. </p>
    </td>
  </tr><table border="1" >
<tr><th>Vendor</th>
<th>Command</th></tr>
<tr><td>SQL Server</td><td>Not supported</td></tr><tr><td>MySQL</td><td>Not supported</td></tr><tr><td>Oracle</td><td>Supported, with variations</td></tr><tr><td>PostgreSQL</td><td>Not supported</td></tr></table>
</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">SQL99 Syntax and Description</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
DROP ROLE role_name</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The DROP ROLE command destroys the specified role. Only users who have WITH ADMIN OPTION may drop roles. </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">Oracle Syntax</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
DROP ROLE [owner_name.]role_name;</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Executing the DROP ROLE command destroys the role in the current user database. It is no longer usable by any users or roles who previously had the role assigned to them. </p>
    </td>
  </tr>
</table>
</div>

<div id="DROP TABLE"><table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td Width="50%" align="left" class="name" valign="top">DROP TABLE<td Width="50%" align="right"class="name" valign="top">SQL-schema&nbsp;&nbsp;</td></tr></table>
<table width="100%" cellspacing="0" cellpadding="0" border="0">
    <tr>
    <td><p>This command removes a table definition and all data, indexes, triggers, constraints, and permission specifications for that table. Any view or stored procedure that references the dropped table encounters problems, unless they are explicitly altered or dropped as well. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Some vendors do not allow a table to be dropped unless certain other characteristics of the table are dropped first. For example, Microsoft SQL Server requires that the table be dropped from any replication scheme and FOREIGN KEY references be dropped before the table itself is dropped. </p>
    </td>
  </tr><table border="1" >
<tr><th>Vendor</th>
<th>Command</th></tr>
<tr><td>SQL Server</td><td>Supported, with variations</td></tr><tr><td>MySQL</td><td>Supported, with variations</td></tr><tr><td>Oracle</td><td>Supported, with variations</td></tr><tr><td>PostgreSQL</td><td>Supported, with variations</td></tr></table>
</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">SQL99 Syntax and Description</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">DROP TABLE table_name RESTRICT | CASCADE</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>In the SQL99 syntax, RESTRICT prohibits the DBMS from executing the command if views or constraints currently reference the table to be dropped. The CASCADE clause causes any referencing objects to be dropped along with the table. </p>
    </td>
  </tr><tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">Microsoft SQL Server Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
DROP TABLE [database_name.][owner_name.]table_name [,...n] GO</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Microsoft SQL Server allows more than one table to be dropped at a time by including a comma between each table name. Tables also may be dropped in databases outside of the current context by specifying the database name (assuming the user has the right permissions). Any constraints or triggers on the table are dropped with the table. Explicitly declared rules and defaults lose their bindings when their underlying table is dropped. Views and stored procedures that reference a dropped table produce an error when they are executed and the table is found to be missing. </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">MySQL Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
DROP TABLE [IF EXISTS] table_name;</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>MySQL permanently and completely deletes the table and all associated files when this command is executed. The IF EXISTS syntax can be added to avert a returned error when attempting to drop a table that might not exist. </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">Oracle Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
DROP TABLE [owner_name.]table_name [CASCADE CONSTRAINTS];</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Dropping a table in Oracle frees the space used by the table and commits any pending changes to the database. When a table is dropped, all the space it previously consumed is immediately regained. All indexes and grants associated with the table are lost. Objects, such as views, stored procedures, and synonyms built upon the table, are marked invalid and cease to function. </p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p><span class="emphasis">Tip</span>: Take
  into account that in Oracle, executing any ALTER
,CREATE,  or DROP
command causes any other pending transactions to commit. </p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The CASCADE CONSTRAINTS clause drops all integrity constraints referring to keys in the dropped table. </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">PostgreSQL Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
DROP TABLE table_name;</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>PostgreSQL supports only the basic DROP TABLE command. </p>
    </td>
  </tr>
</table>
</div>

<div id="DROP TRIGGER"><table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td Width="50%" align="left" class="name" valign="top">DROP TRIGGER<td Width="50%" align="right"class="name" valign="top">SQL-schema&nbsp;&nbsp;</td></tr></table>
<table width="100%" cellspacing="0" cellpadding="0" border="0">
   <tr>
    <td><p>The DROP TRIGGER command removes a trigger for a table within the current database. </p>
    </td>
  </tr><table border="1" >
<tr><th>Vendor</th>
<th>Command</th></tr>
<tr><td>SQL Server</td><td>Supported, with variations</td></tr><tr><td>MySQL</td><td>Not supported</td></tr><tr><td>Oracle</td><td>Supported, with variations</td></tr><tr><td>PostgreSQL</td><td>Supported, with variations</td></tr></table>
</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">SQL99 Syntax and Description</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
DROP TRIGGER trigger_name</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>DROP TRIGGER removes a trigger from the current database. MySQL does not support this command. </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">Microsoft SQL Server Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">DROP TRIGGER [owner_name.]trigger_name [,...n] GO</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Microsoft SQL Server allows multiple triggers to be dropped by placing a comma between each trigger name. </p>
    </td>
  </tr>

Oracle Syntax and Variations
DROP TRIGGER [owner_name.]trigger_name;
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Oracle drops the indicated trigger and commits pending changes to the database when this command is executed. </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">PostgreSQL Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
DROP TRIGGER trigger_name ON table_name;</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>PostgreSQL requires that the table where the trigger resides is named. It then drops all references to an existing trigger when this command is executed. </p>
    </td>
  </tr>
</table>
</div>

<div id="DROP VIEW">
<table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td Width="50%" align="left" class="name" valign="top">DROP VIEW<td Width="50%" align="right"class="name" valign="top">SQL-schema&nbsp;&nbsp;</td></tr></table>
<table width="100%" cellspacing="0" cellpadding="0" border="0">
   <tr>
    <td><p>This command permanently removes a view from the current database. </p>
    </td>
  </tr><table border="1" >
<tr><th>Vendor</th>
<th>Command</th></tr>
<tr><td>SQL Server</td><td>Supported</td></tr><tr><td>MySQL</td><td>Not supported</td></tr><tr><td>Oracle</td><td>Supported</td></tr><tr><td>PostgreSQL</td><td>Supported</td></tr></table>
</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">SQL99 Syntax and Description</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
DROP VIEW view_name RESTRICT | CASCADE</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>In the SQL99 syntax, RESTRICT tells the DBMS to prohibit the drop if views or assertions that currently reference the table are to be dropped. The CASCADE clause causes any referencing objects to be dropped along with the view. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>This command is not currently supported by MySQL. </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">Microsoft SQL Server Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
DROP VIEW [owner_name.]view_name [,...n] GO</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Microsoft SQL Server allows multiple views to be dropped in a single command by placing a comma between each view name. The views must reside in the same database. Information about the view is removed from all system tables. </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">Oracle Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
DROP VIEW [owner_name.]view_name;</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>As with other Oracle DROP commands, the owner name may be specified along with the view name. Users with the system privilege, DROP ANY VIEW, may drop views owned by other users. </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">PostgreSQL Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
DROP VIEW view_name;</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>In PostgreSQL, the DROP VIEW command drops an existing view from the current database. Only the owner of the view may drop it. The PostgreSQL command DROP TABLE also can be used to drops views. </p>
    </td>
  </tr>
</table>
</div>

<div id="FETCH"><table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td Width="50%" align="left" class="name" valign="top">FETCH
  <td Width="50%" align="right"class="name" valign="top">SQL-data&nbsp;&nbsp;</td>
</tr></table>
<table width="100%" cellspacing="0" cellpadding="0" border="0">
    <tr>
    <td><p>The FETCH command is one of four commands used in cursor processes. FETCH retrieves a specific row from a server-side cursor. </p>
    </td>
  </tr><table border="1" >
<tr><th>Vendor</th>
<th>Command</th></tr>
<tr><td>SQL Server</td><td>Supported</td></tr><tr><td>MySQL</td><td>Not supported</td></tr><tr><td>Oracle</td><td>Supported, with variations</td></tr><tr><td>PostgreSQL</td><td>Supported, with variations</td></tr></table>
</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">SQL99 Syntax and Description</span></td>
  </tr>
  <tr>
    <td><p>The FETCH command retrieves a record from the cursor_name (created by the DECLARE CURSOR statement), based on either the NEXT , PRIOR , FIRST , LAST , ABSOLUTE , or RELATIVE keyword. The values retrieved by the FETCH statement optionally may be stored in variables. The FETCH operations are: </p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>NEXT:<br>
Tells the cursor to return the record immediately following the current row,
and increments the current row to the row returned.
FETCH NEXT
is the default behavior for FETCH and retrieves the first record if it is performed
as the first fetch against
a cursor. (PostgreSQL uses the keyword FORWARD
or the string FETCH RELATIVE NEXT.
) </p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>PRIOR:<br>
 Tells the cursor to return the record immediately preceding the current row,
  and decrements the current row to the row returned. FETCH PRIOR
does not retrieve a record if it is performed as the first fetch against the
cursor. (PostgreSQL uses the keyword BACKWARD
or the string FETCH RELATIVE PRIOR
.) </p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>FIRST:<br>
 Tells the cursor to return the first record in the cursor and makes it the
  current row. (Not supported by PostgreSQL.)
</p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>LAST:<br>
Tells the cursor to return the last record in the cursor and makes it the
current row. (Not supported by PostgreSQL.)</p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>ABSOLUTE {n}:<br>
 Tells the cursor to return the nth record from the cursor record set counting
  from the top (if n is positive), or nth record counting from the bottom (if
  n is negative), making the returned record the new current record of the cursor.
  If n is 0, no rows are returned. (Not supported by PostgreSQL.)
</p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>RELATIVE {n}:<br>
 Tells the cursor to return the record n rows after the current record (if
  n is positive) or n rows before the current record (if n is negative), making
  the returned record the new current row of the cursor. If n is 0, the current
  row is returned. (Supported as described by PostgreSQL except where n is 0.)
</p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The INTO keyword allows data from each column in the FETCH command to be placed into a local variable. Each column in the FETCH command must have a corresponding variable of a matching datatype in the INTO clause. ( INTO is not supported by PostgreSQL.) </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>PostgreSQL cursors may be used only within explicitly declared transactions using BEGIN , COMMIT , or ROLLBACK . PostgreSQL allows either a specific number of records to be retrieved or all of them, using either a number or the keyword ALL . </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">Oracle Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>FETCH cursor_name
{INTO variable_name1 [,...n] ]
| BULK COLLECT INTO [collection_name [,...n] }</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Oracle cursors are forward-scrolling cursors. They must either insert the retrieved values into matching variables, or using the BULK COLLECT clause, bulk-bind the output before passing it back to the PL/SQL parser. FETCH often is paired with a PL/SQL FOR loop to process all the rows in the cursor. </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">PostgreSQL Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>FETCH [ FORWARD | BACKWARD | RELATIVE [ { [ # | ALL | NEXT | PRIOR ] } ]  ]
[ count ]
FROM cursor_name</pre>
</span>
</td>
</tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>PostgreSQL cursors may be used only within explicitly declared transactions using BEGIN , COMMIT , or ROLLBACK . </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The cursor can be FORWARD scrolling, BACKWARD scrolling, or RELATIVE scrolling. The RELATIVE clause may include either a number of records to retrieve or all of them, using either a number or the keyword ALL . </p>
    </td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="example"><span class="title">
  Example</span>
</td>
</tr>
   <tr>
    <td><p>This Oracle example retrieves several elements of the <span class="emphasis">employee_new_hires_cursor</span> (refer to the example under DECLARE CURSOR ) into some local variables: </p>
    </td>
  </tr>
    <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
    </tr>

  <tr>
  <td>
  <span class="programlisting">
  <pre>FETCH FROM employee_new_hires_cursor
  INTO : emp_id, :fname, :lname, :job_id</pre>
  </span
  </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>This PostgreSQL retrieves five records from the <span class="emphasis">employee</span> table: </p>
    </td>
  </tr>
  <tr>
    <td><tr>
<td>
<span class="programlisting">
FETCH FORWARD 5 IN employee_new_hires_cursor;</span>
</td>
</tr>
 </table>
</div>

<div id="GRANT">
<table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td Width="50%" align="left" class="name" valign="top">GRANT<td Width="50%" align="right"class="name" valign="top">SQL-schema&nbsp;&nbsp;</td></tr></table>
<table width="100%" cellspacing="0" cellpadding="0" border="0">
    <tr>
    <td><p>In SQL99, the GRANT statement authorizes users and roles to access and use database objects. Most database vendors also use the GRANT statement to authorize users and roles to create database objects and execute stored procedures, functions, and so on. </p>
    </td>
  </tr><table border="1" >
<tr><th>Vendor</th>
<th>Command</th></tr>
<tr><td>SQL Server</td><td>Supported, with variations</td></tr><tr><td>MySQL</td><td>Supported, with variations</td></tr><tr><td>Oracle</td><td>Supported, with variations</td></tr><tr><td>PostgreSQL</td><td>Supported, with variations</td></tr></table>

</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">SQL99 Syntax and Description</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>GRANT { ALL [PRIVILEGES] }
| SELECT
| INSERT [ (column_name [,...n]) ]
| DELETE
| UPDATE [ (column_name [,...n]) ]
| REFERENCES [ (column_name [,...n]) ]
| USAGE }[,...n]
ON { [TABLE] table_name
| DOMAIN domain_name
| COLLATION collation_name
| CHARACTER SET character_set_name
| TRANSLATION translation_name }
TO {grantee_name |  PUBLIC}
[WITH GRANT OPTION]</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The GRANT statement allows users to be authorized for one or more access privileges  SELECT , INSERT , UPDATE , DELETE , REFERENCES , or USAGE  by an authority who can grant those privileges. Each privilege allows the user to execute the specified command, while REFERENCES and USAGE provide other privileges. Multiple access privileges are specified by placing a comma between each privilege, or access to all privileges is granted with ALL . The PRIVILEGES keyword is entirely optional. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The USAGE privilege applies to any database object besides a table, while the others apply only to tables. The USAGE privilege lets users create objects based upon the definition of another, such as using a translation to construct a collation. The REFERENCES privilege enables a table in a constraint or foreign key to be used. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The INSERT , UPDATE , and REFERENCES privileges may be assigned against specific columns within a table. If no columns are specified, then all columns are assumed. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The ON clause declares the specific table or database object where the user is receiving privileges. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The TO clause tells exactly which user or role receives a given authorization. Alternately, privileges may be granted to PUBLIC , meaning that all users (including those that will be created in the future) have the specified privilege. Authorization may be granted to other users using WITH GRANT OPTION . In turn, this clause tells the database that users who receive an access privilege can then grant that same access privilege to other users. </p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p><span class="emphasis">Tip</span>:   Depending on the specific database implementation, views
  may or may not have independent access privileges from their base tables. <br>
</p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">Microsoft SQL Server Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">

<pre>GRANT { ALL [PRIVILEGES] }
| SELECT
| INSERT
| DELETE
| UPDATE
| REFERENCES
| EXECUTE
| CREATE {DATABASE | DEFAULT | FUNCTION | PROCEDURE | RULE | TABLE | VIEW}
| BACKUP {DATABASE | LOG} } [,...n]
ON { {table_name | view_name} [(column [,...n])]
| stored_procedure_name
| extended_stored_procedure_name
| user_defined_function_name
| [(column [,...n] ON {table_name | view_name} }
TO {grantee_name | PUBLIC} [,...n]
[WITH GRANT OPTION]
[AS {group | role}]</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Microsoft SQL Server allows the SELECT , INSERT , UPDATE , DELETE , and REFERENCES access permissions to be granted on a table. A column list may be identified only for SELECT and UPDATE access permissions. By default, all columns are granted SELECT and UPDATE access privileges. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Only the EXECUTE permission may be granted on stored procedures, extended stored procedures, and user-defined functions; a user must have the REFERENCES privilege to create a FOREIGN KEY constraint. This permission also is required when creating a function or view that depends upon an object with SCHEMABINDING . </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The AS clause grants privileges as if under a different group or role context. Since groups and roles cannot execute the GRANT command, this is an easy way to grant privileges to someone outside of the group or role. Privileges may not be granted in a database other than the current database context. </p>
    </td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="example"><span class="title">
  Example</span>
</td>
</tr>
  <tr>
    <td><p>First, CREATE DATABASE and CREATE TABLE are used to grant permissions to the users Emily and Sarah. Next, numerous permissions are granted on the <span class="emphasis">titles</span> table to the editors group. The editors are then able to grant these permission to others: </p>
    </td>
  </tr><tr>
<td>
<span class="programlisting">
<pre>GRANT CREATE DATABASE, CREATE TABLE TO emily, sarah
GO

GRANT SELECT, INSERT, UPDATE, DELETE ON titles
TO editors
WITH GRANT OPTION
GO</pre>
</span>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">MySQL Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>GRANT { ALL PRIVILEGES
| SELECT
| INSERT [ (column_name [,...n]) ]
| DELETE
| UPDATE [ (column_name [,...n]) ]
| REFERENCES [ (column_name [,...n]) ]
| USAGE
| ALTER
| CREATE
| DROP
| FILE
| INDEX
| PROCESS
| RELOAD
| SHUTDOWN }[,...n]
ON {table_name | * | *.* | database_name.*}
TO grantee_name [IDENTIFIED BY 'password'] [,...n]
[WITH GRANT OPTION]</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>MySQL provides additional access privileges, primarily relating to object manipulation within a database. As with the other privileges, granting any of the access privileges (such as ALTER , CREATE , INDEX , or RELOAD ) allows the user to execute the command. REFERENCES is supported, but has no functionality. USAGE actually disables a grantee's privileges. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The following are access privileges that are usable with tables: SELECT , INSERT , UPDATE , DELETE , CREATE , DROP , GRANT , INDEX , and ALTER . INSERT , UPDATE , and SELECT may be applied at the column level. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>MySQL's implementation of the ON clause allows some interesting options. Global privileges can be set, applying to all databases on the server, by specifying ON *.* . Database-wide privileges may be set by specifying ON database_name.* or ON * within the current database. The host, table, database, and column name must be 60 or fewer characters. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>MySQL supports the possibility of granting rights to a specific user on a specific host if the grantee_name is in the form USER@HOST . Wildcards can be included in a grantee_name to provide the access privilege to a large number of users at one time. The grantee_name must be 16 or fewer characters. When specifying the user, password protection may be enforced by including the IDENTIFIED BY clause. </p>
    </td>
  </tr>

<tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="example"><span class="title">
  Example</span>
</td>
</tr>  <tr>
    <td><p>This example grants permissions to two users with passwords: </p>
    </td>
  </tr>
  <tr>
<td>
<span class="programlisting">
<pre>GRANT SELECT ON employee TO Dylan IDENTIFIED BY 'porsche',
  kelly IDENTIFIED BY 'mercedes',
  emily IDENTIFIED BY 'saab';</pre>
</span>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">Oracle Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>GRANT { ALL [PRIVILEGES] }
{| GRANT ANY PRIVILEGE }
{| SELECT | INSERT  | DELETE | UPDATE | REFERENCES }
{| CREATE [ANY] {CLUSTER | CONTEXT | DATABASE| DATABASE LINK | DIMENSION
   | DIRECTORY | INDEXTYPE | INDEX | LIBRARY | OPERATOR | OUTLINE
   | PROCEDURE | PROFILE | ROLE | ROLLBACK SEGMENT | SEQUENCE | SESSION
   | SNAPSHOT | SYNONYM | TABLE | TABLESPACE | TRIGGER | TYPE |
   | USER | [MATERIALIZED] VIEW}
| DROP [ANY] {...as CREATE...}
| ALTER [ANYh] {...as CREATE...}
| AUDIT SYSTEM
| EXECUTE [ANY] {INDEXTYPE | OPERATOR | PROCEDURE | TYPE
| BACKUP [ANY] {TABLE | DATABASE | LOG} } [,...n] }
ON { [schema_name.]
{table_name | view_name} [ (column [,...n]) ]
| stored_procedure_name
| extended_stored_procedure_name
| user_defined_function_name
| DIRECTORY directory_name
| JAVA {SOURCE | RESOURCE} [schema_name.]object_name }
TO {{grantee_name | role_name} [,...n] | PUBLIC}
[WITH ADMIN OPTION];</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>It is plainly clear that Oracle has an exhaustive GRANT command. In fact, the syntax shown does not cover every permutation of the statement. Note that there are two general classes of privileges available under GRANT: object privileges (such as the privilege to SELECT or DELETE from a specific table) and system privileges (such as CREATE CLUSTER or DROP ANY TABLE ). </p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p> <span class="emphasis">Warning: </span> Oracle does not allow the combination of object and system
  privileges in a single GRANT command. Multiple object privileges or system privileges may be granted to a
single user or role in a GRANT
command, but a GRANT
command may not grant both object and system privileges.</p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Nearly every supported Oracle feature is permitted under a GRANT command. Privileges can be granted not only on database objects (such as tables and views) and system commands (such as CREATE ANY TABLE ), but also on schema objects (such as DIRECTORY , JAVA SOURCE, and RESOURCE ). </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The ANY option grants the privilege to execute a given statement against objects of a specific type owned by any user within the schema. A more complete list of Oracle system privileges is shown in Table 3.2 . </p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
 <tr>
<td>
<table border="1">
<tr>
<th>
Category of Privilege</th>
<th>
System Privilege</th>
<th>
Description</th>
</tr>
<tr>
<td>
CLUSTER</td>
<td>
CREATE CLUSTER</td>
<td>
Grants privilege to create a cluster in the grantee's own
schema.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
CREATE ANY CLUSTER</td>
<td>
Grants privilege to create a cluster in any schema.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
ALTER ANY CLUSTER</td>
<td>
Grants privilege to alter clusters in any schema.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
DROP ANY CLUSTER</td>
<td>
Grants privilege to drop clusters in any schema.</td>
</tr>

<tr>
<td>
CONTEXT</td>
<td>
CREATE ANY CONTEXT</td>
<td>
Grants privilege to create any context namespace.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
DROP ANY CONTEXT</td>
<td>
Grants privilege to drop any context namespace.</td>
</tr>

<tr>
<td>
DATABASE</td>
<td>
ALTER DATABASE</td>
<td>
Grants privilege to alter the database.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
ALTER SYSTEM</td>
<td>
Issues ALTER SYSTEM statements.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
AUDIT SYSTEM</td>
<td>
Issues AUDIT <span class="emphasis">sql_statements
</span>statements.</td>
</tr>

<tr>
<td>
DATABASE LINKS</td>
<td>
CREATE DATABASE LINK</td>
<td>
Grants privilege to create private database links in grantee's
own schema.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
CREATE PUBLIC


DATABASE LINK</td>
<td>
Grants privilege to create public


database links.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
DROP PUBLIC


DATABASE LINK</td>
<td>
Grants privilege to drop public


database links.</td>
</tr>

<tr>
<td>
DIMENSIONS</td>
<td>
CREATE DIMENSION</td>
<td>
Grants privilege to create dimensions in the grantee's own
schema.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
CREATE ANY


DIMENSION</td>
<td>
Grants privilege to create dimensions in any schema.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
ALTER ANY


DIMENSION</td>
<td>
Grants privilege to alter dimensions in any schema.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
DROP ANY


DIMENSION</td>
<td>
Grants privilege to drop dimensions in any schema.</td>
</tr>

<tr>
<td>
DIRECTORIES</td>
<td>
CREATE ANY


DIRECTORY</td>
<td>
Grants privilege to create directory database objects.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
DROP ANY


DIRECTORY</td>
<td>
Grants privilege to drop directory

database objects.</td>
</tr>

<tr>
<td>
INDEXTYPES</td>
<td>
CREATE INDEXTYPE</td>
<td>
Grants privilege to create an indextype in the grantee's own
schema.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
CREATE ANY


INDEXTYPE</td>
<td>
Grants privilege to create an indextype in any schema.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
ALTER ANY


INDEXTYPE</td>
<td>
Modifies indextypes in any schema.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
DROP ANY


INDEXTYPE</td>
<td>
Grants privilege to drop an indextype in any schema.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
EXECUTE ANY


INDEXTYPE</td>
<td>
References an indextype in any schema.</td>
</tr>

<tr>
<td>
INDEXES</td>
<td>
CREATE ANY INDEX</td>
<td>
Grants privilege to create a domain index in any schema or an index
on any table in any schema.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
ALTER ANY INDEX</td>
<td>
Grants privilege to alter indexes in any schema.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
DROP ANY INDEX</td>
<td>
Grants privilege to drop indexes in any schema.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
QUERY REWRITE</td>
<td>
Enables rewrite using a materialized view, or creates a
function-based index, when materialized view or index references
tables and views are in the grantee's own schema.</td>
</tr>

<tr>

<td>&nbsp;</td>
<td>
GLOBAL QUERY REWRITE</td>
<td>
Enables rewrite using a materialized view, or creates a
function-based index, when materialized view or index references
tables views are in any schema.</td>
</tr>

<tr>
<td>
LIBRARIES</td>
<td>
CREATE LIBRARY</td>
<td>
Grants privilege to create external procedure/function libraries in
grantee's own schema.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
CREATE ANY LIBRARY</td>
<td>
Grants privilege to create external procedure/function libraries in
any schema.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
DROP LIBRARY</td>
<td>
Grants privilege to drop external procedure/function libraries in the
grantee's own schema.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
DROP ANY LIBRARY</td>
<td>
Grants privilege to drop external procedure/function libraries in any
schema.</td>
</tr>

<tr>
<td>
MATERIALIZED VIEWS (identical to SNAPSHOTS)</td>
<td>
CREATE MATERIALIZED VIEW</td>
<td>
Grants privilege to create a materialized view in the grantee's
own schema.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
CREATE ANY MATERIALIZED VIEW</td>
<td>
Grants privilege to create materialized views in any schema.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
ALTER ANY MATERIALIZED VIEW</td>
<td>
Grants privilege to alter materialized views in any schema.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
DROP ANY MATERIALIZED VIEW</td>
<td>
Grants privilege to drop materialized views in any schema.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
GLOBAL QUERY REWRITE</td>
<td>
Enables rewrite using a materialized view, or creates a
function-based index, when materialized view or index references
tables or views are in any schema.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
QUERY REWRITE</td>
<td>
Enables rewrite using a materialized view, or creates a
function-based index, when that materialized view or index references
tables and views that are in the grantee's own schema.</td>
</tr>

<tr>
<td>
OPERATORS</td>
<td>
CREATE OPERATOR</td>
<td>
Grants privilege to create an operator and its bindings in the
grantee's own schema.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
CREATE ANY


OPERATOR</td>
<td>
Grants privilege to create an operator and its bindings in any schema.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
DROP ANY OPERATOR</td>
<td>
Grants privilege to drop an operator in any schema.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
EXECUTE ANY


OPERATOR</td>
<td>
References an operator in any schema.</td>
</tr>

<tr>
<td>
OUTLINES</td>
<td>
CREATE ANY OUTLINE</td>
<td>
Grants privilege to create outlines that can be used in any schema
that uses outlines.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
ALTER ANY OUTLINE</td>
<td>
Modifies outlines.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
DROP ANY OUTLINE</td>
<td>
Grants privilege to drop outlines.</td>
</tr>

<tr>
<td>
PROCEDURES</td>
<td>
CREATE PROCEDURE</td>
<td>
Grants privilege to create stored procedures, functions, and packages
in grantee's own schema.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
CREATE ANY


PROCEDURE</td>
<td>
Grants privilege to create stored procedures, functions, and packages
in any schema.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
ALTER ANY


PROCEDURE</td>
<td>
Grants privilege to alter stored procedures, functions, or packages
in any schema.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
DROP ANY


PROCEDURE</td>
<td>
Grants privilege to drop stored procedures, functions, or packages in
any schema.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
EXECUTE ANY


PROCEDURE</td>
<td>
Executes procedures or functions (standalone or packaged).</td>
</tr>

<tr>
<td>
PROFILES</td>
<td>
CREATE PROFILE</td>
<td>
Grants privilege to create profiles.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
ALTER PROFILE</td>
<td>
Grants privilege to alter profiles.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
DROP PROFILE</td>
<td>
Grants privilege to drop profiles.</td>
</tr>

<tr>
<td>
ROLES</td>
<td>
CREATE ROLE</td>
<td>
Grants privilege to create roles.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
ALTER ANY ROLE</td>
<td>
Grants privilege to alter any role in the database.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
DROP ANY ROLE</td>
<td>
Grants privilege to drop roles.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
GRANT ANY ROLE</td>
<td>
Grants any role in the database.</td>
</tr>

<tr>
<td>
ROLLBACK SEGMENTS</td>
<td>
CREATE ROLLBACK SEGMENT</td>
<td>
Grants privilege to create rollback segments.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
ALTER ROLLBACK SEGMENT</td>
<td>
Grants privilege to alter rollback segments.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
DROP ROLLBACK SEGMENT</td>
<td>
Grants privilege to drop rollback segments.</td>
</tr>

<tr>
<td>
SEQUENCES</td>
<td>
CREATE SEQUENCE</td>
<td>
Grants privilege to create sequences in grantee's own schema.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
CREATE ANY SEQUENCE</td>
<td>
Grants privilege to create sequences in any schema.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
ALTER ANY SEQUENCE</td>
<td>
Grants privilege to alter any sequence in the database.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
DROP ANY SEQUENCE</td>
<td>
Grants privilege to drop sequences in any schema.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
SELECT ANY SEQUENCE</td>
<td>
References sequences in any schema.</td>
</tr>

<tr>
<td>
SESSIONS</td>
<td>
CREATE SESSION</td>
<td>
Connects to the database.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
ALTER RESOURCE COST</td>
<td>
Sets costs for session resources.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
ALTER SESSION</td>
<td>
Issues ALTER SESSION statements.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
RESTRICTED SESSION</td>
<td>
Logs on after the instance is started using the SQL*Plus
STARTUP RESTRICT statement.</td>
</tr>

<tr>
<td>
SNAPSHOTS (identical to MATERIALIZED VIEWS)</td>
<td>
CREATE SNAPSHOT</td>
<td>
Grants privilege to create snapshots in grantee's own schema.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
CREATE ANY


SNAPSHOT</td>
<td>
Grants privilege to create snapshots in any schema.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
ALTER ANY SNAPSHOT</td>
<td>
Grants privilege to alter any snapshot in the database.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
DROP ANY SNAPSHOT</td>
<td>
Grants privilege to drop snapshots in any schema.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
GLOBAL QUERY REWRITE</td>
<td>
Enables rewrite using a snapshot, or creates a function-based index,
when that snapshot or index references tables and views in any
schema.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
QUERY REWRITE</td>
<td>
Enables rewrite using a snapshot, or creates a function-based index,
when that snapshot or index references tables and views are in the
grantee's own schema.</td>
</tr>

<tr>
<td>
SYNONYMS</td>
<td>
CREATE SYNONYM</td>
<td>
Grants privilege to create synonyms in grantee's own schema.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
CREATE ANY SYNONYM</td>
<td>
Grants privilege to create private synonyms in any schema.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
CREATE PUBLIC SYNONYM</td>
<td>
Grants privilege to create public synonyms.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
DROP ANY SYNONYM</td>
<td>
Grants privilege to drop private synonyms in any schema.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
DROP PUBLIC SYNONYM</td>
<td>
Grants privilege to drop public synonyms.</td>
</tr>

<tr>
<td>
TABLES</td>
<td>
CREATE ANY TABLE</td>
<td>
Grants privilege to create tables in any schema. The owner of the
schema containing the table must have a space quota on the tablespace
to contain the table.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
ALTER ANY TABLE</td>
<td>
Grants privilege to alter any table or view in the schema.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
BACKUP ANY TABLE</td>
<td>
Uses the Export utility to incrementally export objects from the
schema of other users.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
DELETE ANY TABLE</td>
<td>
Deletes rows from tables, table partitions, or views in any schema.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
DROP ANY TABLE</td>
<td>
Grants privilege to drop or truncate tables or table partitions in
any schema.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
INSERT ANY TABLE</td>
<td>
Inserts rows into tables and views in any schema.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
LOCK ANY TABLE</td>
<td>
Locks tables and views in any schema.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
UPDATE ANY TABLE</td>
<td>
Updates rows in tables and views in any schema.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
SELECT ANY TABLE</td>
<td>
Queries tables, views, or snapshots in any schema.</td>
</tr>

<tr>
<td>
TABLESPACES</td>
<td>
CREATE TABLESPACE</td>
<td>
Grants privilege to create tablespaces.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
ALTER TABLESPACE</td>
<td>
Grants privilege to alter tablespaces.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
DROP TABLESPACE</td>
<td>
Grants privilege to drop tablespaces.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
MANAGE TABLESPACE</td>
<td>
Takes tablespaces offline and online, and begins and ends tablespace
backups.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
UNLIMITED TABLESPACE</td>
<td>
Uses an unlimited amount of any tablespace. This privilege overrides
any specific quotas assigned. If you revoke this privilege from a
user, the user's schema objects remain, but further tablespace
allocation is denied unless authorized by specific tablespace quotas.
You cannot grant this system privilege to roles.</td>
</tr>

<tr>
<td>
TRIGGERS</td>
<td>
CREATE TRIGGER</td>
<td>
Grants privilege to create a database trigger in grantee's own
schema.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
CREATE ANY TRIGGER</td>
<td>
Grants privilege to create database triggers in any schema.</td>
</tr>
<tr>
<td>&nbsp;</td>
<td>
ALTER ANY TRIGGER</td>
<td>
Enables, disables, or compiles database triggers in any schema.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
DROP ANY TRIGGER</td>
<td>
Grants privilege to drop database triggers in any schema.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
ADMINISTER DATABASE TRIGGER</td>
<td>
Grants privilege to create a trigger on
<span class="emphasis">DATABASE</span>. (You also must have the
<span class="emphasis">CREATE TRIGGER</span> or
<span class="emphasis">CREATE ANY TRIGGER</span> privilege.)</td>
</tr>

<tr>
<td>
TYPES</td>
<td>
CREATE TYPE</td>
<td>
Grants privilege to create object types and object-type bodies in
grantee's own schema.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
CREATE ANY TYPE</td>
<td>
Grants privilege to create object types and object-type bodies in any
schema.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
ALTER ANY TYPE</td>
<td>
Grants privilege to alter object types in any schema.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
DROP ANY TYPE</td>
<td>
Grants privilege to drop object types and object-type bodies in any
schema.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
EXECUTE ANY TYPE</td>
<td>
Uses and references object types and collection types in any schema,
and invokes methods of an object type in any schema <span class="emphasis">if you
make the grant to a specific user</span>. If you grant
<span class="emphasis">EXECUTE ANY TYPE</span> to a role, users holding the
enabled role will not be able to invoke methods of an object type in
any schema.</td>
</tr>

<tr>
<td>
USERS</td>
<td>
CREATE USER</td>
<td>
Grants privilege to create users. This privilege also allows the
creator to:


<br>Assign quotas on <span class="emphasis">any tablespace</span>
<br>Set default and temporary tablespaces
<br>Assign a profile as part of a <span class="emphasis">CREATE USER
</span>statement</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
ALTER USER</td>
<td>
Grants the privilege to alter any user. This privilege authorizes the
grantee to:


<br>Change another user's password or authentication method
<br>Assign quotas on <span class="emphasis">any tablespace</span>
<br>Set default and temporary tablespaces, and
<br>Assign a profile and default roles</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
BECOME USER</td>
<td>
Becomes another user (required by any user performing a full database
import).</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
DROP USER</td>
<td>
Grants privilege to drop users.</td>

</tr>

<tr>
<td>
VIEWS</td>
<td>
CREATE VIEW</td>
<td>
Grants privilege to create views in grantee's own schema.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
CREATE ANY VIEW</td>
<td>
Grants privilege to create views in any schema.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
DROP ANY VIEW</td>
<td>
Grants privilege to drop views in any schema.</td>
</tr>

<tr>
<td>
MISCELLANEOUS</td>
<td>
ANALYZE ANY</td>
<td>
Analyzes any table, cluster, or index in any schema.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
AUDIT ANY</td>
<td>
Audits any object in any schema using <span class="emphasis">AUDIT</span>
<span class="emphasis">schema_objects </span>statements.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
COMMENT ANY TABLE</td>
<td>
Comments on any table, view, or column in any schema.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
FORCE ANY


TRANSACTION</td>
<td>
Forces the commit or rollback of any in-doubt distributed transaction
in the local database; induces the failure of a distributed
transaction.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
FORCE TRANSACTION</td>
<td>
Forces the commit or rollback of grantee's own in-doubt
distributed transactions in the local database.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
GRANT ANY


PRIVILEGE</td>
<td>
Grants any system privilege.</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
SYSDBA</td>
<td>
Authorizes the user to:


<br>Performs <span class="emphasis">STARTUP</span> and
<span class="emphasis">SHUTDOWN</span> operations
<br><span class="emphasis">ALTER DATABASE</span>: open, mount,
back up, or change character set
<br>CREATE DATABASE
<br><span class="emphasis">ARCHIVELOG</span> and <span class="emphasis">RECOVERY</span>
<br>Includes the <span class="emphasis">RESTRICTED SESSION</span> privilege</td>
</tr>

<tr>
<td>&nbsp;</td>
<td>
SYSOPER</td>
<td>
Authorizes the user to:


<br>Performs <span class="emphasis">STARTUP</span> and
<span class="emphasis">SHUTDOWN</span> operations
<br><span class="emphasis">ALTER DATABASE OPEN/MOUNT/BACKUP &#8212; ARCHIVELOG
</span>and <span class="emphasis">RECOVERY</span>
<br>Includes the <span class="emphasis">RESTRICTED SESSION</span> privilege</td>
</tr>

</table>
</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">
PostgreSQL Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>GRANT { ALL
| SELECT
| INSERT
| DELETE
| UPDATE
| RULE } [,...n]
ON { object_name }
TO {grantee_name | PUBLIC | GROUP group_name}</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>PostgreSQL does not support the WITH GRANT OPTION clause or column-level permissions. PostgreSQL's implementation of GRANT behaves as if WITH GRANT OPTION is always enabled. Any user granted a permission is able to grant that privilege to other users. PostgreSQL allows permissions to be assigned to a GROUP , provided it is a valid, preexisting group_name . </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>PostgreSQL does not support GRANT on system commands, but several other database vendors do. </p>
    </td>
  </tr>
<tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="example"><span class="title">
  Example</span>
</td>
</tr>
    <td><p>PostgreSQL support for the GRANT statement is elementary: </p>
    </td>
  </tr>
  <tr>
        <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td>
    <span class="programlisting">
	<pre>GRANT INSERT ON publishers TO PUBLIC;

    GRANT SELECT, UPDATE ON sales TO emily;</pre>
</span>
    </td>
  </tr>
</table>
</div>


<div id="INSERT"><table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td Width="50%" align="left" class="name" valign="top">INSERT<td Width="50%" align="right"class="name" valign="top">SQL-schema&nbsp;&nbsp;</td></tr></table>
<table width="100%" cellspacing="0" cellpadding="0" border="0">
    <tr>
    <td><p>The INSERT statement adds rows of data to a table or view. The INSERT statement allows records to be entered into a table through one of several methods: </p>
    </td>
  </tr>
  <tr>
  <td>
<ol>
  <li>The first method is to insert records using the DEFAULT
    values created on the columns given table via the <br>
CREATE TABLE
    or ALTER TABLE
  statements. (This method is not supported by Oracle.) </li>
  <li> The second and most common method is to declare the actual
  values to be inserted into each column of the record.</li>
  <li> The third method, which quickly populates a table with many records, is
    to insert the result set of a SELECT statement into a table.
     </li>
</ol>
</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<table border="1" >
<tr><th>Vendor</th>
<th>Command</th></tr>
<tr><td>SQL Server</td><td>Supported, with variations</td></tr><tr><td>MySQL</td><td>Supported, with variations</td></tr><tr><td>Oracle</td><td>Supported, with variations</td></tr><tr><td>PostgreSQL</td><td>Supported</td></tr></table>
</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">SQL99 Syntax and Description</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>INSERT [INTO] [[database_name.]owner.] {table_name | view_name} [(column_
    list)]
{[DEFAULT] VALUES | VALUES (value[,...]) | SELECT_statement }</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>To use the INSERT statement, first declare the table (or view) where the data is to be inserted. The INTO keyword is optional. Specify the columns in the table that receives data by enclosing them in parentheses separated by commas in the column_list . The column_list can be left off, but all columns that are defined for the table are then assumed. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The DEFAULT VALUES method is mutually exclusive from the list_of_values and SELECT_statement methods. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The INSERT . . . VALUES statement adds a single row of data to a table using literal values supplied in the statement. The INSERT statement, combined with a nested SELECT statement, allows a table to be quickly populated with multiple rows. When using INSERT . . . SELECT between two tables, it is important to ensure that the tables possess compatible datatypes and structures, although any incompatibilities between the two tables can be compensated for in the SELECT statement. INSERT . . . SELECT also is supported by PostgreSQL. </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">Microsoft SQL Server Syntax and Description</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>INSERT [INTO] [[database_name.]owner.]
    {table_name | view_name} [(column_list)]
{[DEFAULT] VALUES | list_of_values | SELECT_statement |
 EXEC[UTE] { procedure_name }
    [[@parameter_name=] {value [OUTPUT] | DEFAULT}[,...]}</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Microsoft SQL Server's implementation of the INSERT command differs in that it allows the DEFAULT keyword. DEFAULT tells the INSERT statement simply to create a new record using all of the default values declared for a given table. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The major difference in this vendor's implementation is the EXECUTE keyword. The EXECUTE clause tells SQL Server to store the result set returned by a dynamic Transact-SQL statement, a system-stored procedure, a user-stored procedure, a Remote Procedure Call (RPC), or extended stored procedure into a local table. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>For example, the following INSERT retrieves the C:\temp directory and stores it in the temporary table called <span class="emphasis">#ins_exec_container</span> : </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td>
    <span class="programlisting">
    <pre>INSERT INTO #ins_exec_container
EXEC master..xp_cmdshell "dir c:\temp"
GO</pre>
</span>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">MySQL Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>INSERT [LOW_PRIORITY | DELAYED] [IGNORE]
[INTO] [[database_name.]owner.] {table_name | view_name} [(column_list)]
{VALUES (value[,...]) | SELECT_statement | SET column=value[,...n]}</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The option LOW_PRIORITY tells MySQL to defer the execution of INSERT until no other clients are reading from the table. This could result in a long wait. The DELAYED option allows the client to continue at once, even if the INSERT has not yet completed. The IGNORE keyword tells MySQL not to attempt to insert records that would duplicate a value in a primary key or unique key; otherwise, without this clause, the INSERT fails. The SET column=value syntax allows the columns of the table to be declared and the values to insert in them. </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">
Oracle Syntax and Description</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>INSERT [INTO] [[database_name.]owner.] {table_name | view_name}
   [PARTITION partition_name | SUBPARTITION subpartition_name]
[(column_list)]
{VALUES (value1[,...n]) RETURNING expression1 [,...n] INTO variable1
   [,...n]
 |
SELECT_statement
[WITH {READ ONLY | CHECK OPTION [CONSTRAINT constraint_name]} }</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Oracle's implementation of the INSERT statement allows data insertion not only into a given table, view, or snapshot, but also into a given partition or subpartition within a table using the PARTITION and SUBPARTITION keywords. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>When the INSERT statement is correlated with a SELECT clause, some new rules come into play. If the SELECT clause is coupled with a VALUES clause, only one row is inserted into the table  the first row returned by the SELECT clause. If SELECT is used without VALUES , then all rows returned by the query are inserted into the table. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The RETURNING clause is not used to insert the values into a table, but into variables instead. There must be a one-for-one match between the expressions and variables of the RETURNING clause. The expressions returned by the clause do not necessarily have to be those mentioned in the VALUES clause. For example, the following INSERT statement places a record into the sales table, but places a completely distinct value into a bind variable: </p>
    </td>
  </tr><tr>
<td>
<span class="programlisting">
<pre>INSERT authors (au_id, au_lname, au_fname, contract )
VALUES ('111-11-1111', 'Rabbit', 'Jessica', 1)
RETURNING hire_date INTO :temp_hr_dt;</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Notice that the RETURNING clause returns the <span class="emphasis">hire_date</span> even though <span class="emphasis">hire_date</span> is not one of the values listed in the VALUES clause. (In this example, it is reasonable to assume a default value was established for the <span class="emphasis">hire_date</span> column.) LONG datatypes may not be manipulated by RETURNING . RETURNING cannot be used on views with INSTEAD OF triggers. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Additionally, the SELECT clause may utilize the WITH option. WITH READ ONLY specifies that the result set retrieved by the SELECT clause cannot be altered by the INSERT statement. The WITH CHECK OPTION clause tells Oracle to prohibit any data change that would produce rows that are not included in the result set of the SELECT clause. </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">PostgreSQL Syntax and Description</span></td>
  </tr>
<tr>
  <tr>
    <td><p>PostgreSQL supports the SQL99 standard for the INSERT statement. Refer to the earlier section for the SQL99 syntax and usage. </p>
    </td>
  </tr>
<tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="example"><span class="title">
  Example</span>
</td>
</tr>  <tr>
    <td><p>In this example, a new row in the <span class="emphasis">authors</span> table is inserted for the author Jessica Rabbit on a Microsoft SQL Server database: </p>
    </td>
  </tr><tr>
<td>
<span class="programlisting">
<pre>INSERT INTO authors (au_id, au_lname, au_fname, phone, address, city,
     state, zip, contract )
VALUES ('111-11-1111', 'Rabbit', 'Jessica', DEFAULT, '1717 Main St', NULL,
    'CA', '90675', 1)</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Every column is assigned a specific, literal value except the <span class="emphasis">phone</span> column, which is assigned the default value (as assigned during the CREATE TABLE or ALTER TABLE statement), and the <span class="emphasis">city</span> column, which is null. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Here is a partial INSERT on a Microsoft SQL Server database of the same data: </p>
    </td>
  </tr><tr>
<td>
<span class="programlisting">
<pre>INSERT authors (au_id, au_lname, au_fname,  phone, contract )
VALUES ('111-11-1111', 'Rabbit', 'Jessica', DEFAULT, 1)</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>To load data from <span class="emphasis">sales</span> table into the <span class="emphasis">new_sales</span> table, INSERT . . . SELECT can be used: </p>
    </td>
  </tr>
  <tr>
    <td>
<span class="programlisting">
<pre>INSERT sales
    (stor_id,
    ord_num,
    ord_date,
    qty,
    payterms,
    title_id)
SELECT
    CAST(store_nbr AS CHAR(4)),
    CAST(order_nbr AS VARCHAR(20)),
    order_date,
    quantity,
    SUBSTRING(payment_terms,1,12),
    CAST(title_nbr AS CHAR(1))
FROM new_sales
WHERE order_date &gt;= '01/01/2000'         -- retrieve only the newer records</pre>
</span
    ></td>
  </tr>
</table>
</div>

<div id="LIKE Operator"><table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td Width="50%" align="left" class="name" valign="top">LIKE Operator<td Width="50%" align="right"class="name" valign="top">SQL-schema&nbsp;&nbsp;</td></tr></table>
<table width="100%" cellspacing="0" cellpadding="0" border="0">
    <tr>
    <td><p>The LIKE operator enables specified string patterns in SELECT , INSERT , UPDATE , and DELETE statements to be matched. The specified pattern can even include special wildcard characters. </p>
    </td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
  <tr>
  <td>
  <table border="1" >
<tr><th>Vendor</th>
<th>Command</th></tr>
<tr><td>SQL Server</td><td>Supported, with variations</td></tr><tr><td>MySQL</td><td>Supported, with variations</td></tr><tr><td>Oracle</td><td>Supported, with variations</td></tr><tr><td>PostgreSQL</td><td>Supported, with variations</td></tr></table>
</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">SQL99 Syntax and Description</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
WHERE expression [NOT] LIKE string_pattern</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The usefulness of LIKE is based on the wildcard operators that it supports. LIKE returns a TRUE Boolean value when the comparison finds one or more matching values. Note that the default case sensitivity of the DBMS is very important to the behavior of LIKE . For example, Microsoft SQL Server is not case-sensitive by default (though it can be configured that way). So the query: </p>
    </td>
  </tr><tr>
<td>
<span class="programlisting">
<pre>SELECT *
FROM authors
WHERE lname LIKE 'LARS%'</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>would find authors whose last names are stored as `larson' or `lars,' even though the search was for uppercase `LARS%'. Oracle is case-sensitive to " % " and " _ " pattern characters, and has other regular-expression pattern matching available using operators other than LIKE . The wildcard operators are as follows in Table 3.3 . </p>
    </td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
  <tr>
  <td>
<table width="75%" border="1">
  <tr>
    <th>Wildcard Operator</th>
    <th>Example</th>
    <th>Description</th>
  </tr>
  <tr>
    <td>%</td>
    <td><p>Retrieves any record of city with &quot;ville&quot; in its name. (Supported
        by all vendors.)<br>
</p>
    <p>SELECT * FROM authors WHERE city LIKE '%ville%'<br>
    </p></td>
    <td> Matches any string; resembles * in DOS operations.<br></td>
  </tr>
  <tr>
    <td>[ ]</td>
    <td><p>Retrieves any author with a last name like Carson, Carsen, Karson, or
        Karsen. (Not supported by Oracle. Supported by Microsoft SQL Server.)<br>
  </p>
    <p>SELECT * FROM authors WHERE au_lname LIKE '[CK]ars[eo]n'</p></td>
    <td> Matches any value in the specified set, as in [abc], or
    any range, as in [k-n].<br></td>
  </tr>
  <tr>
    <td>[^ ]</td>
    <td> <p>Retrieves any author with a last name that ends in arson or arsen,
      <span class="emphasis">but not</span>
  Larsen or Larson. (Supported by Microsoft SQL Server.) </p>
    <p>SELECT * FROM authors WHERE au_lname LIKE '[A-Z^L]ars[eo]n'</p></td>
    <td>Matches any characters not in the specified set or range.</td>
  </tr>
  <tr>
    <td> _ (underscore)<br></td>
    <td> Retrieves any author with a first name <span class="emphasis">not</span>
like Sheryl or Cheryl. (Supported by all vendors.) <br><br>
SELECT * FROM authors WHERE au_fname NOT LIKE '_heryl'<br></td>
    <td>Matches any single character.</td>
  </tr>
</table>
</td>
</tr>
 <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p> <span class="emphasis">Tip:</span> When performing string comparisons with LIKE
, all characters in the pattern string are significant, including all leading
or trailing
blank spaces. </p>
    </td>
  </tr>

</table>
</div>

<div id="OPEN"><table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td Width="50%" align="left" class="name" valign="top">OPEN<td Width="50%" align="right"class="name" valign="top">SQL-schema&nbsp;&nbsp;</td></tr></table>
<table width="100%" cellspacing="0" cellpadding="0" border="0">
   <tr>
    <td><p>The OPEN command opens a server cursor created with a DECLARE CURSOR statement. MySQL does not support ANSI-style server-side cursors. </p>
    </td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
  <table border="1" >
<tr><th>Vendor</th>
<th>Command</th></tr>
<tr><td>SQL Server</td><td>Supported</td></tr><tr><td>MySQL</td><td>Not supported</td></tr><tr><td>Oracle</td><td>Supported</td></tr><tr><td>PostgreSQL</td><td>Supported</td></tr></table>
</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">SQL99 Syntax and Description</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
OPEN { cursor_name }</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The cursor_name is the name of the cursor created with the DECLARE CURSOR command. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>In addition to standard server cursors, Microsoft SQL Server allows global cursors to be declared (in the format OPEN GLOBAL cursor_name ) that can be referenced by multiple users. Plus, Oracle allows parameters to be passed directly into the cursor when it is opened (in the format OPEN cursor_name parameter1 [,...n] ). </p>
    </td>
  </tr>
<tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="example"><span class="title">
  Example</span>
</td>
</tr>
  <tr>
    <td><p>The following example from Microsoft SQL Server opens a cursor and fetches all the rows. The same functionality in Oracle and PostgreSQL could be accomplished without the final DEALLOCATAE clause: </p>
    </td>
  </tr>
  <tr>
        <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><span class="programlisting">
<pre>DECLARE employee_cursor CURSOR FOR
  SELECT lname, fname
  FROM pubs.dbo.authors
  WHERE lname LIKE 'K%'

OPEN employee_cursor

FETCH NEXT FROM employee_cursor

WHILE @@FETCH_STATUS = 0
BEGIN
  FETCH NEXT FROM Employee_Cursor
END

CLOSE employee_cursor

DEALLOCATE employee_cursor
-- DEALLOCATE is specific to Microsoft SQL Server and non-ANSI
-- standard.</pre>
</span>
    </td>
  </tr>
</table>
</div>

<div id="OPERATORS"><table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td Width="50%" align="left" class="name" valign="top">OPERATORS<td Width="50%" align="right"class="name" valign="top">SQL-schema&nbsp;&nbsp;</td></tr></table>
<table width="100%" cellspacing="0" cellpadding="0" border="0">
  <tr>
    <td><p>An operator is a symbol specifying an action that is performed on one or more expressions. Operators are used most often in DELETE , INSERT , SELECT , or UPDATE statements but also are used frequently in the creation of database objects, such as stored procedures, functions, triggers, and views. </p>
    </td>
  </tr>
  tr>
          <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
  <td>
  <table border="1" >
<tr><th>Vendor</th>
<th>Command</th></tr>
<tr><td>SQL Server</td><td>Supported, with variations</td></tr><tr><td>MySQL</td><td>Supported, with variations</td></tr><tr><td>Oracle</td><td>Supported, with variations</td></tr><tr><td>PostgreSQL</td><td>Supported, with variations</td></tr></table>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Operators typically fall into these logical categories: </p>
    </td>
  </tr>
  <tr>
  <td>
<ul>
<li>Arithmetic operators: Supported by all databases.</li>
<li>Assignment operators: Supported by all databases.</li>
<li>Bitwise operators: Supported by Microsoft SQL Server</li>
<li>Comparison operators: Supported by all databases.</li>
<li>Logical operators: Supported by Oracle, Microsoft SQL Server, and PostgreSQL</li>
<li>Unary operators: Supported by Oracle</li>
</ul>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">Arithmetic Operators</span></td>
  </tr>
 <tr>
    <td><p>Arithmetic operators perform mathematical operations on two expressions of any datatypes in the numeric datatype category. See Table 3.4 for a listing of the arithmatic operators. </p>
    </td>
  </tr>
  <tr>
          <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
  <td>
<table width="75%" border="1">
  <tr>
    <th>Arithmetic Operator</th>
    <th>Meaning</th>
  </tr>
  <tr>
    <td>+</td>
    <td>Addition</td>
  </tr>
  <tr>
    <td>-</td>
    <td>Subtraction</td>
  </tr>
  <tr>
    <td>*</td>
    <td>Multiplication</td>
  </tr>
  <tr>
    <td>/</td>
    <td>Division</td>
  </tr>
  <tr>
    <td>%</td>
    <td> Modula (SQL Server only); returns the remainder of a division
    operation as an integer value.</td>
  </tr>
</table>
</td>
</tr>

    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p><span class="emphasis">Tip: </span> In Oracle and SQL Server, the + and - operators also can be used
  to perform arithmetic operations on date values.</p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">
Assignment Operators</span></td>
  </tr>

  <tr>
    <td><p>Except in Oracle, the assignment operator ( = ) assigns the value to a variable or the alias of a column heading. In Microsoft SQL Server, the keyword AS may be assigned as an operator for table- or column-heading aliases. </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">
Bitwise Operators
  </span></td>
  </tr>
  <tr>
    <td><p>Microsoft SQL Server provides bitwise operators as a shortcut to perform bit manipulations between two-integer expressions (see Table 3.5 ). Valid datatypes that are accessible to bitwise operators include binary , bit , int , smallint , tinyint , and varbinary . </p>
    </td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
    </tr>

  <tr>
  <tr>
  <td>
<table width="75%" border="1">
  <tr>
    <th>Bitwise Operators</th>
    <th>Meaning</th>
  </tr>
  <tr>
    <td>&amp;</td>
    <td>Bitwise AND (two operands)</td>
  </tr>
  <tr>
    <td>|</td>
    <td>Bitwise OR (two operands)</td>
  </tr>
  <tr>
    <td>^</td>
    <td> Bitwise exclusive OR (two operands)<br></td>
  </tr>
</table>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
 <tr>
     <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
 </tr>
 <tr>
    <td valign="top" colspan="2" class="description"><span class="title">Comparison Operators</span></td>
  </tr>
  <tr>
    <td><p>Comparison operators test whether two expressions are equal or unequal. The result of a comparison operation is a Boolean value: TRUE , FALSE , or UNKNOWN . Also, note that the ANSI standard behavior for a comparison operation where one or more of the expressions are NULL is NULL . For example, the expression 23 + NULL returns NULL, as does the expression Feb 23, 2002 + NULL . See Table 3.6 for a list of the comparison operators. </p>
    </td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
    </tr>

  <tr>
  <tr>
  <td>
<table width="75%" border="1">
  <tr>
    <th>Comparison Operators</th>
    <th>Meaning</th>
  </tr>
  <tr>
    <td>=</td>
    <td>Equal to</td>
  </tr>
  <tr>
    <td>&gt;</td>
    <td>Greater than</td>
  </tr>
  <tr>
    <td>&lt;</td>
    <td>Less than</td>
  </tr>
  <tr>
    <td>&gt;=</td>
    <td>Greater than or equal to </td>
  </tr>
  <tr>
    <td>&lt;=</td>
    <td> Less than or equal to</td>
  </tr>
  <tr>
    <td>&lt;&gt;</td>
    <td>Not equal to (not ANSI standard)</td>
  </tr>
  <tr>
    <td>!=</td>
    <td>Not equal to (not ANSI standard)</td>
  </tr>

  <tr>
    <td>!&lt;</td>
    <td>Not less than (not ANSI standard)</td>
  </tr>
  <tr>
    <td>!&gt;</td>
    <td>Not greater than (not ANSI standard)</td>
  </tr>
</table>
</td>
</tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
   <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Boolean comparison operators are used most frequently in a WHERE clause to filter the rows that qualify for the search conditions. The following Microsoft SQL Server example uses the greater than or equal to comparison operation: </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><span class="programlisting">
    <pre>SELECT *
   FROM Products
   WHERE ProductID &gt;= @MyProduct</pre>
</span>
    </td>
  </tr>

<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">Logical Operators</span>
</td>
</tr>
  <tr>
    <td><p>Logical operators are commonly used in a WHERE clause to test for the truth of some condition. Logical operators return a Boolean value of either TRUE or FALSE . Logical operators also are discussed under the SELECT topic. Not all RDBMS support all operators. See Table 3.7 for a list of logical operators. </p>
    </td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
    </tr>

 <tr>
  <td>
<table width="75%" border="1">
  <tr>
    <th>Logical Operators</th>
    <th>Meaning</th>
  </tr>
  <tr>
    <td>ALL</td>
    <td><p>TRUE if all of a set of comparisons are TRUE</p>
    </td>
  </tr>
   <tr>
    <td>AND</td>
    <td>TRUE if both Boolean expressions are TRUE</td>
  </tr>
  <tr>
    <td>ANY</td>
    <td>TRUE if any one of a set of comparisons is TRUE</td>
  </tr>
  <tr>
    <td>BETWEEN</td>
    <td>TRUE if the operand is within a range</td>
  </tr>
  <tr>
    <td>EXISTS</td>
    <td><p>TRUE if a subquery contains any rows</p>
    </td>
  </tr>
  <tr>
    <td>IN</td>
    <td>TRUE if the operand is equal to one of a list of expressions</td>
  </tr>
  <tr>
    <td>LIKE</td>
    <td>TRUE if the operand matches a pattern</td>
  </tr>
  <tr>
    <td>NOT</td>
    <td>Reverses the value of any other Boolean operator</td>
  </tr>
  <tr>
    <td>OR</td>
    <td>TRUE if either Boolean expression is TRUE<br></td>
  </tr>
  <tr>
    <td>SOME</td>
    <td>TRUE if some of a set of comparisons are TRUE<br></td>
  </tr>
</table>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">Unary Operators</span>
</td>
</tr>
  <tr>
    <td><p>Unary operators perform an operation on only one expression of any of the datatypes of the numeric datatype category. Unary operators may be used on integer datatypes, though positive and negative may be used on any numeric datatype (see Table 3.8 ). </p>
    </td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
    </tr>
  <tr>
   <td>
<table width="75%" border="1">
  <tr>
    <th>Unary Operators</th>
    <th>Meaning</th>
  </tr>
  <tr>
    <td>+</td>
    <td><p>Numeric value is positive    </p>
    </td>
  </tr>
 <tr>
    <td>-</td>
    <td>Numeric value is negative</td>
  </tr>
  <tr>
    <td>~</td>
    <td>A bitwise NOT, returns the complement of the number (not in Oracle)</td>
  </tr>
</table>
</td>
</tr>
   <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">Operator Precedence</span>
</td>
</tr>
  <tr>
    <td><p>Sometimes operator expressions become rather complex. When an expression has multiple operators, operator precedence determines the sequence in which the operations are performed. The order of execution can significantly affect the resulting value. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Operators have the following precedence levels. An operator on higher levels is evaluated before an operator on a lower level: </p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><span class="programlisting">
    () (parenthetical expressions)<br>
+, -, ~ (unary operators)<br>
*, /, % (mathematical operators)<br>
+, - (arithmetic operators)<br>
=, >, <, >=, <=, <>, !=, !>, !< (comparison operators)<br>
^ (Bitwise Exclusive OR), &amp; (Bitwise AND), | (Bitwise OR)<br>
NOT<br>
AND<br>
ALL, ANY, BETWEEN, IN, LIKE, OR, SOME <br>
= (variable assignment)</span>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Operators are evaluated from left to right when they are of equal precedence. However, parentheses are used to override the default precedence of the operators in an expression. Expressions within a parentheses are evaluated first, while operations outside the parentheses are evaluated next. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>For example, the following expressions in an Oracle query return very different results: </p>
    </td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>

  <tr>
<td>
<span class="programlisting">
<pre>SELECT 2 * 4 + 5 FROM dual
-- Evaluates to 8 + 5 which yields an expression result of 13.

SELECT 2 * (4 + 5) FROM dual
-- Evaluates to 2 * 9 which yields an expression result of 18.</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>In expressions with nested parentheses, the most deeply nested expression is evaluated first. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>This example contains nested parentheses, with the expression 5 -3 in the most deeply nested set of parentheses. This expression yields a value of 2 . Then, the addition operator (+) adds this result to 4 , which yields a value of 6 . Finally, the 6 is multiplied by 2 to yield an expression result of 12 : </p>
    </td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td>
    <span class="programlisting">
	<pre>SELECT 2 * (4 + (5 - 3) ) FROM dual
-- Evaluates to 2 * (4 + 2) which further evaluates to 2 * 6, and
-- yields an expression result of 12.</pre>
</span>
    </td>
  </tr>
</table>
</div>

<div id="RETURN">
<table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td Width="50%" align="left" class="name" valign="top">RETURN
  <td Width="50%" align="right"class="name" valign="top">SQL-control&nbsp;&nbsp;</td>
</tr></table>
<table width="100%" cellspacing="0" cellpadding="0" border="0">
  <tr>
    <td><p>The RETURN statement terminates processing within a SQL-invoked function (as opposed to a host-invoked function) and returns the function's result value. </p>
    </td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
 </tr>
  <tr>
  <td>
  <table border="1" >
<tr><th>Vendora</th>
<th>Command</th></tr>
<tr><td>SQL Server</td><td>Supported</td></tr><tr><td>MySQL</td><td>Supported</td></tr><tr><td>Oracle</td><td>Supported</td></tr><tr><td>PostgreSQL</td><td>Supported</td></tr></table>
</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">SQL99 Syntax and Description</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
RETURNS return_parameter_value | NULL</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The RETURN function is used within a function to end its processing. Using the NULL clause terminates the function without returning an actual value. Otherwise, the parameter value specified is returned either as a variable or as a literal expression. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Although the RETURN statement is categorized as a separate command within SQL, it is deeply intertwined with the CREATE FUNCTION statement. Check the CREATE FUNCTION statement for a more complete understanding of each vendor's implementation of RETURN. </p>
    </td>
  </tr>
<tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="example"><span class="title">
  Example</span>
</td>
</tr>
 <tr>
    <td><p>This example creates a function. The function returns the value that is stored in the proj_rev variable to the calling session: </p>
    </td>
  </tr><tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr><tr>
<td>
<span class="programlisting">
<pre>CREATE FUNCTION project_revenue (project IN varchar2)
RETURN NUMBER
AS
   proj_rev NUMBER(10,2);
BEGIN
   SELECT SUM(DECODE(action,'COMPLETED',amount,0) -
          SUM(DECODE(action,'STARTED',amount,0)   +
          SUM(DECODE(action,'PAYMENT',amount,0)
   INTO proj_rev
   FROM construction_actions
   WHERE project_name = project;
   RETURN (proj_rev);
END;</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>This example creates a function that returns a calculated value to the calling session: </p>
    </td>
  </tr>
  <tr>
    <td><tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>CREATE FUNCTION metric_volume -- Input dimensions in centimeters.
   (@length decimal(4,1),
   @width decimal(4,1),
   @height decimal(4,1) )
RETURNS decimal(12,3) -- Cubic Centimeters.
AS
BEGIN
   RETURN ( @length * @width * @height )
END
GO</pre>
</span>
</td>
</tr>
    </td>
  </tr>
</table>
</div>

<div id="REVOKE"><table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td Width="50%" align="left" class="name" valign="top">REVOKE<td Width="50%" align="right"class="name" valign="top">SQL-schema&nbsp;&nbsp;</td></tr></table>
<table width="100%" cellspacing="0" cellpadding="0" border="0">
  <tr>
    <td><p>The REVOKE statement removes permissions for a user, group, or role on a specific database object or system command. </p>
    </td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
  <td>
  <table border="1" >
<tr><th>Vendor</th>
<th>Command</th></tr>
<tr><td>SQL Server</td><td>Supported, with variations</td></tr><tr><td>MySQL</td><td>Supported, with variations</td></tr><tr><td>Oracle</td><td>Supported, with variations</td></tr><tr><td>PostgreSQL</td><td>Supported, with variations</td></tr></table>
</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">SQL99 Syntax and Description</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>REVOKE [GRANT OPTION FOR]
{ ALL PRIVILEGES }
| SELECT
| INSERT
| DELETE
| UPDATE
| REFERENCES
| USAGE }[,...n]
ON { [TABLE] table_name
| DOMAIN domain_name
| COLLATION collation_name
| CHARACTER SET character_set_name
| TRANSLATION translation_name }
FROM {grantee_name | PUBLIC} [,...n]
{CASCADE | RESTRICT}</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>A specific privilege on a specific database object can be revoked for a single user using REVOKE privilege_name ON object_name FROM grantee_name . A specific privilege on a specific object may be revoked from all users via the PUBLIC clause. As an alternative, the WITH GRANT OPTION can be used to revoke permissions using the REVOKE GRANT OPTION FOR clause. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The RESTRICT option revokes only the specified privilege. The CASCADE option revokes the specified privilege and any privileges that are dependent upon the granted privilege. A cascading revocation may exhibit different behavior on different database platforms, so be sure to read the vendor documentation for the correct implementation of this option. </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">Microsoft SQL Server Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>REVOKE [GRANT OPTION FOR]
{ALL [ PRIVILEGES ]
| SELECT
| INSERT
| DELETE
| UPDATE
| REFERENCES
| EXECUTE
| CREATE {DATABASE | DEFAULT | FUNCTION | PROCEDURE | RULE | TABLE | VIEW}
| BACKUP {DATABASE | LOG} } [,...n]
ON { {table_name | view_name} [(column [,...n])]
| stored_procedure_name
| extended_stored_procedure_name
| user_defined_function_name
| [(column [,...n] ON {table_name | view_name} }
{TO | FROM} {grantee_name} [,...n]
[CASCADE]
[AS {group_name | role_name} ]</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>This command is essentially SQL99 compatible, with the exception of the augmentations introduced in the GRANT command. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>If commands were granted to a user WITH GRANT OPTION enabled, the privilege should be revoked using both WITH GRANT OPTION and CASCADE . </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>REVOKE can only be used in the current database. REVOKE also is used to disable any DENY settings. </p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p><span class="emphasis">Tip:</span> Microsoft SQL Server additionally supports the DENY statement. DENY
is syntactically similar to REVOKE
. However, it is conceptually different in that REVOKE
neutralizes a user's privileges while DENY
explicitly prohibits a user's privileges. Use the DENY
statement to keep a user or role from accessing a privilege. <br>
</p>
    </td>
  </tr>

<tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="example"><span class="title">
  Example</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><span class="programlisting">
    <pre>REVOKE CREATE DATABASE, CREATE TABLE FROM emily, sarah
GO

REVOKE GRANT OPTION FOR
SELECT, INSERT, UPDATE, DELETE ON titles
TO editors
GO</pre>
</span>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">MySQL Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>REVOKE { ALL PRIVILEGES
| SELECT
| INSERT [ (column_name [,...n]) ]
| UPDATE [ (column_name [,...n]) ]
| REFERENCES [ (column_name [,...n]) ]
| DELETE
| USAGE
| ALTER
| CREATE
| DROP
| FILE
| INDEX
| PROCESS
| RELOAD
| SHUTDOWN } [,...n]
ON {table_name | * | *.* | database_name.*}
FROM user_name [,...n]</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The REVOKE statement rolls back any permissions previously granted to one or more users. Permissions may be revoked globally, as described in the GRANT statement. Furthermore, MySQL's implementation of REVOKE does not explicitly roll back permissions on objects that are dropped. Thus, it is necessary to explicitly REVOKE permissions on a table, even if the table is dropped. MySQL otherwise conforms to the SQL99 standard for the REVOKE command. </p>
    </td>
  </tr>
<tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="example"><span class="title">
  Example</span>
</td>
</tr>
  <tr>
    <td><p>The first command revokes all privileges on the <span class="emphasis">sales</span> table for Emily and Dylan, while the second command revokes all privileges for the user Kelly in the current database: </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><span class="programlisting">
    <pre>REVOKE ALL PRIVILEGES ON sales FROM emily, dylan;

REVOKE * employee FROM kelly;</pre>
</span>
    </td>
  </tr>

<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">Oracle Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>REVOKE {ALL [PRIVILEGES] | [object_privilege] }
ON { [schema_name.][object] | [DIRECTORY directory_object_name] }
FROM {grantee_name | role | PUBLIC} [,...n]
[CASCADE [CONSTRAINTS] ] [FORCE];

REVOKE {system_privilege | role}
FROM {grantee_name | role | PUBLIC} [,...n];</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The REVOKE command not only can revoke object and system privileges, it also can revoke a role from a given user or other role. Refer to the GRANT statement for more information on the specific object and system privileges supported by the REVOKE command. </p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p><span class="emphasis">Tip:</span> The two forms of the REVOKE
command, REVOKE object_privilege
and REVOKE system_privilege
, are mutually exclusive. Do not attempt to do both operations in a single statement. </p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>When a user's privileges are revoked, the privileges of all users who received their privileges from the revoked user also are revoked. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Users who are granted GRANT ANY ROLE system privilege also can revoke any role. The REVOKE command can only revoke privileges specifically granted with the GRANT command, not privileges available through roles or the operating system. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The ON DIRECTORY clause identifies a directory object where permissions are revoked. The CASCADE CONSTRAINTS clause drops any referential integrity constraints users create if their REFERENCES privilege is revoked. The FORCE clause revokes EXECUTE permissions on dependent user-defined table and type objects. Consequently, those objects are marked as invalid and unusable until they are recompiled. </p>
    </td>
  </tr>
<tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="example"><span class="title">
  Example</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>To revoke a user from a role: </p>
    </td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
   <tr>
   <td><span class="programlisting">REVOKE read-only FROM sarah;</span</td>
   <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>To revoke a system-command privilege: </p>
    </td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
  <td><span class="programlisting">REVOKE CREATE ANY SEQUENCE, CREATE ANY DIRECTORY FROM read_only;</span</td>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>To revoke a REFERENCES privilege: </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><span class="programlisting">REVOKE REFERENCES ON pubs_new_york.emp FROM dylan CASCADE CONSTRAINTS;</span>
    </td>
  </tr>

<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">PostgreSQL Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>REVOKE { ALL
| SELECT
| INSERT
| DELETE
| UPDATE
| RULE
| REFERENCES
| USAGE} [,...n]
ON {object_name}
TO {grantee_name | PUBLIC | GROUP group_name}
{CASCADE | RESTRICT}</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Access to tables, views, and sequences can be revoked in PostgreSQL. It is otherwise identical to the SQL99 command. Refer to the SQL99 REVOKE syntax discussion, as well as the SQL99 GRANT discussion. </p>
    </td>
  </tr>
</table>
</div>

<div id="ROLLBACK"><table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td Width="50%" align="left" class="name" valign="top">ROLLBACK
  <td Width="50%" align="right"class="name" valign="top">SQL-transaction&nbsp;&nbsp;</td>
</tr></table>
<table width="100%" cellspacing="0" cellpadding="0" border="0">

  <tr>
    <td><p>The ROLLBACK statement undoes a transaction to its beginning or a previously declared SAVEPOINT . It closes open cursors and releases locks in the same way as COMMIT . </p>
    </td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
  <table border="1" >
<tr><th>Vendor</th>
<th>Command</th></tr>
<tr><td>SQL Server</td><td>Supported, with variations</td></tr><tr><td>MySQL</td><td>Not supported</td></tr><tr><td>Oracle</td><td>Supported</td></tr><tr><td>PostgreSQL</td><td>Supported</td></tr></table></td>
</tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">SQL99 Syntax and Description</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
ROLLBACK [WORK] [TO SAVEPOINT savepoint_name]</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>In addition to finalizing a single or group of data-manipulation operations, the ROLLBACK statement undoes transactions up to the last issued BEGIN or SAVEPOINT statement. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>SQL99 offers the new, optional keywords AND CHAIN . None of the four vendors yet support this command. This new syntax is: </p>
    </td>
  </tr></tr>
<tr>
<td>
<span class="programlisting">ROLLBACK [WORK] [AND [NO] CHAIN]</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The AND CHAIN option tells the DBMS to end the current transaction, but to share the common transaction environment (such as transaction isolation level) with the next transaction. The AND NO CHAIN option simply ends the single transaction. The ROLLBACK command is functionally equivalent to the command, ROLLBACK WORK AND NO CHAIN . </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">Microsoft SQL Server Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>ROLLBACK [TRAN[SACTION] [transaction_name |
 @tran_name_variable |
savepoint_name | @savepoint_variable] ]</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>ROLLBACK clears all data modifications made to the current open transaction or to a specific, existing savepoint. If ROLLBACK is issued alone, it rolls back the current open transaction. ROLLBACK normally frees locks, but it does not free locks when rolling back to a savepoint. ROLLBACK behaves similarly to COMMIT with regards to nested triggers, decrementing the @@TRANCOUNT system variable by one. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>ROLLBACK TRANSACTION , when issued in a trigger, undoes all data modifications, including those performed by the trigger, up to the point of the ROLLBACK statement. Nested triggers are not executed if they follow a ROLLBACK within a trigger; however, any statements within the trigger that follow the rollback are not impacted by the rollback. </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">
Oracle Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
ROLLBACK [WORK] [TO savepoint_name] [FORCE text];</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>ROLLBACK clears all data modifications made to the current open transaction or to a specific, existing savepoint. Oracle's implementation closely follows the SQL standard with the exception of the FORCE option. ROLLBACK FORCE rolls back to an in-doubt distributed transaction. These transactions are described in the Oracle system view, DBA_2PC_PENDING . </p>
    </td>
  </tr>

<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">PostgreSQL Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
{ROLLBACK | ABORT} [WORK | TRANSACTION];</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>ROLLBACK clears all data modifications made to the current open transaction or to a specific, existing savepoint. PostgreSQL supports both the SQL99 WORK option and the TRANSACTION option. It does not support rolling back to a savepoint. The ABORT option may be used as a full synonym of ROLLBACK . </p>
    </td>
  </tr>
<tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="example"><span class="title">
  Example</span>
</td>
</tr>
  <tr>
    <td><p>Here is a Transact-SQL batch using COMMIT and ROLLBACK in Microsoft SQL Server. It inserts a record into the sales table. If it fails, the transaction is rolled back; if the statement succeeds, the transaction is committed: </p>
    </td>
  </tr>
  <tr>
        <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><span class="programlisting">
    <pre>BEGIN TRAN -- initializes a transaction

-- the transaction itself
INSERT INTO sales
VALUES('7896','JR3435','Oct 28 1997',25,'Net 60','BU7832')

-- some error-handling in the event of a failure
IF @@ERROR &lt;&gt; 0
BEGIN
    -- raises an error in the event log and skips to the end
    RAISERROR 50000 'Insert of sales record failed'
    ROLLBACK WORK
    GOTO end_of_batch
END

-- the transaction is committed if no errors are detected
COMMIT TRAN

-- the GOTO label that enables the batch to skip to the end without
-- committing
end_of_batch:
GO</pre>
</span>
    </td>
  </tr>
</table>
</div>

<div id="SAVEPOINT"><table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td Width="50%" align="left" class="name" valign="top">SAVEPOINT</td>
  <td Width="50%" align="right"class="name" valign="top">SQL-transaction&nbsp;&nbsp;</td>
</tr></table>
<table width="100%" cellspacing="0" cellpadding="0" border="0">
   <tr>
    <td><p>This command creates a savepoint in the current transaction. Transactions can be divided into logical breakpoints using the SAVEPOINT command. Multiple savepoints may be specified within a single transaction. The main benefit of the SAVEPOINT command is that transactions may be partially rolled back to a unique savepoint marker using the ROLLBACK command. </p>
    </td>
  </tr>
  <td>
  <tr>
  <table border="1" >
<tr><th>Vendor</th>
<th>Command</th></tr>
<tr><td>SQL Server</td><td>Supported, with variations</td></tr><tr><td>MySQL</td><td>Not supported</td></tr><tr><td>Oracle</td><td>Supported</td></tr><tr><td>PostgreSQL</td><td>Not supported</td></tr></table></td>
</tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">SQL99 Syntax and Description</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
SAVEPOINT savepoint_name</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Some vendors allow duplicate savepoint names within a transaction, but this is not recommended. Substitute savepoint identifiers (in the format :X) also may be included to enable DBMS to track the savepoint with an integer rather than a name. Not all vendors support this approach, and it is not recommended as the best practice. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Note that SQL99 supports the statement RELEASE SAVEPOINT savepoint_name , enabling an existing savepoint to be eliminated. However, this statement is not supported by any of the vendors covered in this book. </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">
Microsoft SQL Server Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">

SAVE TRAN[SACTION] {savepoint_name | @savepoint_variable}</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Microsoft SQL Server does not support the SAVEPOINT command. Instead, it uses the SAVE command. Rather than declaring the literal name of the savepoint, you can reference a variable containing the name of the savepoint. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>When the ROLLBACK TRAN savepoint_name command is executed, SQL Server rolls the transaction back to the appropriate savepoint, then continues processing at the next valid Transact-SQL command following the ROLLBACK statement. Finally, the transaction must be concluded with a COMMIT or a final ROLLBACK statement. </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">Oracle Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
SAVEPOINT savepoint_name</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Oracle fully supports the SQL99 implementation. </p>
    </td>
  </tr>
<tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="example"><span class="title">
  Example</span>
</td>
</tr>
    <tr>
    <td><p>This example performs several data modifications, rolls back to a savepoint, and then rolls back the transaction completely: </p>
    </td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>

  <tr>
    <td><span class="programlisting">
    <pre>INSERT INTO sales VALUES('7896','JR3435','Oct 28 1997',25,'Net
60','BU7832');

SAVEPOINT after_insert;

UPDATE sales SET terms = 'Net 90'
WHERE sales_id = '7896';

SAVEPOINT after_update;

DELETE sales;

ROLLBACK TO after_insert;
ROLLBACK;</pre>
</span>
    </td>
  </tr>
</table>
</div>

<div id="SELECT">
  <table width="100%" cellspacing="0" cellpadding="0" border="0">
    <tr>
      <td Width="50%" align="left" class="name" valign="top">SELECT</td>
      <td Width="50%" align="right"class="name" valign="top">SQL-data&nbsp;&nbsp;</td>
    </tr>
  </table>
  <table width="100%" cellspacing="0" cellpadding="0" border="0">
    <tr>
      <td><p>The SELECT statement retrieves rows, columns, and derived values
          from one or many tables of a database. </p></td>
    </tr>
    <tr>
      <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
    </tr>
    <tr>
      <td> <table border="1" >
          <tr>
            <th>Vendor</th>
            <th>Command</th>
          </tr>
          <tr>
            <td>SQL Server</td>
            <td>Supported, with variations (ANSI joins supported)</td>
          </tr>
          <tr>
            <td>MySQL</td>
            <td>Supported, with variations (ANSI joins partially supported)</td>
          </tr>
          <tr>
            <td>Oracle</td>
            <td>Supported, with variations (ANSI joins not supported)</td>
          </tr>
          <tr>
            <td>PostgreSQL</td>
            <td>Supported, with variations (ANSI joins partially supported)</td>
          </tr>
        </table></td>
    </tr>
    <tr>
      <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
    </tr>
    <tr>
      <td valign="top" class="description"><span class="title">SQL99 Syntax and
          Description</span></td>
    </tr>
    <tr>
      <td><p>The full syntax of the SELECT statement is powerful and complex,
          but can be broken down into these main clauses: </p></td>
    </tr>
    <tr>
      <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
    </tr>
    <tr>
      <td> <span class="programlisting">
<pre>SELECT [ALL | DISTINCT] select_list
FROM table_name1 [,..., table_nameN]
[JOIN join_condition]
[WHERE search_condition]
[GROUP BY group_by_expression]
[HAVING search_condition]
[ORDER BY order_expression [ASC | DESC] ]</pre>
</span> </td>
    </tr>
    <tr>
      <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
    </tr>
    <tr>
      <td><p>Each clause of the SELECT statement has a specific use. Thus, it
          is possible to speak individually of the FROM clause, the WHERE clause,
          or the GROUP BY clause. However, not every query needs every clause.
          At a minimum, a query needs a SELECT item list and a FROM clause. (Microsoft
          SQL Server and PostgreSQL both support certain types of queries that
          do not need a FROM clause. Refer to the examples below for more information.) </p></td>
    </tr>
    <tr>
      <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
    </tr>
    <tr>
      <td valign="top" class="description"><span class="title"> SELECT item list</span> </td>
    </tr>
    <tr>
      <td><p>The SELECT item list basically includes all items of information
          a user wants to retrieve from the server. Different types of elements
          can appear in the select item list. It's possible to retrieve literal
          strings, aggregate functions, and mathematical calculations. In Microsoft
          SQL Server, the SELECT item list may contain a subquery. </p></td>
    </tr>
    <tr>
      <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
    </tr>
    <tr>
      <td><p>ALL is the default, meaning all records are returned, including
          defaults. DISTINCT is a keyword that tells the query to filter out
          all duplicate records. Thus, the result set includes only one instance
          of identical records.</p></td>
    </tr>
    <tr>
      <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
    </tr>
    <tr>
      <td><p>There are several other rules for what can appear in the SELECT
          item list: </p></td>
    </tr>
    <tr>
      <td> <ul>
          <li>Most commonly, all the columns desired should be listed out using
            a comma between each one.</li>
          <li>An asterisk (*) serves as shorthand to retrieve all the columns
            in every table shown in the FROM clause, as they are listed in the
            CREATE TABLE statement. </li>
          <li>Column aliases are added in to replace the default column headings
            used in the results. Use the format column AS &quot;alias&quot;<br>
            or column alias. This is especially useful when a column heading
            is too cryptic or lengthy to be readily understood. For example:
            <br>-- alias format SELECT au_lname AS &quot;Last Name&quot; FROM
              authors -- alternative alias format SELECT au_lname &quot;Last
              Name&quot; FROM authors.
          </li>
          <li>Local and global variables, where supported, may appear as a select
            list item.</li>
          <li>Comments may be dispersed throughout any SQL or Transact-SQL statement
            by using either the double-dash ( <br>
&#8212; ) or the slash-asterisk ( /* ... */ ). The double-dash causes the query
to ignore any text that follows the double-dash until the end of line. The slash
causes the query to ignore any text within the slash-asterisk and inverse slash-asterisk. </li>
          <li>The table name should be prefixed to the column name in a query
            using multiple tables. Technically, the table name needs to apply
            to any column in <span class="emphasis">both</span> tables; it is
            commonly considered good practice to do so anyway. For example, both
            the <br>
            <span class="emphasis">jobs </span> and <span class="emphasis">employee</span> tables
            contain the <span class="emphasis">job_id</span> column:

            <br>SELECT employee.emp_id, employee.fname, employee.lname, jobs.job_desc
              FROM employee, jobs WHERE employee.job_id = jobs.job_id ORDER BY
              employee.fname, employee.lname
          </li>
          <li>The schema or owner name should be prefixed to a column when extracted
            from a context outside of the current user. If the table is owned
            by another username, then the username must be included in the column
            reference. For example, assume that this example query is run in
            the PUBS database but also retrieves data from the SALES database:
            <br>SELECT employee.emp_id, salesadmin.sales_summary.total_amt --
              the schema, table, and then column name must be listed! FROM employee,
              salesadmin.sales_summary WHERE employee.emp_id = salesadmin.sales_summary.emp_id
              ORDER BY employee.emp_id;
          </li>
          <li> Literal expressions may be used as a select list item.</li>
          <li>Mathematics calculations can be entered as a select list item.
            In Microsoft SQL Server, no FROM statement is needed. In Oracle,
            the calculation should be executed against the system table called
            DUAL . The table allows the SELECT command to retrieve values where
            no table exists. For example:<br>
            --QUERY (Microsoft) SELECT 2 + 2 --QUERY (Oracle) SELECT 2 + 2
              FROM dual --RESULTS 4

          </li>
        </ul></td>
    </tr>
    <tr>
      <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
    </tr>
    <tr>
      <td valign="top" class="description"><span class="title"> FROM clause</span></td>
    </tr>
    <tr>
      <td><p>The FROM clasue generally serves two purposes: to list the tables
          and views where a query retrieved its data (with a comma between each
          tablename); and to assign an alias for long table names, making coding
          lengthy queries a lot easier. An alias can be assigned in the FROM
          clause by two means: by typing the tablename, a space, and the alias;
          or by typing the tablename, AS, and the alias.The example below illustrates
          each of these techniques. An example of a query that extracts data
          from multiple tables might have a FROM and WHERE clause that is coded
          in the following manner: </p></td>
    </tr>
    <tr>
      <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
    </tr>
    <tr>
      <td><span class="programlisting">
<pre>SELECT   e.emp_id,
         e.fname,
         e.lname,
         j.job_desc
FROM     employee e,
         jobs AS  j
WHERE    e.job_id = j.job_id
ORDER BY e.fname,
         e.lname</pre>
</span> </td>
    </tr>
    <tr>
      <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
    </tr>
    <tr>
      <td><p><span class="emphasis">Tip:</span> Once an alias has been assigned
          in a query, be sure to use it exclusively for table references within
          that query. Do <span class="emphasis">not</span> mix references to
          the full table name and the alias in a query. </p></td>
    </tr>
    <tr>
      <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
    </tr>
    <tr>
      <td><p>This query retrieves the emp_id (first and last name of each employee
          stored in the <span class="emphasis">employee</span> table) and joins
          the <br>
          job_id of the employee, which is a code number, with the full job description
          found in the JOBS table. <br>
          <br>
        </p></td>
    </tr>
    <tr>
      <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
    </tr>
    <tr>
      <td valign="top" class="description"><span class="title">JOIN clause</span></td>
    </tr>
    <tr>
      <td><p>In non-ANSI standard implementations, the join operation is performed
          in the WHERE clause (described in the section on WHERE clauses). In
          the ANSI SQL-92 standards, joins are performed in the JOIN clause of
          the query. These join methods are known as the <span class="emphasis">theta
          style</span> and the <span class="emphasis">ANSI style</span> of joins,
          respectively. </td>
    </tr>
    <tr>
      <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
    </tr>
    <tr>
      <td><p> To retrieve joined data from two or more tables, the tables first
          must share a meaningful relationship. <span class="emphasis">The tables
          to be joined must possess a column or columns that share a common set
          of values that allow the tables to be meaningfully linked.</span> This
          column, or columns, is called the <span class="emphasis">join key</span> or <span class="emphasis">common
          key</span> . Most  but not all  of the time, the join key is the
          primary key of one table and a foreign key in another table. As long
          as the data in the columns match, the join can be performed.</p></td>
    </tr>
    <tr>
      <td> In the PUBS database, both the <span class="emphasis">employee</span> table
        and the <span class="emphasis">jobs</span> table contain a <span class="emphasis">job_id</span> column.
        Thus, <span class="emphasis">job_id</span> is the common key between
        the <span class="emphasis">employee</span> and <span class="emphasis">jobs</span> tables.
        To perform a query using an ANSI-style join, list the first table and
        the keyword JOIN , followed by the table to be joined. Once the second
        table is typed in, type the keyword ON and the join condition that would
        have been used in the old style query. The following shows the original
        query now in ANSI style: </td>
    </tr>
    <tr>
      <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
    </tr>
    <tr>
      <td><span class="programlisting">
<pre>SELECT   e.emp_id,
         e.fname,
         e.lname,
         j.job_desc
FROM     employee AS e
JOIN     jobs AS j ON e.job_id = j.job_id
ORDER BY e.fname,
         e.lname</pre>
</span> </td>
    </tr>
    <tr>
      <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
    </tr>
    <tr>
      <td valign="top" class="description"><span class="title">Join types</span></td>
    </tr>
    <tr>
      <td> These problems are solved by the use of join types in the ANSI style
        and the equal-asterisk (` =*' ) combination for Microsoft SQL Server
        or plus-asterisk (` +* ') for Oracle in theta joins. The following list
        shows how to control this behavior in joins:
    </tr>
    </td>
     <tr>
      <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
    </tr>
    <tr>
      <td><p>Cross Join:<br>
          Specifies the complete cross product of two tables. For each record
              in the first table, all the records in the second table are joined,
              creating a <span class="emphasis">huge</span> result set. This
              command has the same effect as leaving off the join condition and
              is also know as a "Cartesian Product." Cross joins are not advisable
              or recommended (currently supported by Microsoft SQL Server): <br>
        </p></td>
    </tr>
    <tr>
      <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
    </tr>
    <tr>
      <td><span class="programlisting">
<pre>-- theta style
SELECT e.emp_id,
       e.fname,
       e.lname,
       j.job_desc
FROM   employee e,
   Jobs j

-- ANSI style
SELECT e.emp_id,
       e.fname,
       e.lname,
       j.job_desc
FROM   employee e
CROSS JOIN jobs j</pre></span> </td>
    </tr>
    <tr>
      <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
    </tr>
    <tr>
      <td><p>Inner Join:</p></td>
    </tr>
    <tr>
      <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
    </tr>
    <tr>
      <td><p>Specifies that unmatched rows in either table of the join should
          be discarded. If no join type is explicitly defined in the ANSI style,
          then this is the default (currently supported by Microsoft SQL Server,
          PostgreSQL and MySQL): <br>
        </p></td>
    </tr>
    <tr>
      <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
    </tr>
    <tr>
      <td>
<pre>-- theta style
SELECT e.emp_id,
       e.fname,
       e.lname,
       j.job_desc
FROM   employee e,
       jobs j
WHERE  e.job_id = j.job_id

-- ANSI style
SELECT e.emp_id,
       e.fname,
       e.lname,
       j.job_desc
FROM   employee e
JOIN   jobs j ON e.job_id = j.job_id</pre></span> </td>
    </tr>
    <tr>
      <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
    </tr>
    <tr>
      <td><p>Left [Outer] Join:</p></td>
    </tr>
    <tr>
      <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
    </tr>
    <tr>
      <td><p>Specifies that all records be returned from the table on the left
          side of the join statement. If a record is returned from the left table
          has no matching record in the table on the right side of the join,
          it is still returned. Columns from the right table return NULL values.
          (In this case, all employees are returned whether they have a job description
          or not.) Many professionals recommend configuring outer joins as left
          joins wherever possible for consistency (currently supported by Microsoft
          SQL Server):</p></td>
    </tr>
    <tr>
      <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
    </tr>
    <tr>
      <td><span class="programlisting">
      <pre>-- Oracle theta style
SELECT e.emp_id,
       e.fname,
       e.lname,
       j.job_desc
FROM   employee e,
       jobs     j
WHERE   j.job_id (+) = e.job_id

-- ANSI style
SELECT e.emp_id,
       e.fname,
       e.lname,
       j.job_desc
FROM   employee e
LEFT JOIN jobs j ON e.job_id = j.job_id</pre></span> </td>
    </tr>
    <tr>
      <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
    </tr>
    <tr>
      <td><p>Right [Outer] Join:</p></td>
    </tr>
    <tr>
      <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
    </tr>
    <tr>
      <td><p>Specifies that all records be returned from the table on the right
          side of the join statement, even if the table on the left has no matching
          record. Columns from the left table return NULL values. (In the example,
          all records in the <span class="emphasis">jobs</span><br>
          table are returned with or without a matching record in the <span class="emphasis">employee</span> table
          (currently supported by Microsoft SQL Server): </p></td>
    </tr>
    <tr>
      <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
    </tr>
    <tr>
      <td><span class="programlisting">
      <pre>-- Oracle theta style
SELECT e.emp_id,
       e.fname,
       e.lname,
       j.job_desc
FROM   employee e,
       jobs j
WHERE  j.job_id = (+) e.job_id

-- ANSI style
SELECT e.emp_id,
       e.fname,
       e.lname,
       j.job_desc
FROM   employee e
RIGHT JOIN jobs j ON e.job_id = j.job_id</pre></span> </td>
    </tr>
    <tr>
      <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
    </tr>
    <tr>
      <td><p>Full Join:</p></td>
    </tr>
    <tr>
      <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
    </tr>
    <tr>
      <td><p> Specifies that all rows from either table be returned, regardless
          of matching records in the other table. The result set shows NULL values
          where no data exists in the join (currently supported by Microsoft
          SQL Server): </p></td>
    </tr>
    <tr>
      <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
    </tr>
    <tr>
      <td><p>-- theta style does not support this -- function -- ANSI style SELECT
          e.emp_id, e.fname, e.lname, j.job_desc FROM employee e FULL JOIN jobs
          j ON e.job_id = j.job_id </p></td>
    </tr>
    <tr>
      <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
    </tr>
    <tr>
      <td><p>Joins in the ANSI style are actually easier to understand than those
          in theta style, since the query itself clearly indicates which table
          is on the left in a LEFT JOIN and which table is on the right in a
          RIGHT JOIN. </p></td>
    </tr>
    <tr>
      <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
    </tr>
    <tr>
      <td><p>The syntax to perform a similar query with multipart keys and multiple
          tables joined together is largely an extension of the same technique. </p></td>
    </tr>
    <tr>
      <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
    </tr>
    <tr>
      <td valign="top" class="description"><span class="title">Multi-table Join
          Example</span></td>
    </tr>
        <tr>
	      <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
	    </tr>

    <tr>
      <td><span class="programlisting">
      <pre>--theta style query with multiple tables
SELECT   a.au_lname,
         a.au_fname,
         t2.title
FROM     authors a,
         titleauthor t1,
         titles t2
WHERE    a.au_id     = t1.au_id
  AND    t1.title_id = t2.title_id
ORDER BY t2.title

-- ANSI style query with multiple tables
SELECT   a.au_lname,
         a.au_fname,
         t2.title
FROM     authors a
JOIN     titleauthor AS t1 ON a.au_id     = t1.au_id
JOIN     titles      AS t2 ON t1.title_id = t2.title_id
ORDER BY t2.title</pre></span> </td>
    </tr>
    <tr>
      <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
    </tr>
    <tr>
      <td valign="top" class="description"><span class="title"> Multi-key Join
          Example:</span></td>
    </tr>
    <tr>
      <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
    </tr>
    <tr>
      <td> <span class="programlisting">
      <pre>--theta style query with multipart key
SELECT   s1.store_id,
         s1.title_id,
         s2.qty
FROM     sales s1,
         sales_projections s2
WHERE    s1.store_id = s2.store_id
  AND  s1.title_id = s2.title_id
ORDER BY s1.store_id, s2.title_id

-- ANSI style query with multipart key
SELECT   s1.store_id,
         s1.title_id,
         s2.qty
FROM     sales s1
JOIN     sales_projections s2 ON s1.store_id = s2.store_id
   AND   s1.title_id = s2.title_id
ORDER BY s1.store_id, s2.title_id</span> </td>
    </tr>
    <tr>
      <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
    </tr>
    <tr>
      <td valign="top" class="description"><span class="title"> The WHERE clause:</span></td>
    </tr>
    <tr>
      <td><p> The WHERE clause is an extremely potent component of the SELECT
          statement.The WHERE clause provides most of the search conditions that
          cull unwanted data from the query; the remaining search conditions
          are satisfied by the HAVING clause (explained later in this section). <br>
          A poorly written WHERE clause can ruin an otherwise beautiful SELECT
          statement, so the nuances of the WHERE clause <span class="emphasis"> must
          be mastered</span> thoroughly. This is an example of a typical query
          and a multipart WHERE clause: </p></td>
    </tr>
    <tr>
      <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
    </tr>
    <tr>
      <td><span class="programlisting">
      <pre>SELECT   a.au_lname,
         a.au_fname,
         t2.title,
         convert(char,t2.pubdate)
FROM     authors a
JOIN     titleauthor t1 ON a.au_id = t1.au_id
JOIN     titles t2 ON t1.title_id = t2.title_id
WHERE    (t2.type = 'business' OR t2.type = 'popular_comp')
  AND    t2.advance &gt; $5500
ORDER BY t2.title</pre>
</span> </td>
    </tr>
    <tr>
      <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
    </tr>
    <tr>
      <td><p>In examining the query, note that parentheses impact the order in
          which WHERE criteria are processed according to Operators Precedence. </p></td>
    </tr>
    <tr>
      <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
    </tr>
    <tr>
      <td><p> The database's default <span class="emphasis">sort order</span> determines
          how the WHERE clause retrieves results sets for a query. For example,
          Microsoft SQL Server is (by default) dictionary-order and case-insensitive
          , making no differentiation between "Smith", "smith", and "SMITH".
          But Oracle uses dictionary-order and case-sensitive, finding the values "Smith", "smith",
          and "SMITH" to be unequal. </p></td>
    </tr>
    <tr>
      <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
    </tr>
    <tr>
      <td><p> There are more specific capabilities of the WHERE clause than what
          is illustrated in the example. Table 3.9 helps provide a quick summary
          of the common capabilities of the WHERE clause. </p></td>
    </tr>
    <tr>
      <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
    </tr>
    <tr>
      <td>
	  <table align="center" border="1">
    <tr>
      <th> Search Condition Shorthand<br></th>
      <th>Syntax</th>
      <th>Example</th>
      <th>Usage and Description</th>
    </tr>
    <tr>
      <td>Simple Boolean check</td>
      <td>WHERE [NOT] expression comparison_operator expression</td>
      <td>SELECT au_id FROM authors WHERE au_id = '172-32-1176' SELECT au_id
        FROM authors WHERE au_lname NOT LIKE 'John%'</td>
      <td>The operators &lt;, &gt;, &lt;&gt;, &gt;=, &lt;= , and = can be used
        when comparing expressions. There are also a number of special comparison
        operators, such as <br>
        LIKE , described later in this table. The keyword NOT checks for the
        inverse of any Boolean check based on the regular operators &lt;, &gt;, &lt;&gt;, &gt;=, &lt;=
        , and =, in addition to special operators such as <br>
        LIKE , NULL , BETWEEN , IN , EXISTS , ANY , and ALL.<br></td>
    </tr>
    <tr>
      <td>Multiple search conditions</td>
      <td>WHERE [NOT] expression comparison_operator expression {AND | OR} expression
        comparison_operator expression</td>
      <td>SELECT au_id FROM authors WHERE au_id = '172-32-1176' AND au_lname
        = 'White'</td>
      <td>AND merges multiple conditions and returns results when <b>both</b> conditions
        are true. AND takes priority over other operators. <br>
        <br>
        Parentheses in the WHERE clause further affect the priority of operators. <br>
        OR merges multiple conditions and returns results when <b>either </b> condition
        is true. OR takes priority after AND.<br></td>
    </tr>
    <tr>
      <td>NULL check</td>
      <td>WHERE [NOT] column_name IS [NOT] NULL<br></td>
      <td>SELECT * FROM titles WHERE price IS NULL</td>
      <td>IS NULL and IS NOT NULL tell the query to check for null values (or
        all values except null values). <br></td>
    </tr>
    <tr>
      <td>JOIN check</td>
      <td><p>WHERE [NOT] column_value(s) [(+)]=[(+)] column_value(s)<br>
          Or<br>
          WHERE [NOT] column_value(s) [*]=[*] column_value(s)</p>
        </p></td>
      <td>SELECT a.au_lname, a.au_fname, t2.title FROM authors a, titleauthor
        t1, titles t2 WHERE a.au_id = t1.au_id AND t1.title_id = t2.title_id
        ORDER BY t2.title</td>
      <td>JOIN checks can be performed by evaluating the common key between two
        or more tables. Outer joins are accomplished in PostgreSQL by adding
        the asterisk to the side where all records should be retrieved. Outer
        joins in Oracle are accomplished by adding the plus sign in parentheses
        (+) to the side where null values are allowed (basically, the opposite
        of the asterisk method). Refer to the previous section on JOINs<br>
        for more information.</td>
    </tr>
    <tr>
      <td>LIKE check</td>
      <td>WHERE [NOT] column_name [NOT] LIKE 'match_string'</td>
      <td> /* get any phone number starting with 415 */ SELECT * FROM authors
        WHERE phone LIKE '415%'<br></td>
      <td>LIKE tells the query to use pattern matching on the string in quotation
        marks. The wildcard symbols are detailed under the LIKE entry</td>
    </tr>
    <tr>
      <td>EXISTence check</td>
      <td>WHERE [NOT] EXISTS (subquery)</td>
      <td>SELECT p1.pub_name FROM publishers p1 WHERE EXISTS (SELECT * FROM titles
        t1 WHERE pub_id =p1.pub_id AND type = 'psychology')</td>
      <td>EXISTS is always used in conjunction with a subquery; rather than returning
        data, the subquery is a Boolean test of whether the data exists. This
        example will return all publishers of psychology books.</td>
    </tr>
    <tr>
      <td>BETWEEN range check</td>
      <td>WHERE [NOT] expression [NOT] BETWEEN expression AND expression</td>
      <td>SELECT * FROM titles WHERE ytd_sales BETWEEN 4000 AND 9000</td>
      <td>BETWEEN performs an inclusive range check. It is the same as <br>
        WHERE <b>(expression</b> &gt;= <br>
        <b>x and expression</b> &lt;=<br>
        <b>y)</b>. <br></td>
    </tr>
    <tr>
      <td>IN range check</td>
      <td>WHERE [NOT] expression [NOT] IN (value_list | subquery)</td>
      <td>SELECT * FROM stores WHERE state IN ('WA','IL','NY') SELECT * FROM
        stores WHERE stor_id IN (SELECT stor_id FROM sales WHERE ord_date LIKE 'Oct%')</td>
      <td>IN returns a result set that matches any of a list of values or returns
        a result set of the outer query whose value matches those values returned
        by a subquery. The <b>value_list</b> or subquery should be enclosed in
        parentheses. </td>
    </tr>
    <tr>
      <td>SOME | ALL<br>
        range check </td>
      <td>WHERE [NOT] expression comparison_operator {[ANY | SOME] | ALL} (subquery)</td>
      <td>-- to duplicate the functionality of IN SELECT au_lname, au_fname FROM
        authors WHERE city = ANY (SELECT city FROM publishers) -- to duplicate
        the functionality of NOT IN SELECT au_lname, au_fname FROM authors WHERE
        city &lt;&gt; ALL (SELECT city FROM publishers) /* to find the titles
        that got an advance larger than the minimum advance amount paid New Moon
        Books*/ SELECT title FROM titles WHERE advance &gt; ANY (SELECT advance
        FROM publishers, titles WHERE titles.pub_id = publishers.pub_id AND pub_name
        = 'New Moon Books')</td>
      <td> <p>ALL and SOME are always used with a subquery and a comparison operator,
          such as &lt;, &gt;, &lt;&gt;, &gt;=, or &lt;=. A query of the ALL type
          evaluates either TRUE or FALSE when all values retrieved by the subquery
          match the value in the WHERE (or HAVING <br>
          ) clause, or when the subquery returns no rows of the outer statement. </p>
        <p>SOME has the same functionality as EXISTS . It works the same as <br>
          ALL , except that it evaluates to TRUE when any value retrieved in
            the subquery satisfies the comparison predicate in the <br>
          WHERE clause of the outer statement. <br>
        </p></td>
    </tr>
  </table>
  </td>
  </tr>
  <tr>
    <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Table 3.9 </p></td>
  </tr>
  <tr>
    <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p> As mentioned in Table 3.9 wildcard characters can augment the search
        options, especially with the LIKE operator. ReAggregates and the GROUP
        BY clausefer to the LIKE topic for more information on types of wildcard
        operations.</p></td>
  </tr>
  <tr>
    <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Aggregates and the GROUP BY clause:</p></td>
  </tr>
  <tr>
    <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The GROUP BY clause (and the HAVING clause) are indeed only in queries
        that utilize <span class="emphasis">aggregate functions </span> (discussed
        earlier in this chapter). Queries using aggregate functions provide many
        types of summary information. The most common aggregate functions include: </p></td>
  </tr>
  <tr>
    <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><ul>
      <li> AVG: returns the average of all non-NULL values in the specified column(s). </li>
      <li> COUNT: counts the occurrences of all non-NULL values in the specified
        column(s). </li>
      <li>COUNT DISTINCT: counts the occurrences of all unique, non-null values
        in the specified column(s). </li>
      <li>COUNT(*): counts every record in the table. </li>
      <li>MAX: MAX aggregate function returns the highest non-NULL value in the
        specified column(s). </li>
      <li>MIN: MIN aggregate function returns the lowest non-NULL value in the
        specified column(s). </li>
      <li>SUM: totals all non-NULL values in the specified column(s). </li>
	  </ul></td>
  </tr>
  <tr>
    <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p> The aggregate functions are limited by the datatypes on which they
        may be used. Only COUNT and COUNT DISTINCT can be used by a column of
        any datatype. MIN and MAX operate on numeric columns (of any type), as
        well as date and character columns. The SUM and AVG functions may operate
        only on numeric column datatypes. <br>
      </p></td>
  </tr>
  <tr>
    <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p> <span class="emphasis">Tip:</span> If it is necessary to perform
        aggregate functions on columns containing null values, use the ISNULL(
        ) function in SQL Server or the NVL function in Oracle to assign a value
        to the null columns. </p></td>
  </tr>
  <tr>
    <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p> Queries that return a sole value are known as a <span class="emphasis">scalar
          aggregate</span> values. Scalar aggregates do not need a GROUP BY<br>
        clause. For example:<br>
        --Query SELECT AVG(price) FROM titles --Results 14.77<br>
        <br>
        Queries that return both regular column values and aggregate functions
        are commonly called <span class="emphasis">vector aggregates</span>.
        Vector aggregates use the GROUP BY clause and return one or many rows.
        There are a few rules to follow when using GROUP BY:<br>
      <ul>
        <li>Place GROUP BY in the proper clause order - after the WHERE clause
          and before the ORDER BY clause.</li>
        <li> Include all non-aggregate columns in the GROUP BY clause. </li>
        <li> Do not use a column alias in the GROUP BY clause, though table aliases
          are acceptable. </li>
      </ul></td>
  </tr>
  <tr>
    <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Suppose it is necessary to know how many employees occupy each type
        of job within the firm:</p></td>
  </tr>
  <tr>
    <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><span class="programlisting">
    <pre>--Query
SELECT   j.job_desc AS "Job Description",
         COUNT(e.job_id) AS "Nbr in Job"
FROM     employee e
JOIN     jobs j ON e.job_id = j.job_id
GROUP BY j.job_desc

--Results
Job Description                                    Nbr in Job
-------------------------------------------------- -----------
Acquisitions Manager                               4
Business Operations Manager                        1
Chief Executive Officer                            1
Chief Financial Officer                            1
Designer                                           3
Editor                                             3
Managing Editor                                    4
Marketing Manager                                  4
Operations Manager                                 4
Productions Manager                                4
Public Relations Manager                           4
Publisher                                          7
Sales Representative                               3</pre></span> </td>
  </tr>
  <tr>
    <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td valign="top" class="description"><span class="title"> The HAVING clause</span> </td>
  </tr>
  <tr>
    <td> <p> The HAVING clause adds search conditions on the result of the GROUP
        BY clause.HAVING does not affect the rows used to calculate the aggregates;
        it affects only the rows returned by the query. </p></td>
  </tr>
  <tr>
    <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>HAVING works very much like teh WHERE clause The HAVING clause uses
        all the same search conditions as the WHERE clause detailed in Table
        3.9. </p></td>
  </tr>
  <tr>
    <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>For example, to find out which jobs have more than three people:</p></td>
  </tr>
  <tr>
    <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><span class="programlisting">
    <pre>--Query
SELECT   j.job_desc "Job Description",
         COUNT(e.job_id) "Nbr in Job"
FROM     employee e
JOIN     jobs j ON e.job_id = j.job_id
GROUP BY j.job_desc
HAVING   COUNT(e.job_id) &gt; 3

--Results
Job Description                                    Nbr in Job
-------------------------------------------------- -----------
Acquisitions Manager                               4
Managing Editor                                    4
Marketing Manager                                  4
Operations Manager                                 4
Productions Manager                                4
Public Relations Manager                           4
Publisher                                          7</pre>
</span> </td>
  </tr>
  <tr>
    <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p><span class="emphasis">Tip:</span>HAVING should not be used to eliminate
        rows that can be eliminated using the WHERE clause. HAVING conditions
        should always involve aggregate values. </p></td>
  </tr>
  <tr>
    <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td valign="top" class="description"><span class="title"> The ORDER BY clause</span></td>
  </tr>
  A result set can be sorted through the ORDER BY clause , in accordance with
  the database's sort order <span class="emphasis">.</span>The result set may
  be sorted in either ascending ( ASC ) or descending ( DESC ) order. (Ascending
  order is the default.) For example:
  </p>
  </td>
  </tr>
  <tr>
    <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><span class="programlisting">
    <pre>--QUERY
SELECT   e.emp_id "Emp ID",
         rtrim(e.fname) || " " || rtrim(e.lname) "Name",
         j.job_desc "Job Desc"
FROM     employee e,
         jobs j
WHERE    e.job_id = j.job_id
  AND    j.job_desc = 'Acquisitions Manager'
ORDER BY e.fname DESC,
         e.lname ASC

--RESULTS
Emp ID    Name                           Job Desc
--------- ------------------------------ --------------------
M-R38834F Martine Ranc&eacute;                  Acquisitions Manager
MAS70474F Margaret Smith                 Acquisitions Manager
KJJ92907F Karla Jablonski                Acquisitions Manager
GHT50241M Gary Thomas                    Acquisitions Manager</pre></span> </td>
  </tr>
  <tr>
    <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p> After the result set is pared down to meet the search conditions,
        the result set is sorted by the authors' last names in descending order.
        Where the authors' last names are equal, the authors' first names are
        sorted in ascending order.</p></td>
  </tr>
  <tr>
    <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>All implementations discussed here also allow the use of ordinal positions
        in the ORDER_BY clause. The order of the result set may be ordered by
        specifying the integer of the column_position rather than the column
        name or alias. For example, to order by the au_id , au_fname , and finally
        by the au_lname : </p></td>
  </tr>
  <tr>
    <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><span class="programlisting">SELECT au_fname, au_lname, au_id FROM authors
        ORDER BY 3, 1, 2</span> </td>
  </tr>
  <tr>
    <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p> In general, use an ORDER BY clause to control the order of the query
        result set. If no ORDER BY clause is specified, most implementations
        return the data according to the physical order of data within the table
        or according to the order of an index utilized by the query. This can
        cause problems if the index or physical sort order of the data is ever
        changed. Instead, explicitly state the order. </p></td>
  </tr>
  <tr>
    <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td valign="top" class="description"><span class="title"> Microsoft SQL Server
        Syntax and Variations</span></td>
  </tr>
  <tr>
    <td><p>Microsoft offers several variations on the SELECT statement, including
        optimizer hints, the INTO clause, the TOP clause, GROUP BY variations,
        COMPUTE , and WITH OPTIONS . </p></td>
  </tr>
  <tr>
    <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>SELECT . . . INTO<br>
        SELECT select_list INTO new_table_name FROM table_source WHERE clause<br>
        <br>
        The SELECT . . . INTO feature is a somewhat controversial command option
        found only in SQL Server. The <br>
        SELECT . . . INTO command quickly copies the rows and columns queried
        from other table(s) into a new table using a non-logged operation.</p></td>
  </tr>
  <tr>
    <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p> This example creates a table called <span class="emphasis">non_mgr_employees</span> using
        SELECT . . . INTO. The table contains the <br>
        emp_id , first name, and last name of each non-manager from the employee
        table, joined with their job description taken from the jobs table: </td>
        </tr>
        <tr>
		    <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
       </tr>
        <tr>
        <td>

      <pre>--QUERY
	  SELECT   e.emp_id "emp_id",
	           convert(char(25),rtrim(e.fname) + " " + rtrim(e.lname)) "name",
	           substring(j.job_desc,1,30) "job_desc"
	  INTO     non_mgr_employee
	  FROM     employee e
	      JOIN jobs AS j ON e.job_id = j.job_id
	  WHERE    j.job_desc NOT LIKE '%MANAG%'
	  ORDER BY 2,3,1</pre>
	  </td>
	  </tr>
	    <tr>
	      <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
	    </tr>

	  <tr>
	  <td>

        The newly created and loaded table non_mgr_employee now can be queried.
        A simple query returns that data: </p></td>
  </tr>
  <tr>
    <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><span class="programlisting">
    <pre>--QUERY
SELECT   emp_id,
         name,
         job_desc
FROM     non_mgr_emp
ORDER BY 3,2,1

--RESULTS
emp_id    name                      job_desc
--------- ------------------------- ------------------------------
PTC11962M Philip Cramer             Chief Executive Officer
F-C16315M Francisco Chang           Chief Financial Officer
&lt;...edited for brevity...&gt;
PMA42628M Paolo Accorti             Sales Representative
TPO55093M Timothy O'Rourke          Sales Representative</pre>
</span> </td>
  </tr>
  <tr>
    <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p><span class="emphasis">Warning:</span> SELECT . . . INTO should be
        used only in development or non-production code. </p></td>
  </tr>
  <tr>
    <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td valign="top" class="description"><span class="title"> The TOP clause</span></td>
  </tr>
  <tr>
    <td> The TOP clause follows this syntax: </td>
  </tr>
  <tr>
    <td> <span class="programlisting"> SELECT [TOP n [PERCENT] [WITH TIES]] select
        list FROM table_name</span> </td>
  </tr>
  <tr>
    <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p> This command specifies that only the first n rows are to be retrieved
        in the query result set. If a percentage also is specified, only the
        first n percent of the rows are retrieved. The WITH TIES keyword can
        be used only on queries with an ORDER BY<br>
        clause. This variation specifies that additional rows are returned from
        the base result set using the same value in the ORDER BY clause, appearing
        as the last of the TOP rows. <br>
        <br> </td>
  </tr>
  <tr>
    <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td valign="top" class="description"><span class="title"> GROUP BY Variations</span></td>
  </tr>
  <tr>
    <td> GROUP BY in Microsoft SQL Server supports the ALL , WITH CUBE , and
      WITH ROLLUP variations:<br>
      <br>
      [ GROUP BY [ALL] group_by_expression [,...n] [ WITH { CUBE | ROLLUP } ]
      ] <br>
      <br>
      The ALL variation forces the result set to include all groups, even those
      that do not have any rows matching the filters in the <br>
      WHERE clause. ALL cannot be used with CUBE or ROLLUP . CUBE specifies that
      additional summary rows for every combination of group and subgroup should
      be retrieved with the result set. ROLLUP functions similarly to CUBE except
      that it returns groups in a summarized hierarchical order &#8212; from
      lowest level to highest level in the group.
      </p> </td>
  </tr>
  <tr>
    <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td valign="top" class="description"><span class="title"> The COMPUTE Clause</span></td>
  </tr>
  <tr>
    <td> The COMPUTE clause generates totals that appear as additional summary
      columns at the end of the result set. The <br>
      COMPUTE BY clause generates control breaks and subtotals in the result
      set. Both COMPUTE BY and <br>
      COMPUTE can be specified in the same query: <br>
      <br>
      [ COMPUTE { { AVG | COUNT | MAX | MIN | STDEV | STDEVP |VAR | VARP | SUM
      } (expression) } [,...n] [ BY expression [,...n] ] ]
      </p> </td>
  </tr>
  <tr>
    <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p> The arguments ( AV , COUNT , MAX , MIN , STDEV , STDEVP , VAR , VARP
        , SUM ) specify the aggregation to be performed by the COMPUTE clause.
        The expression value is typically a column name. The BY expression value
        can be one or more columns shown in the queries' ORDER BY clause.COMPUTE
        appears in a query after the ORDER BY clause. </td>
  </tr>
  <tr>
    <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td valign="top" class="description"><span class="title"> The OPTION clause</span></td>
  </tr>
  <tr>
    <td> The OPTION clause is the last clause that may appear in a Microsoft
      SQL Server query. It specifies that a query hint <br>
      should be used throughout the entire query. Query hints are a non-ANSI-standard
      method of overriding the default processing of a query. Query hints and
      the complete syntax and usage of OPTION are beyond the scope of this book,
      but may be found in SQL Server documentation. <br>
      </p> </td>
  </tr>
  <tr>
    <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td valign="top" class="description"><span class="title"> MySQL Syntax and
        Variations</span> </td>
  </tr>
  <tr>
    <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>MySQL extensions include changes to the default SELECT keyword, partial
        JOIN support, the LIMIT clause, and the PROCEDURE clause. </p></td>
  </tr>
  <tr>
    <td><p>The first extension to the default SELECT clause is STRAIGHT_ JOIN
        . STRAIGHT_JOIN forces the optimizer to join tables in the exact order
        they appear in the FROM clause. SQL_SMALL_RESULT and SQL_BIG_RESULT can
        be used when the query has a GROUP BY clause or a DISTINCT clause to
        tell the optimizer to expect a small or large result set, respectively.
        Since MySQL builds a temporary table when a query has a DISTINCT or GROUP
        BY clause, these optional clauses tell MySQL to build a fast temporary
        table in memory (for SQL_SMALL_RESULT ) and a slower, disk-based temporary
        table (for SQL_BIG_RESULT ) to process the worktable. HIGH_PRIORITY gives
        the query a higher priority than statements that modify data within the
        table. It should only be used for special, high-speed queries. The LIMIT
        clause constrains the number of rows returned by the query, starting
        at the offset_record and returning number_of_rows . If only one integer
        is supplied, this number is assumed to be the number of records wanted,
        and a default offset of 0 is assumed. </p></td>
  </tr>
  <tr>
    <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The SELECT . . . INTO OUTFILE `file_name' clause writes the result
        set of the query to a file on the host filesystem. The file_name must
        not already exist. The syntax SELECT . . . INTO DUMPFILE writes a single
        continuous line of data without column terminations, line terminations,
        or escape characters. This option is used mostly for blob files. </p></td>
  </tr>
  <tr>
    <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>MySQL supports only these types of JOIN syntax: </p></td>
  </tr>
  <tr>
    <td> <span class="programlisting">[CROSS JOIN] INNER JOIN STRAIGHT_JOIN LEFT
      [OUTER] JOIN NATURAL LEFT [OUTER] JOIN</td>
  </tr>
  <tr>
    <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td valign="top" class="description"><span class="title"> Oracle Syntax and
        Variations</span></td>
  </tr>
  <tr>
    <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><span class="programlisting">
    <pre>SELECT {[ALL] [DISTINCT] | [UNIQUE]}...
{columns_and_expressions_list} [,...n] AS alias
[INTO {variable[,...n] | record}]
FROM {[table_name [@database_link]| view_name | snapshot_name]
   | subquery [WITH {READ ONLY | CHECK OPTION [CONSTRAINT constraint_name]}]
   | TABLE {(nested_tbl_column)}
      [PARTITION {partition_name}]
      [SUBPARTITION {subpartition_name}
         [SAMPLE [BLOCK] [sample_percentage]}
WHERE
[[START WITH clause] CONNECT BY clause]
GROUP BY...
[ORDER BY... [NULLS FIRST | NULLS LAST] |
 FOR UPDATE [OF [schema.]table[,...n]] [NOWAIT] ]</pre></span> </td>
  </tr>
  <tr>
    <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Oracle allows several extensions to SELECT support-added functionality
        within the server. For example, since nested tables and partitioned tables
        both can be created (see CREATE TABLE ), the SELECT statement allows
        queries from those specifically named structures. (The PARTITION clause
        is not needed to query from the default partition.) </p></td>
  </tr>
  <tr>
    <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The SAMPLE clause tells Oracle to select records from a random sampling
        of rows within the result set, rather than from the entire table. The
        SAMPLE BLOCK clause tells Oracle to use block sampling rather than row
        sampling. The sampling percentage, telling Oracle the total block or
        row count to be included in the sample, may be anywhere between .000001
        to 99. Sampling may be used only on single-table queries. </p></td>
  </tr>
  <tr>
    <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p><span class="emphasis">Tip:</span> The SELECT . . . INTO syntax is
        usable only in PL/SQL code and allows the SELECT statement to assign
        values to variables. </p></td>
  </tr>
  <tr>
    <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>When querying a nested table, the FROM TABLE nested_table_column clause
        must be used. The @database_link clause allows the query to access tables
        stored in other databases and on other servers when those databases and
        servers have been declared as a <span class="emphasis">db_link</span>.
        (Refer to the vendor documentation for more information on db_link.) </p></td>
  </tr>
  <tr>
    <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The NULL FIRST and NULL LAST options to the ORDER BY clause specify
        that the result set order rows containing nulls end should appear either
        first or last, respectively. </p></td>
  </tr>
  <tr>
    <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Oracle allows the specification of result sets in a hierarchical order.
        These so-called hierarchical queries have a number of rules and unique
        behaviors. Refer to the vendor documentation for complete rules on using
        this type of query. The START WITH clause is essential for hierarchical
        queries and specifies the root rows of a hierarchy. The CONNECT BY clause
        describes the relationship between parent and child rows in the hierarchy. </p></td>
  </tr>
  <tr>
    <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The FOR UPDATE OF clause exclusively locks the row returned by the
        query. It should be followed immediately by an UPDATE . . . WHERE command,
        COMMIT , or ROLLBACK . The NOWAIT option tells Oracle not to wait if
        that record is already locked. Instead, the query terminates and immediately
        returns to the user. </p></td>
  </tr>
  <tr>
    <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td valign="top" class="description"><span class="title"> PostgreSQL Syntax
        and Variations</span></td>
  </tr>
  <tr>
    <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><span class="programlisting">
    <pre>SELECT...
[INTO [TEMPORARY | TEMP] [TABLE] new_table_name]
FROM...
WHERE...
[FOR UPDATE [OF class_name[,...n]]
[LIMIT {count | ALL} [offset [,number_of_records]] ]</pre></span> </td>
  </tr>
  <tr>
    <td valign="top" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>PostgreSQL allows the creation of a new table using the SELECT . .
        . INTO syntax, which is essentially the same as that supported by Microsoft
        SQL Server. It helps the FOR UPDATE clause to exclusively lock records
        selected by the query. It also supports the LIMIT clause, similar to
        that of MySQL, to constrain the number of rows returned by the query. </p></td>
  </tr>
  </table>
</div>
<div id="SET CONNECTION"><table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td Width="50%" align="left" class="name" valign="top">SET CONNECTION
  <td Width="50%" align="right"class="name" valign="top">SQL-connection&nbsp;&nbsp;</td>
</tr></table>
<table width="100%" cellspacing="0" cellpadding="0" border="0">

  <tr>
    <td><p>The SET CONNECTION statement allows users to switch between several open connections on one or more database servers. </p>
    </td>
  </tr>
  <tr>
        <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
  <td>
  <table border="1" >
<tr><th>Vendor</th>
<th>Command</th></tr>
<tr><td>SQL Server</td><td>Supported, with limitations</td></tr><tr><td>MySQL</td><td>Not supported</td></tr><tr><td>Oracle</td><td>Not supported</td></tr><tr><td>PostgreSQL</td><td>Not supported</td></tr></table></span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
SET CONNECTION {DEFAULT | connection_name}</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>This command does not end a connection. Instead, it switches from the current connection to the connection named in the command, or to the current connection using the DEFAULT clause. When switching between connections, the old connection becomes dormant (without committing any changes), while the new connection becomes active. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The CONNECT command must be used to create a new connection; the DISCONNECT command is used to terminate one. </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">
Microsoft SQL Server Syntax and Variations</span></td>
  </tr>

  <tr>
    <td><p>Microsoft SQL Server supports SET CONNECTION only in Embedded-SQL (ESQL), but not within its ad hoc querying tool, SQL Query Analyzer. It supports the full SQL99 syntax. </p>
    </td>
  </tr>
<tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="example"><span class="title">
  Example</span>
</td>
</tr>
   <tr>
    <td><p>Here is a full ESQL program in SQL Server that shows CONNECT , DISCONNECT , and SET CONNECTION : </p>
    </td>
  </tr>
  <tr>
        <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><span class="programlisting">
    <pre>EXEC SQL CONNECT TO chicago.pubs AS chicago1 USER sa;
EXEC SQL CONNECT TO new_york.pubs AS new_york1 USER read-only;
// opens connections to the servers named "chicago" //
//   and "new_york"//

EXEC SQL SET CONNECTION chicago1;
EXEC SQL SELECT name FROM employee INTO :name;
// sets the chicago1 connection as active and performs work //
//   within that session //

EXEC SQL SET CONNECTION new_york1;
EXEC SQL SELECT name FROM employee INTO :name;
// sets the new_york1 connection as active and performs work //
//   within that session //

EXEC SQL DISCONNECT ALL;
// Terminates all sessions.  You could alternately use two //
//   DISCONNECT commands, one for each named connection. //</pre>
</span>
    </td>
  </tr>
</table>
</div>

<div id="SET ROLE"><table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td Width="50%" align="left" class="name" valign="top">SET ROLE
  <td Width="50%" align="right"class="name" valign="top">SQL-session&nbsp;&nbsp;</td>
</tr></table>
<table width="100%" cellspacing="0" cellpadding="0" border="0">
   <tr>
    <td><p>The SET ROLE command enables and disables specific security roles for the current session. Sessions are created using the CONNECT statement, while roles are created using the CREATE ROLE statement. </p>
    </td>
  </tr>

  <tr>
        <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
  <td>
  <table border="1" >
<tr><th>Vendor</th>
<th>Command</th></tr>
<tr><td>SQL Server</td><td>Not supported</td></tr><tr><td>MySQL</td><td>Not supported</td></tr><tr><td>Oracle</td><td>Supported, with variations</td></tr><tr><td>PostgreSQL</td><td>Not supported</td></tr></table></td>
</tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">SQL99 Syntax and Description</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
SET ROLE {NONE | role_name}</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The session is opened using the CONNECT statement. Once a user session is initiated, issuing the SET ROLE statement grants that session a set of privileges associated with a role. The SET ROLE command can be issued only outside of a transaction. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>SET ROLE NONE assigns the current session to a NULL role. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>When a role is assigned to the currently active user session, a character string, database variable, or even a system function such as CURRENT_ROLE or SYSTEM_ROLE may be used. In any case, the value specified must be a valid role name. </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">
Oracle Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>SET ROLE {role_name [IDENTIFIED BY password] [,...n]
| [ALL [EXCEPT role_name [,...]]
|  NONE;</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>When a user initiates a connection, Oracle explicitly assigns the privileges that are roles to the user. The role(s) under which the session is operating can be changed with the SET ROLE command. Oracle uses the MAX_ENABLED_ROLES initialization parameter to control the maximum number of roles that can be opened concurrently. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The role_name specified must be a valid role name already created within Oracle. Any roles not specified are unavailable for the current session. If the role_name has a password, it must be listed using the IDENTIFIED BY password clause. Multiple roles are identified by placing a comma between each. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The SET ROLE ALL statement enables all roles that are granted to the current session, including roles that are granted through other roles; other roles may be exempted using the EXCEPT clause. SET ROLE ALL cannot be used when a password must be specified. Roles with passwords may be accessed only through the statement SET ROLE role_name IDENTIFIED BY password . </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The SET ROLE NONE statement disables all roles, including the default role. </p>
    </td>
  </tr>

<tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="example"><span class="title">
  Example</span>
</td>
</tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>To enable the specific roles <span class="emphasis">read_only </span>and <span class="emphasis">updater</span>, identified by the passwords <span class="emphasis">editor </span>and <span class="emphasis">red_marker </span>, respectively, for the current session: </p>
    </td>
  </tr>
  <tr>
        <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
 </tr>
  <tr>
<td>
<span class="programlisting">SET ROLE read_only IDENTIFIED BY editor, updater IDENTIFIED BY red_marker;</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>To enable all roles, except the <span class="emphasis">read_write </span>role: </p>
    </td>
  </tr>
  <tr>
        <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
 </tr>
  <tr>
<td>
<span class="programlisting">SET ROLE ALL EXCEPT read_write;</span>
    </td>
  </tr>
</table>
</div>

<div id="SET TIME ZONE"><table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td Width="50%" align="left" class="name" valign="top">SET TIME ZONE
  <td Width="50%" align="right"class="name" valign="top">SQL-session&nbsp;&nbsp;</td>
</tr></table>
<table width="100%" cellspacing="0" cellpadding="0" border="0">

  <tr>
    <td><p>The SET TIME ZONE statement changes the current session's time zone if it needs to be different from the default time zone. </p>
    </td>
  </tr><tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr><tr>
  <td><table border="1" >
<tr><th>Vendor</th>
<th>Command</th></tr>
<tr><td>SQL Server</td><td>Not supported</td></tr><tr><td>MySQL</td><td>Not supported</td></tr><tr><td>Oracle</td><td>Not supported</td></tr><tr><td>PostgreSQL</td><td>Supported, with variations</td></tr></table></td>
</tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">SQL99 Syntax and Description</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>SET TIME ZONE {'timezone' | LOCAL | DEFAULT
| INTERVAL {+ | -}'00:00' HOUR TO MINUTE};</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Like most SET commands, SET TIME ZONE can be executed only outside of an explicit transaction. The LOCAL clause resets the current-session time values to those of the default time zone for the server. Otherwise, an interval value can be set to increase (with +) or decrease (with -) over the default time. </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">
PostgreSQL Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
SET TIME ZONE {'timezone' | LOCAL | DEFAULT | INTERVAL {+ | -}'00:00' HOUR TO MINUTE};</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>PostgreSQL allows a session's time value to be set to the server default by using either the LOCAL or DEFAULT clause. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The value specified for time zone is dependent on the operating system. For example, `PST8PDT' is a valid time zone for California on Linux systems, while `Europe/Rome' is a valid time zone for Italy on Linux and other systems. If an invalid time zone is specified, the command sets the time zone to Greenwich Mean Time (GMT). </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The time zone also may be set as an interval of the default server time zone. </p>
    </td>
  </tr>
<tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="example"><span class="title">
  Example</span>
</td>
</tr>
  <tr>
    <td><p>In the following example, the time zone is advanced three hours over the current default time zone: </p>
    </td>
  </tr><tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr><tr>
<td>
<span class="programlisting">SET TIME ZONE INTERVAL +'03:00' HOUR TO MINUTE;</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Next, the current time for the current session is set back by four-and-a-half hours: </p>
    </td>
  </tr><tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr><tr>
<td>
<span class="programlisting">SET TIME ZONE INTERVAL -'04:30' HOUR TO MINUTE;</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Finally, the time for the current session is returned to the default: </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr><tr>
<td>
<span class="programlisting">SET TIME ZONE LOCAL;</span>
</td>
</tr>
    </td>
  </tr>
</table>
</div>


<div id="SET TRANSACTION"><table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td Width="50%" align="left" class="name" valign="top">SET TRANSACTION
  <td Width="50%" align="right"class="name" valign="top">SQL-session&nbsp;&nbsp;</td>
</tr></table>
<table width="100%" cellspacing="0" cellpadding="0" border="0">

  <tr>
    <td><p>The SET TRANSACTION statement controls many characteristics of a data modification, such as read/write or its isolation level. </p>
    </td>
  </tr> <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr><tr>
  <td><table border="1" >
<tr><th>Vendor</th>
<th>Command</th></tr>
<tr><td>SQL Server</td><td>Supported, with variations</td></tr><tr><td>MySQL</td><td>Not supported</td></tr><tr><td>Oracle</td><td>Supported, with limitations</td></tr><tr><td>PostgreSQL</td><td>Supported</td></tr></table></td>
</tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">SQL99 Syntax and Description</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>SET [LOCAL] TRANSACTION { {READ ONLY | READ WRITE}[,...]
| ISOLATION LEVEL
  {READ COMMITTED
  | READ UNCOMMITTED
  | REPEATABLE READ
  | SERIALIZABLE}[,...]
| DIAGNOSTIC SIZE INT};</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>When issued, this command is outside the context of a transaction but applies to the next valid transaction. More than one option may be applied with this command, each separated by a comma. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The transaction settings may be applied only to the local server via the LOCAL command. Otherwise, the transaction settings are assumed to apply regardless of where the transaction is run. This option is new to SQL99. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>A transaction also can be specified as READ ONLY or READ WRITE . The DIAGNOSTIC SIZE clause, followed by an integer, designates the specific number of error messages to capture for a transaction. The GET DIAGNOSTICS statement retrieves this information. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The ISOLATION LEVEL clause controls a number of behaviors in a transaction concerning concurrent transactions. Isolation levels control how transactions behave with regards to dirty reads , non-repeatable reads , and phantom records : </p>
    </td>
  </tr>

<tr><td><ul>
<li>Dirty reads: Occur when a transaction reads the altered records of another transaction before the other transaction has completed. This allows a data modification to occur on a record that might not be committed to the database. </li>

<li>Non-repeatable reads: Occur when one transaction reads a record while another modifies it. So, if the first transaction attempts to reread the record, it can't find it. </li>

<li>Phantom records: Occur when a transaction reads a group of records, but a data modification adds or changes the data so that more records satisfy the first transaction.
</li>
</ul>
</td>
</tr>


  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p> Setting the isolation level impacts these  anomalies as depicted in Table 3.10</p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Isolation Level and Anomaly Impact</p>
    </td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
  <tr>
  <td>
<table width="75%" border="1">
  <tr>
    <th>Isolation Level</th>
    <th>Dirty Reads</th>
    <th>Non-Repeatable Reads</th>
    <th>Phantom Records</th>
  </tr>
  <tr>
    <td>READ COMMITTED<br></td>
    <td>No</td>
    <td>Yes</td>
    <td>Yes</td>
  </tr>
  <tr>
    <td>READ UNCOMMITTED</td>
    <td>Yes</td>
    <td>Yes</td>
    <td>Yes</td>
  </tr>
  <tr>
    <td> REPEATABLE READ</td>
    <td>No</td>
    <td>No</td>
    <td>Yes</td>
  </tr>
  <tr>
    <td>SERIALIZABLE</td>
    <td>No</td>
    <td>No</td>
    <td>No</td>
  </tr>
</table>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
    <tr>
    <td><p>For SQL99, SERIALIZABLE is the default isolation level. READ WRITE transactions may not be READ UNCOMMITTED . </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">

Microsoft SQL Server Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>SET TRANSACTION ISOLATION LEVEL
{READ COMMITTED
| READ UNCOMMITTED
| REPEATABLE READ
| SERIALIZABLE}</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>READ COMMITTED is the SQL Server default, as opposed to serializable as the default in SQL99. The isolation level is established for the duration of the entire session, not just the transaction as in SQL99. </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">
Oracle Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
SET TRANSACTION READ ONLY;</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Oracle does not support the full syntax of the SET TRANSACTION statement, and its implementation of READ ONLY differs somewhat as well. Oracle only supports READ COMMITTED and SERIALIZABLE . READ COMMITTED is the default behavior. In Oracle, this command starts a transaction in SERIALIZABLE isolation level. Oracle allows only the SELECT commands when the following commands are set: READ ONLY , ALTER SESSION , ALTER SYSTEM , LOCK TABLE , and SET ROLE . </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">
PostgreSQL Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
SET TRANSACTION ISOLATION LEVEL {READ COMMITTED | SERIALIZABLE};</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>PostgreSQL does not support the full syntax of the SET TRANSACTION statement. In PostgreSQL, SET TRANSACTION ISOLATION LEVEL READ COMMITTED specifies that the current transaction's read-only rows committed before the transaction began. This is the default. SERIALIZABLE , which is the ANSI-default isolation level, specifies that the current transaction's read-only rows committed before the first data modification in the batch is executed. </p>
    </td>
  </tr>
</table>
</div>

<div id="START TRANSACTION"><table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td Width="50%" align="left" class="name" valign="top">START TRANSACTION
  <td Width="50%" align="right"class="name" valign="top">SQL-transaction&nbsp;&nbsp;</td>
</tr></table>
<table width="100%" cellspacing="0" cellpadding="0" border="0">

  <tr>
    <td><p>New in SQL99, the START TRANSACTION statement allows all the functions of SET TRANSACTION to be performed and allows a new transaction to be initiated. </p>
    </td>
  </tr><tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
  <td>
  <table border="1" >
<tr><th>Vendor</th>
<th>Command</th></tr>
<tr><td>SQL Server</td><td>Not supported; see BEGINTRAN later</td></tr><tr><td>MySQL</td><td>Not supported</td></tr><tr><td>Oracle</td><td>Not supported</td></tr><tr><td>PostgreSQL</td><td>Not supported; see BEGINTRAN later</td></tr></table></td>
</tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">SQL99 Syntax and Description</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>START TRANSACTION { {READ ONLY | READ WRITE}[,...]
| ISOLATION LEVEL
  {READ COMMITTED
  | READ UNCOMMITTED
  | REPEATABLE READ
  | SERIALIZABLE}[,...]
| DIAGNOSTIC SIZE INT};</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The only difference between SET and START is that SET is considered outside of the current transaction, while START is considered the marking of a new transaction. </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">
BEGIN TRANSACTION</span>
  </td>
  </tr>
  <tr>
    <td><p>The command BEGIN TRANSACTION provides similar functionality to START TRANSACTION . Both Microsoft SQL Server and PostgreSQL support BEGIN TRANSACTION , though they have slight variations in their syntax. Oracle supports implicit, but not explicit, transactions. MySQL doesn't support atomic transactions at all. BEGIN TRANSACTION declares an explicit transaction, but it does not set isolation levels. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The Microsoft SQL Server syntax is: </p>
    </td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
  <tr>
<td>
<span class="programlisting">
<pre>BEGIN TRAN[SACTION] [transaction_name | @transaction_variable
[WITH MARK [ 'log_description' ] ] ]</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Microsoft SQL Server allows a name to be assigned to a transaction or to reference transactions using a variable. It does not affect or add to functionality. When nesting transactions, only the outermost BEGIN . . . COMMIT or BEGIN . . . ROLLBACK pair should reference the transaction name (if it has one). </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The WITH MARK option logs the transaction to the SQL Server event log. By specifying WITH MARK `log_description' , a descriptive string may be added for the event to be logged. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The PostgreSQL syntax is: </p>
    </td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
  <tr>
<td>
<span class="programlisting">BEGIN [ WORK | TRANSACTION ]</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>PostgreSQL normally runs in autocommit mode where each data modification or query is its own transaction. PostgreSQL normally applies an implicit COMMIT or ROLLBACK at the end of the transaction. Using the BEGIN statement allows the next COMMIT or ROLLBACK to be declared explicitly. </p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>
<span class="emphasis">Warning:</span>  Be sure to issue BEGIN   in a pair with either COMMIT  or ROLLBACK . Otherwise, the DBMS does not complete the command(s) until it encounters COMMIT or ROLLBACK  . This could lead to potentially huge transactions with unpredictable results on the data.
</p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Manually coded transactions are much faster in PostgreSQL than are autocommitted transactions. The SET TRANSACTION ISOLATION LEVEL should be set to SERIALIZABLE just after the BEGIN statement to bolster the transaction isolation. There could be many data-modification statements ( INSERT , UPDATE , DELETE ) within a BEGIN . . . COMMIT block. When the COMMIT command is issued, either all or none of the transactions takes place, depending on the success or failure of the command. </p>
    </td>
  </tr>


<tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="example"><span class="title">
  Example</span>
</td>
</tr>
  <tr>
    <td><p>In the following example, the three INSERT statements all be treated as a single transaction: </p>
    </td>
  </tr>
  <tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
  <tr>
<td>
<span class="programlisting">
<pre>BEGIN TRANSACTION
   INSERT INTO sales VALUES('7896','JR3435','Oct 28 2001',25,
   'Net 60','BU7832')

   INSERT INTO sales VALUES('7901','JR3435','Oct 28 2001',17,
   'Net 60','BU7832')

   INSERT INTO sales VALUES('7907','JR3435','Oct 28 2001',6,
   'Net 60','BU7832')

COMMIT
GO</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>However, the entire group of transactions would fail, for example, if a primary key restraint is in any one of the INSERT statements. </p>
    </td>
  </tr>
</table>
</div>

<div id="TRUNCATE TABLE"><table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td Width="50%" align="left" class="name" valign="top">TRUNCATE TABLE
  <td Width="50%" align="right"class="name" valign="top">SQL-data&nbsp;&nbsp;</td>
</tr></table>
<table width="100%" cellspacing="0" cellpadding="0" border="0">

  <tr>
    <td><p>The TRUNCATE TABLE command is a non-ANSI statement that removes all rows from a table without logging the individual row deletes. It is a very handy command because it quickly erases all the records in a table without altering the table structure, while taking very little space in the redo logs or transaction logs. However, it has a dark side; since it is not logged, it cannot be recovered or backed up. </p>
    </td>
  </tr> <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr><TR>
  <TD><table border="1" >
<tr><th>Vendor</th>
<th>Command</th></tr>
<tr><td>SQL Server</td><td>Supported</td></tr><tr><td>MySQL</td><td>Not supported</td></tr><tr><td>Oracle</td><td>Supported</td></tr><tr><td>PostgreSQL</td><td>Supported</td></tr></table></td>
</tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">SQL99 Syntax and Description</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
TRUNCATE TABLE name</span>
</td>
</tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The TRUNCATE TABLE statement has the same effect as a DELETE statement with no WHERE clause; both erase all rows in a given table. However, there are two important differences. TRUNCATE TABLE is faster, and it is non-logged, meaning it cannot roll back if issued in error. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Typically, TRUNCATE TABLE does not activate triggers and does not function when foreign keys are in place on a given table. </p>
    </td>
  </tr>
<tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="example"><span class="title">
  Example</span>
</td>
</tr>
  <tr>
    <td><p>This example removes all data from the publishers table: </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><span class="programlisting">TRUNCATE TABLE publishers</span>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">
Oracle Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>TRUNCATE { CLUSTER [owner.]cluster
   | TABLE [owner.]table [{PRESERVE | PURGE} SNAPSHOT LOG]}
[{DROP | REUSE} STORAGE]</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Oracle allows a table or an indexed cluster (but not a hash cluster) to be truncated. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>When truncating a table, Oracle allows the option of preserving or purging the snapshot log, if one is defined on the table. PRESERVE maintains the snapshot log when the master table is truncated, while PURGE clears out the snapshot log. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>If the DROP STORAGE clause is added, the disk space freed by the deleted rows is deallocated. If the REUSE STORAGE clause is added, the space of the deleted rows allocated to the table or cluster is left in place. </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">
Microsoft SQL Server and PostgreSQL Note</span></td>
  </tr>
  <tr>
    <td><p>Both of these implementations support the SQL99 default syntax. </p>
    </td>
  </tr>
</table>
</div>

<div id="UPDATE"><table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td Width="50%" align="left" class="name" valign="top">UPDATE
  <td Width="50%" align="right"class="name" valign="top">SQL-data&nbsp;&nbsp;</td>
</tr></table>
<table width="100%" cellspacing="0" cellpadding="0" border="0">

  <tr>
    <td><p>The UPDATE command changes existing data in a table. </p>
    </td>
  </tr><tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
  <td>
  <table border="1" >
<tr><th>Vendor</th>
<th>Command</th></tr>
<tr><td>SQL Server</td><td>Supported, with variations</td></tr><tr><td>MySQL</td><td>Supported, with variations</td></tr><tr><td>Oracle</td><td>Supported, with variations</td></tr><tr><td>PostgreSQL</td><td>Supported</td></tr></table></td>
</tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">SQL99 Syntax and Description</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>UPDATE {table_name | view_name}
SET {column_name | variable_name} = {DEFAULT | expression} [,...n]
WHERE conditions</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>As with the DELETE statement, an UPDATE command is seldom issued without a WHERE clause, since the statement affects every row in the entire table. </p>
    </td>
  </tr>

  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>
<span class="emphasis">Warning:</span> It is good practice to issue a SELECT  command using the same WHERE clause before issuing the actual
UPDATE  statement. This checks all rows in the result set before actually performing the UPDATE
. Whatever rows are returned by the SELECT are modified by the UPDATE.
</p>
    </td>
  </tr>

<tr>
      <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="example"><span class="title">
  Example</span>
</td>
</tr>

  <tr>
    <td><p>A basic UPDATE statement without a WHERE clause looks like this: </p>
    </td>
  </tr><tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
<td>
<span class="programlisting">UPDATE authors SET contract = 0</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Without a WHERE clause, all authors in the authors table have their contract status set to (meaning they don't have a contract any more). Similarly, values can be adjusted mathematically with an UPDATE statement: </p>
    </td>
  </tr><tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr><tr>
<td>
<span class="programlisting">UPDATE titles SET price = price * 1.1</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>This UPDATE statement would increase all book prices by 10%. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Adding a WHERE clause to an UPDATE statement allows records in the table to be modified selectively: </p>
    </td>
  </tr><tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr><tr>
<td>
<span class="programlisting">
<pre>UPDATE titles
SET price = price * 1.1</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>This query makes two changes to any record of the type `popular_com' . The command increases their price by 15% and alters their type to `pers_comp' . </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>There are times when it's required to update values in a given table based on the values stored in another table. For example, if it is necessary to update the publication date for all the titles written by a certain author, it is also necessary to find the author and list of titles first through subqueries: </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><span class="programlisting">
    <pre>UPDATE titles
SET    pubdate = 'Jan 01 2002'
WHERE  title_id IN
    (SELECT title_id
     FROM   titleauthor
     WHERE  au_id IN
         (SELECT au_id
          FROM   authors
          WHERE  au_lname = 'White'))</pre>
</span>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">
Microsoft SQL Server Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>UPDATE {table_name | view_name} [WITH (table_hint [,...n])]
SET {column_name | variable_name} = {DEFAULT | expression | NULL} [,...n]
[FROM {table [,...n]}]
WHERE {conditions | CURRENT OF [GLOBAL] cursor_name}
[OPTION (query_hint [,...n])]</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Microsoft SQL Server is capable of updating both views and tables. Table- and query-level optimizer hints may be declared using the WITH table_hint and OPTION clauses. Optimizer hints override the default functionality of the query optimizer. Consult the vendor documentation for a full discussion of optimizer hints. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>Microsoft SQL Server supports the FROM clause in an UPDATE statement. The chief benefit of this variation is much easier multitable joins. The following is a sample of table joins using both styles of syntax: </p>
    </td>
  </tr><tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr><tr>
<td>
<span class="programlisting">
<pre>-- ANSI style
UPDATE titles
SET    pubdate = GETDATE(  )
WHERE  title_id IN
    (SELECT title_id
     FROM   titleauthor
     WHERE  au_id IN
         (SELECT au_id
          FROM   authors
          WHERE  au_lname = 'White'))

-- Microsoft Transact-SQL style
UPDATE  titles
SET     pubdate = GETDATE(  )
FROM    authors a,
        titleauthor t2
WHERE   a.au_id     = t2.au_id
    AND t2.title_id = titles.title_id
    AND a.au_lname  = 'White'</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>To perform the update using the Transact-SQL style is simply a matter of three table joins between <span class="emphasis">authors </span>, <span class="emphasis">titles </span>, and <span class="emphasis">titleauthor </span>. But to perform the same operation using ANSI-compliant code, first the <span class="emphasis">au_id</span> in <span class="emphasis">author </span>must be found and passed up to the <span class="emphasis">titleauthors </span>table, where the <span class="emphasis">title_id </span>must be identified and then passed up to the main update statement. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The clause WHERE CURRENT OF cursor_name tells SQL Server, when used in combination with a cursor, to update only the single record where the cursor is currently positioned. The cursor may be a global or local cursor as designated by the keyword GLOBAL . </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>This example updates the state column for the first 10 authors from the authors table: </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>UPDATE authors SET state = 'ZZ' FROM (SELECT TOP 10 * FROM authors ORDER BY au_lname) AS t1 WHERE authors.au_id = t1.au_id</p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">
MySQL Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>UPDATE authors
SET state = 'ZZ'
FROM (SELECT TOP 10 * FROM authors ORDER BY au_lname) AS t1
WHERE authors.au_id = t1.au_id</pre>


</refsect1>
<refsect1 id="ch03-_Toc484079648">
<title>MySQL Syntax and Variations</title>


<pre>UPDATE [LOW PRIORITY] table_name
SET {column_name | variable_name} = {DEFAULT | expression}
WHERE conditions
[LIMIT integer]</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>MySQL supports the SQL99 standard with two variations: the LOW PRIORITY clause and the LIMIT clause. The LOW PRIORITY clause tells MySQL to delay the execution of the UPDATE statement until no other client is reading from the table. The LIMIT clause restricts the UPDATE action to a specific number of rows as designated by the integer value. </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">
Oracle Syntax and Variations</span></td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td>
<span class="programlisting">
<pre>UPDATE [schema.]{view_name | snapshot_name
   | table_name [@database_link]
      {[PARTITION partition_name] | [SUBPARTITION subpartition_name]}
   | subquery [WITH {[READ ONLY]
      | [CHECK OPTION [CONSTRAINT constraint_name] ]
SET {column [,...] = {expression [,...n] | subquery} | VALUE value}
WHERE conditions | CURRENT OF cursor_name}
RETURNING expression [,...n] INTO variable [,...n];</pre>
</span>
</td>
</tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The Oracle implementation of UPDATE allows updates against views, snapshots, and tables in an allowable schema. When updating tables, the table can be a local table or one made available via @dblink . Updates always occur against the partition; however, the UPDATE command supports updates against a named PARTITION or SUBPARTITION , if preferred. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>When updating against a subquery, the WITH clause becomes available. The WITH READ ONLY clause specifies that the subquery cannot be updated. The WITH CHECK OPTION tells Oracle to abort any changes to the updated table that would not appear in the result set of the subquery. The CONSTRAINT subclause tells Oracle to further restrict changes based upon a specific constraint. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>The SET VALUE clause allows the user to set the entire row value for any table datatype values. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>In Oracle, the WHERE CURRENT OF clause indicates that the UPDATE should be performed only on the current record within the cursor context. </p>
    </td>
  </tr>
  <tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
  </tr>
  <tr>
    <td><p>RETURNING retrieves the rows affected by the command. When used for a single-row update, the values of the row can be stored in PL/SQL variables and bind variables. When used for a multirow delete, the values of the rows are stored in bind arrays. The INTO keyword indicates that the updated values should be stored in the variables list. </p>
    </td>
  </tr>
<tr>
    <td valign="top" colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
    <td valign="top" colspan="2" class="description"><span class="title">
PostgreSQL Syntax and Variations</span></td>
  </tr>
  <tr>
    <td><p>PostgreSQL supports the SQL99 standard. Refer to Section , earlier, for a full description of the UPDATE command. </p>
    </td>
  </tr>
</table>
</div>
  </body>
  </html>