Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Microsoft Jet Database Engine wikipedia , lookup
Entity–attribute–value model wikipedia , lookup
Clusterpoint wikipedia , lookup
Extensible Storage Engine wikipedia , lookup
Microsoft SQL Server wikipedia , lookup
Oracle Database wikipedia , lookup
Open Database Connectivity wikipedia , lookup
Database model wikipedia , lookup
Oracle Database Sequences and Alpha Five Data Access Objects Auto-Increment Columns Some databases implement a column property called auto-increment (typically a number) to automatically generate unique key values for newly inserted table rows. You may omit the value from the SQL INSERT statement VALUES list or set it to NULL. In some cases, the database may allow you to insert a specific value provided that it is unique for the table. Oracle Sequences Oracle uses a different approach to generating unique keys. The objects that generate unique keys are called SEQUENCES. A sequence is a database object that provides a unique number and keeps track of the current value. Let‟s say that we want to create a new sequence called MySequence with an initial value of 1. New values should be created by adding 10 to the original value. The maximum value generated is limited only by the size of the maximum possible number. CREATE SEQUENCE MySequence START WITH 1 INCREMENT BY 10 NOMAXVALUE To see the current value of the sequence we would execute the following query: SELECT MySequence.currval from dual Notes: 1. We reference the currval property of MySequence to find the current value. 2. dual is a pseudo table used in Oracle when you want to select a single value or evaluate an expression. To generate a new value for the sequence we would include the expression below: MySequence.nextval Note: The nextval property returns the next value for the sequence and handles incrementing the value at the same time. Kurt Rayner Page 1 4/15/2008 Oracle Database Sequences and Alpha Five Data Access Objects Manually Specifying a Sequence Value on Insert There are a couple of ways to insert a new row in a table using a sequence. The first way, and most direct, is to include MySequence.nextval as the column value to be inserted. This approach, however, depends on the table‟s users knowing the correct sequence to use and being consistent about usage. In the example below, we are inserting a unique sequence value for the key column. INSERT INTO MyTable (MyKeyColumn, MyValueColumn) VALUES (MySequence.nextval, „Test1‟) Relying on a Trigger to Create a Unique Value A more reliable alternative is to create a trigger for the table that will make sure the sequence is used to generate new values. In the example below, we will create a trigger that checks for a NULL initial value and, if a NULL value is found, creates one using the sequence. In order to get the behavior, you either omit the value or explicitly specify a NULL value (both have the same effect). Creating a PL/SQL trigger to manage the sequence for a table: CREATE OR REPLACE TRIGGER A5TI_MYTABLE BEFORE INSERT ON MYTABLE REFERENCING NEW AS new FOR EACH ROW WHEN (new.KeyValue IS NULL) BEGIN SELECT A5AI_MYTABLE.nextval into :new.KeyValue from dual; END A5TI_MYTABLE; Note: Triggers can also be implemented in Java. Appendix B shows an example of this trigger generated in Java and the required scripts to install it and associate it with the table. Omitting the key column: INSERT INTO MyTable (MyValueColumn) VALUES ( „Test1‟) Explicitly specifying NULL for the key column: INSERT INTO MyTable (MyKeyColumn, MyValueColumn) VALUES (NULL, „Test1‟) Kurt Rayner Page 2 4/15/2008 Oracle Database Sequences and Alpha Five Data Access Objects How Alpha Five Makes Sequences Easier Obviously, if you are hand coding SQL statements, you have complete control over the syntax. You need only make sure that the trigger exists or to hand code the <sequence>.nextval expression as the newly inserted value. But what if Alpha Five is automatically generating the SQL for you? Unfortunately, there is no schema information in Oracle that tells you that a sequence is explicitly tied to a table. There is no way to infer this information with 100% accuracy. What Alpha Five does do however is make sure that any table you export will work as expected. Here‟s the way it works. If a table has a single numeric primary key column that is defined as auto-increment or identity (depending on the original database the table is defined in): 1. A new sequence is generated along with the newly created table. The name of the sequence is always A5AI_<table name>. For example if the table name is ‘Customers’, the associated sequence name will be A5AI_CUSTOMERS. 2. An Oracle trigger is generated for the table that automatically invokes the sequence when the primary key value is NULL during inserts. This trigger can be PLSQL or Java depending on the value of the A5ProcedureLanguage keyword in the connection string. Note that PLSQL is the default for Oracle. 3. When Alpha Five retrieves schema information for a table, it looks for a sequence named A5AI_<table_name>. If it finds this sequence, it stores the name in the key column of the SQL::TableInfo object that describes the table. 4. When SQL statements are created using a SQL::TableInfo with the sequence name in the key column, Alpha Five generates the correct SQL to insert new rows and to retrieve the last inserted identity after a successful insert. If you have an existing table and you want Alpha Five to handle inserting new rows automatically, you need to either create and use a sequence named A5AI_<table_name> or set the sequence name used into the SQL::TableInfo object prior to generating SQL statements. dim ti as SQL::TableInfo myconnection.GetTableInfo(ti, “MyTable”) ti.col[1].IdentitySequenceName = “MyActualSequence” Kurt Rayner Page 3 4/15/2008 Oracle Database Sequences and Alpha Five Data Access Objects How to Create a Table with a Sequence In XBasic The script below demonstrates how Alpha Five (and you can use the same techniques if you wish) creates and populates a SQL::TableInfo defining the table we want to create to demonstrate the export behavior. „ Create and manually populate a SQL::TableInfo dim ti as sql::tableinfo ti.name = "MyTable" „ Add the key column dim tc as sql::datatypeinfo tc.name = "KeyValue" tc.alphatype = "N" tc.autoincrement = .t. ti.addcolumn(tc) „ Add a data column dim tc2 as sql::datatypeinfo tc2.name = "DataValue" tc2.alphatype = "C" tc2.length = 25 ti.addcolumn(tc2) „ Add the Primary Key dim ii as sql::indexinfo ii.name = "PrimaryKey" ii.primarykey = .t. dim ic as sql::indexcolumninfo ic.name = "KeyValue" ii.addcolumn(ic) ti.addIndex(ii) Alpha Five uses the connection object to generate syntax to create a table, triggers and procedures as shown in the script below. Note the use of the SQL::Connection function GenerateCreateTableStatement to create the sequence and the trigger. dim c as sql::connection c.setconnectionstring("{a5syntax=Oracle}") ?c.generatecreatetablestatement(ti) = CREATE TABLE MyTable ( KeyValue number NOT NULL, DataValue varchar2(25) NULL, PRIMARY KEY (KeyValue))\ CREATE SEQUENCE A5AI_MYTABLE START WITH 1 INCREMENT BY 1 NOMAXVALUE\ CREATE OR REPLACE TRIGGER A5TI_MYTABLE BEFORE INSERT ON MYTABLE REFERENCING NEW AS new FOR EACH ROW WHEN (new.KeyValue IS NULL) BEGIN SELECT A5AI_MYTABLE.nextval into :new.KeyValue from dual; END A5TI_MYTABLE; Kurt Rayner Page 4 4/15/2008 Oracle Database Sequences and Alpha Five Data Access Objects Generating A Java Trigger for Oracle You can also generate a Java trigger using the code above by adding the keyword A5ProcedureLanguage to the connection string and setting its value to Java (Note that the default value is PLSQL, but you can code it explicitly if you like. c.setconnectionstring("{a5syntax=Oracle,A5ProcedureLanguage=Java}") CREATE OR REPLACE AND COMPILE JAVA SOURCE NAMED A5JV_MYTABLE AS /* Generated by Alpha Five */ import java.sql.*; public class A5CL_MYTABLE { public static void BeforeInsert(double[] KeyValue) throws SQLException { Connection conn = null; Statement stmt = null; ResultSet rset = null; try { conn = DriverManager.getConnection("jdbc:default:connection:"); stmt = conn.createStatement(); rset = stmt.executeQuery("select A5AI_MYTABLE.nextval from dual"); if (rset.next()) KeyValue[0] = (double)rset.getDouble(1); } catch(SQLException e) { throw(e); } finally { if (rset != null) rset.close(); if (stmt != null) stmt.close(); } } }; CREATE OR REPLACE PROCEDURE A5SP_MYTABLE(new_key IN OUT NUMBER) AS LANGUAGE JAVA NAME 'A5CL_MYTABLE.BeforeInsert(double[])'; CREATE OR REPLACE TRIGGER A5TI_MYTABLE BEFORE INSERT ON MYTABLE FOR EACH ROW WHEN (new.KeyValue is null) CALL A5SP_MYTABLE(:new.KeyValue) Kurt Rayner Page 5 4/15/2008 Oracle Database Sequences and Alpha Five Data Access Objects Conclusion It is probably best to use the newer identity options on most databases, but for Oracle, sequences are a fact of life. If and when Alpha Five can truly infer schema information about the intended usage of sequences for key columns in tables, we will gladly make this process automatic. For now, there are options to make it easier to use. Kurt Rayner Page 6 4/15/2008