The Java Tutorials have been written for JDK 8.Java教程是为JDK 8编写的。Examples and practices described in this page don't take advantage of improvements introduced in later releases and might use technology no longer available.本页中描述的示例和实践没有利用后续版本中引入的改进,并且可能使用不再可用的技术。See Java Language Changes for a summary of updated language features in Java SE 9 and subsequent releases.有关Java SE 9及其后续版本中更新的语言特性的摘要,请参阅Java语言更改。
See JDK Release Notes for information about new features, enhancements, and removed or deprecated options for all JDK releases.有关所有JDK版本的新功能、增强功能以及已删除或不推荐的选项的信息,请参阅JDK发行说明。
Note: MySQL and Java DB currently do not support user-defined types. 注意:MySQL和Java DB目前不支持用户定义的类型。Consequently, no JDBC tutorial example is available to demonstrate the features described in this section.因此,没有JDBC教程示例可用于演示本节中描述的功能。
The following topics are covered:涵盖以下主题:
SQL structured types and SQL结构化类型和DISTINCT
types are the two data types that a user can define in SQL. DISTINCT
类型是用户可以在SQL中定义的两种数据类型。They are often referred to as UDTs (user-defined types), and you create them with a SQL 它们通常被称为UDT(用户定义类型),您可以使用SQL CREATE
TYPE
statement.CREATE TYPE
语句创建它们。
Getting back to the example of The Coffee Break, suppose that the owner has been successful beyond all expectations and has been expanding with new branches. 回到咖啡休息的例子,假设店主的成功超出了所有人的预期,并且一直在扩展新的分支机构。The owner has decided to add a 所有者已决定向数据库添加一个STORES
table to the database containing information about each establishment. STORES
表,其中包含每个机构的信息。STORES
will have four columns:STORES
将有四列:
STORE_NO
LOCATION
COF_TYPES
MGR
The owner makes the column 所有者将列LOCATION
be a SQL structured type, the column COF_TYPES
a SQL ARRAY
, and the column MGR
a REF(MANAGER)
, with MANAGER
being a SQL structured type.LOCATION
设置为SQL结构化类型,将列COF_TYPES
设置为SQLARRAY
,将列MGR
设置为REF(MANAGER)
,将MANAGER
设置为SQL结构化类型。
The first thing the owner must define the new structured types for the address and the manager. 所有者首先必须为地址和经理定义新的结构化类型。A SQL structured type is similar to structured types in the Java programming language in that it has members, called attributes, that may be any data type. SQL结构化类型类似于Java编程语言中的结构化类型,因为它具有称为属性的成员,这些成员可以是任何数据类型。The owner writes the following SQL statement to create the new data type 所有者编写以下SQL语句以创建新的数据类型ADDRESS
:ADDRESS
:
CREATE TYPE ADDRESS ( NUM INTEGER, STREET VARCHAR(40), CITY VARCHAR(40), STATE CHAR(2), ZIP CHAR(5) );
In this statement, the new type 在该语句中,新类型ADDRESS
has five attributes, which are analogous to fields in a Java class. ADDRESS
有五个属性,它们类似于Java类中的字段。The attribute 属性NUM
is an INTEGER
, the attribute STREET
is a VARCHAR(40)
, the attribute CITY
is a VARCHAR(40)
, the attribute STATE
is a CHAR(2)
, and the attribute ZIP
is a CHAR(5)
.NUM
是INTEGER
,属性STREET
是VARCHAR(40)
,属性CITY
是VARCHAR(40)
,属性STATE
是CHAR(2)
,属性ZIP
是CHAR(5)
。
The following excerpt, in which 以下摘录(其中con
is a valid Connection
object, sends the definition of ADDRESS
to the database:con
是有效的连接对象)将ADDRESS
的定义发送到数据库:
String createAddress = "CREATE TYPE ADDRESS " + "(NUM INTEGER, STREET VARCHAR(40), " + "CITY VARCHAR(40), STATE CHAR(2), ZIP CHAR(5))"; Statement stmt = con.createStatement(); stmt.executeUpdate(createAddress);
Now the 现在,ADDRESS
structured type is registered with the database as a data type, and the owner can use it as the data type for a table column or an attribute of a structured type.ADDRESS
结构化类型作为数据类型在数据库中注册,所有者可以将其用作表列或结构化类型属性的数据类型。
One of the attributes the owner of The Coffee Break plans to include in the new structured type 咖啡休息时间的所有者计划在新的结构化类型MANAGER
is the manager's telephone number. MANAGER
中包括的属性之一是经理的电话号码。Because the owner will always list the telephone number as a 10-digit number (to be sure it includes the area code) and will never manipulate it as a number, the owner decides to define a new type called 由于所有者将始终将电话号码列为10位数字(以确保其包含区号),并且不会将其作为数字进行操作,因此所有者决定定义一个名为PHONE_NO
that consists of 10 characters. PHONE_NO
的新类型,该类型由10个字符组成。The SQL definition of this data type, which can be thought of as a structured type with only one attribute, looks like this:此数据类型的SQL定义可以看作是一个只有一个属性的结构化类型,如下所示:
CREATE TYPE PHONE_NO AS CHAR(10);
Or, as noted earlier, for some drivers the definition might look like this:或者,如前所述,对于某些驱动程序,定义可能如下所示:
CREATE DISTINCT TYPE PHONE_NO AS CHAR(10);
A DISTINCT
type is always based on another data type, which must be a predefined type. DISTINCT
类型始终基于另一个数据类型,该数据类型必须是预定义的类型。In other words, a 换句话说,DISTINCT
type cannot be based on a user-defined type (UDT). DISTINCT
类型不能基于用户定义类型(UDT)。To retrieve or set a value that is a 要检索或设置DISTINCT
type, use the appropriate method for the underlying type (the type on which it is based). DISTINCT
类型的值,请对基础类型(它所基于的类型)使用适当的方法。For example, to retrieve an instance of 例如,要检索基于PHONE_NO
, which is based on a CHAR
type, you would use the method getString
because that is the method for retrieving a CHAR
.CHAR
类型的PHONE_NO
实例,可以使用getString
方法,因为这是检索CHAR
的方法。
Assuming that a value of type 假设一个PHONE_NO
is in the fourth column of the current row of the ResultSet
object rs
, the following line of code retrieves it:PHONE_NO
类型的值位于ResultSet
对象rs
当前行的第四列中,下面的代码行将检索该值:
String phoneNumber = rs.getString(4);
Similarly, the following line of code sets an input parameter that has type 类似地,以下代码行设置了一个输入参数,该参数的类型为PHONE_NO
for a prepared statement being sent to the database:PHONE_NO
,用于发送到数据库的准备语句:
pstmt.setString(1, phoneNumber);
Adding on to the previous code fragment, the definition of 在前面的代码片段的基础上,PHONE_NO
will be sent to the database with the following line of code:PHONE_NO
的定义将通过以下代码行发送到数据库:
stmt.executeUpdate( "CREATE TYPE PHONE_NO AS CHAR(10)");
After registering the type 在向数据库注册类型PHONE_NO
with the database, the owner can use it as a column type in a table or as the data type for an attribute in a structured type. PHONE_NO
后,所有者可以将其用作表中的列类型或结构化类型中属性的数据类型。The definition of 以下SQL语句中MANAGER
in the following SQL statement uses PHONE_NO
as the data type for the attribute PHONE
:MANAGER
的定义使用PHONE_NO
作为属性PHONE
的数据类型:
CREATE TYPE MANAGER ( MGR_ID INTEGER, LAST_NAME VARCHAR(40), FIRST_NAME VARCHAR(40), PHONE PHONE_NO );
Reusing 使用前面定义的stmt
, defined previously, the following code fragment sends the definition of the structured type MANAGER
to the database:stmt
,以下代码片段将结构化类型MANAGER
的定义发送到数据库:
String createManager = "CREATE TYPE MANAGER " + "(MGR_ID INTEGER, LAST_NAME " + "VARCHAR(40), " + "FIRST_NAME VARCHAR(40), " + "PHONE PHONE_NO)"; stmt.executeUpdate(createManager);
The owner of The Coffee Break has created three new data types used as column types or attribute types in the database: The structured types Coffee Break的所有者创建了三种新的数据类型,用作数据库中的列类型或属性类型:结构化类型LOCATION
and MANAGER
, and the DISTINCT
type PHONE_NO
. LOCATION
和MANAGER
和DISTINCT
类型PHONE_NO
。The entrepreneur has used 企业家在新的类型PHONE_NO
as the type for the attribute PHONE
in the new type MANAGER
, and ADDRESS
as the data type for the column LOCATION
in the table STORES
. MANAGER
中将PHONE_NO
用作属性PHONE
的类型,将ADDRESS
用作表STORES
中列LOCATION
的数据类型。The MANAGER
type could be used as the type for the column MGR
, but instead the entrepreneur prefers to use the type REF(MANAGER)
because the entrepreneur often has one person manage two or three stores. MANAGER
类型可以用作列MGR
的类型,但企业家更喜欢使用类型REF(MANAGER)
,因为企业家通常由一个人管理两个或三个店铺。Using 使用REF(MANAGER)
as a column type avoids repeating all the data for MANAGER
when one person manages more than one store.REF(MANAGER)
作为列类型可以避免在一个人管理多个存储时重复MANAGER
的所有数据。
With the structured type 在已创建结构化类型MANAGER
already created, the owner can now create a table containing instances of MANAGER
that can be referenced. MANAGER
的情况下,所有者现在可以创建一个包含可引用的MANAGER
实例的表。A reference to an instance of 对MANAGER
will have the type REF(MANAGER)
. MANAGER
实例的引用的类型为REF(MANAGER)
。A SQL SQL REF
is nothing more than a logical pointer to a structured type, so an instance of REF(MANAGER)
serves as a logical pointer to an instance of MANAGER
.REF
只不过是指向结构化类型的逻辑指针,因此REF(MANAGER)
的实例充当指向MANAGER
实例的逻辑指针。
Because a SQL 因为SQL REF
value needs to be permanently associated with the instance of the structured type that it references, it is stored in a special table together with its associated instance. REF
值需要与它引用的结构化类型的实例永久关联,所以它与其关联的实例一起存储在一个特殊的表中。A programmer does not create 程序员不直接创建REF
types directly but rather creates the table that will store instances of a particular structured type that can be referenced. REF
类型,而是创建一个表来存储可引用的特定结构化类型的实例。Every structured type that is to be referenced will have its own table. When you insert an instance of the structured type into the table, the database automatically creates a 要引用的每个结构化类型都有自己的表。在表中插入结构化类型的实例时,数据库会自动创建一个REF
instance. REF
实例。For example, to contain instances of 例如,为了包含可引用的MANAGER
that can be referenced, the owner created the following special table using SQL:MANAGER
实例,所有者使用SQL创建了以下特殊表:
CREATE TABLE MANAGERS OF MANAGER (OID REF(MANAGER) VALUES ARE SYSTEM GENERATED);
This statement creates a table with the special column 此语句创建一个具有特殊列OID
, which stores values of type REF(MANAGER)
. OID
的表,该列存储REF(MANAGER)
类型的值。Each time an instance of 每次将MANAGER
is inserted into the table, the database will generate an instance of REF(MANAGER)
and store it in the column OID
. MANAGER
实例插入表中时,数据库将生成一个REF(MANAGER)
实例并将其存储在OID
列中。Implicitly, an additional column stores each attribute of 另一列隐式地存储插入表中的MANAGER
that has been inserted into the table, as well. MANAGER
的每个属性。For example, the following code fragment shows how the entrepreneur created three instances of the 例如,以下代码片段显示了企业家如何创建MANAGER
structured type to represent three managers:MANAGER
结构化类型的三个实例来表示三个经理:
INSERT INTO MANAGERS ( MGR_ID, LAST_NAME, FIRST_NAME, PHONE) VALUES ( 000001, 'MONTOYA', 'ALFREDO', '8317225600' ); INSERT INTO MANAGERS ( MGR_ID, LAST_NAME, FIRST_NAME, PHONE) VALUES ( 000002, 'HASKINS', 'MARGARET', '4084355600' ); INSERT INTO MANAGERS ( MGR_ID, LAST_NAME, FIRST_NAME, PHONE) VALUES ( 000003, 'CHEN', 'HELEN', '4153785600' );
The table 表MANAGERS
will now have three rows, one row for each manager inserted so far. MANAGERS
中现在有了三行数据,每行针对一个刚插入的经理。The column 列OID
will contain three unique object identifiers of type REF(MANAGER)
, one for each instance of MANAGER.
OID
将包含三个REF(MANAGER)
类型的唯一对象标识符,每个MANAGER
实例一个。These object identifiers were generated automatically by the database and will be permanently stored in the table 这些对象标识符由数据库自动生成,并将永久存储在表MANAGERS
. MANAGERS
中。Implicitly, an additional column stores each attribute of 隐式地,另一列存储MANAGER
. MANAGER
的每个属性。For example, in the table 例如,在表MANAGERS
, one row contains a REF(MANAGER)
that references Alfredo Montoya, another row contains a REF(MANAGER)
that references Margaret Haskins, and a third row contains a REF(MANAGER)
that references Helen Chen.MANAGERS
中,一行包含引用Alfredo Montoya的REF(MANAGER)
,另一行包含引用Margaret Haskins的REF(MANAGER)
,第三行包含引用Helen Chen的REF(MANAGER)
。
To access a 要访问REF(MANAGER)
instance, you select it from its table. REF(MANAGER)
实例,请从其表中选择它。For example, the owner retrieved the reference to Alfredo Montoya, whose ID number is 000001, with the following code fragment:例如,所有者检索到对Alfredo Montoya的引用,其ID号为000001,代码片段如下:
String selectMgr = "SELECT OID FROM MANAGERS " + "WHERE MGR_ID = 000001"; ResultSet rs = stmt.executeQuery(selectMgr); rs.next(); Ref manager = rs.getRef("OID");
Now the variable 现在,变量manager
can be used as a column value that references Alfredo Montoya.manager
可以用作引用Alfredo Montoya的列值。
The following code example creates the table 下面的代码示例创建表MANAGERS
, a table of instances of the structured type MANAGER
that can be referenced, and inserts three instances of MANAGER
into the table. MANAGERS
,即可以引用的结构化类型MANAGER
实例表,并将MANAGER
的三个实例插入表中。The column 此表中的列OID
in this table will store instances of REF(MANAGER)
. OID
将存储REF(MANAGER)
的实例。After this code is executed, the 执行此代码后,MANAGERS
table will have a row for each of the three MANAGER
objects inserted, and the value in the OID
column will be the REF(MANAGER)
type that identifies the instance of MANAGER
stored in that row.MANAGERS
表将针对插入的三个MANAGER
对象中的每一个都有一行,OID
列中的值将是标识存储在该行中的管理器实例的REF(MANAGER)
类型。
package com.oracle.tutorial.jdbc; import java.sql.*; public class CreateRef { public static void main(String args[]) { JDBCTutorialUtilities myJDBCTutorialUtilities; Connection myConnection = null; if (args[0] == null) { System.err.println("Properties file not specified " + "at command line"); return; } else { try { myJDBCTutorialUtilities = new JDBCTutorialUtilities(args[0]); } catch (Exception e) { System.err.println("Problem reading properties " + "file " + args[0]); e.printStackTrace(); return; } } Connection con = null; Statement stmt = null; try { String createManagers = "CREATE TABLE " + "MANAGERS OF MANAGER " + "(OID REF(MANAGER) " + "VALUES ARE SYSTEM " + "GENERATED)"; String insertManager1 = "INSERT INTO MANAGERS " + "(MGR_ID, LAST_NAME, " + "FIRST_NAME, PHONE) " + "VALUES " + "(000001, 'MONTOYA', " + "'ALFREDO', " + "'8317225600')"; String insertManager2 = "INSERT INTO MANAGERS " + "(MGR_ID, LAST_NAME, " + "FIRST_NAME, PHONE) " + "VALUES " + "(000002, 'HASKINS', " + "'MARGARET', " + "'4084355600')"; String insertManager3 = "INSERT INTO MANAGERS " + "(MGR_ID, LAST_NAME, " + "FIRST_NAME, PHONE) " + "VALUES " + "(000003, 'CHEN', 'HELEN', " + "'4153785600')"; con = myJDBCTutorialUtilities.getConnection(); con.setAutoCommit(false); stmt = con.createStatement(); stmt.executeUpdate(createManagers); stmt.addBatch(insertManager1); stmt.addBatch(insertManager2); stmt.addBatch(insertManager3); int [] updateCounts = stmt.executeBatch(); con.commit(); System.out.println("Update count for: "); for (int i = 0; i < updateCounts.length; i++) { System.out.print(" command " + (i + 1) + " = "); System.out.println(updateCounts[i]); } } catch(BatchUpdateException b) { System.err.println("-----BatchUpdateException-----"); System.err.println("Message: " + b.getMessage()); System.err.println("SQLState: " + b.getSQLState()); System.err.println("Vendor: " + b.getErrorCode()); System.err.print("Update counts for " + "successful commands: "); int [] rowsUpdated = b.getUpdateCounts(); for (int i = 0; i < rowsUpdated.length; i++) { System.err.print(rowsUpdated[i] + " "); } System.err.println(""); } catch(SQLException ex) { System.err.println("------SQLException------"); System.err.println("Error message: " + ex.getMessage()); System.err.println("SQLState: " + ex.getSQLState()); System.err.println("Vendor: " + ex.getErrorCode()); } finally { if (stmt != null) { stmt.close(); } JDBCTutorialUtilities.closeConnection(con); } } }
Our entrepreneur now has the UDTs required to create the table 我们的企业家现在拥有创建表STORES
. STORES
所需的UDT。The structured type 结构化类型ADDRESS
is the type for the column LOCATION
, and the type REF(MANAGER)
is the type for the column MGR
.ADDRESS
是列LOCATION
的类型,类型REF(MANAGER)
是列管理器的类型。
The UDT UDT COF_TYPES
is based on the SQL data type ARRAY
and is the type for the column COF_TYPES
. COF_TYPES
基于SQL数据类型ARRAY
,是列COF_TYPES
的类型。The following line of code creates the type 下面的代码行将COF_ARRAY
as an ARRAY
value with 10 elements. COF_ARRAY
类型创建为包含10个元素的ARRAY
值。The base type of COF_ARRAY
is VARCHAR(40)
.COF_ARRAY
的基本类型是VARCHAR(40)
。
CREATE TYPE COF_ARRAY AS ARRAY(10) OF VARCHAR(40);
With the new data types defined, the following SQL statement creates the table 定义了新的数据类型后,以下SQL语句将创建表STORES
:STORES
:
CREATE TABLE STORES ( STORE_NO INTEGER, LOCATION ADDRESS, COF_TYPES COF_ARRAY, MGR REF(MANAGER) );
The following code fragment inserts one row into the 下面的代码片段将一行插入STORES
table, supplying values for the columns STORE_NO
, LOCATION
, COF_TYPES
, and MGR
, in that order:STORES
表,按顺序为STORE_NO
、LOCATION
、COF_TYPES
和MGR
列提供值:
INSERT INTO STORES VALUES ( 100001, ADDRESS(888, 'Main_Street', 'Rancho_Alegre', 'CA', '94049'), COF_ARRAY('Colombian', 'French_Roast', 'Espresso', 'Colombian_Decaf', 'French_Roast_Decaf'), SELECT OID FROM MANAGERS WHERE MGR_ID = 000001 );
The following goes through each column and the value inserted into it.下面将介绍每一列及其插入的值。
STORE_NO: 100001
This column is type 此列为INTEGER
, and the number 100001
is an INTEGER
type, similar to entries made before in the tables COFFEES
and SUPPLIERS
.INTEGER
类型,数字100001
为INTEGER
类型,类似于之前在表COFFEES
和表SUPPLIERS
中的条目。
LOCATION: ADDRESS(888, 'Main_Street', 'Rancho_Alegre', 'CA', '94049')
The type for this column is the structured type 此列的类型是结构化类型ADDRESS
, and this value is the constructor for an instance of ADDRESS
. ADDRESS
,此值是ADDRESS
实例的构造函数。When we sent the definition of 当我们将ADDRESS
was sent to the database, one of the things it did was to create a constructor for the new type. ADDRESS
的定义发送到数据库时,它所做的一件事就是为新类型创建一个构造函数。The comma-separated values in parentheses are the initialization values for the attributes of the 括号中以逗号分隔的值是ADDRESS
type, and they must appear in the same order in which the attributes were listed in the definition of the ADDRESS
type. ADDRESS
类型属性的初始化值,它们的出现顺序必须与ADDRESS
类型定义中列出属性的顺序相同。888
is the value for the attribute NUM
, which is an INTEGER
value. 888
是属性NUM
的值,它是一个INTEGER
值。"Main_Street"
is the value for STREET
, and "Rancho_Alegre"
is the value for CITY
, with both attributes being of type VARCHAR(40)
. "Main_Street"
是STREET
的值,"Rancho_Alegre"
是CITY
的值,两个属性的类型都是VARCHAR(40)
。The value for the attribute 属性STATE
is "CA"
, which is of type CHAR(2)
, and the value for the attribute ZIP
is "94049"
, which is of type CHAR(5)
.STATE
的值为"CA"
,类型为CHAR(2)
,属性ZIP
的值为"94049"
,类型为CHAR(5)
。
COF_TYPES: COF_ARRAY( 'Colombian', 'French_Roast', 'Espresso', 'Colombian_Decaf', 'French_Roast_Decaf'),
The column 列COF_TYPES
is of type COF_ARRAY
with a base type of VARCHAR(40)
, and the comma-separated values between parentheses are the String
objects that are the array elements. COF_TYPES
是COF_ARRAY
类型,基类型为VARCHAR(40)
,括号之间以逗号分隔的值是作为String
元素的字符串对象。The owner defined the type 所有者将类型COF_ARRAY
as having a maximum of 10 elements. COF_ARRAY
定义为最多有10个元素。This array has 5 elements because the entrepreneur supplied only 5 此数组有5个元素,因为企业家仅为其提供了5个String
objects for it.String
对象。
MGR: SELECT OID FROM MANAGERS WHERE MGR_ID = 000001
The column 列MGR
is type REF(MANAGER)
, which means that a value in this column must be a reference to the structured type MANAGER
. MGR
的类型为REF(MANAGER)
,这意味着此列中的值必须是对结构化类型MANAGER
的引用。All of the instances of MANAGER
are stored in the table MANAGERS
. MANAGER
的所有实例都存储在表MANAGER
中。All of the instances of REF(MANAGER)
are also stored in this table, in the column OID
. REF(MANAGER)
的所有实例也存储在此表中的OID
列中。The manager for the store described in this table row is Alfredo Montoya, and his information is stored in the instance of 此表行中描述的存储区的经理是Alfredo Montoya,他的信息存储在MANAGER
that has 100001
for the attribute MGR_ID
. MANAGER
实例中,该实例的属性MGR_ID
为100001
。To get the 要获取与Alfredo Montoya的REF(MANAGER)
instance associated with the MANAGER
object for Alfredo Montoya, select the column OID
that is in the row where MGR_ID
is 100001
in the table MANAGERS
. MANAGER
对象关联的REF(MANAGER)
实例,请选择表MANAGERS
中MGR_ID
为100001
的行中的列OID
。The value that will be stored in the 存储在MGR
column of the STORES
table (the REF(MANAGER)
value) is the value the DBMS generated to uniquely identify this instance of the MANAGER
structured type.STORES
表的MGR
列中的值(REF(MANAGER)
值)是DBMS生成的唯一标识此MANAGER
结构化类型实例的值。
Send the preceding SQL statement to the database with the following code fragment:使用以下代码片段将前面的SQL语句发送到数据库:
String insertMgr = "INSERT INTO STORES VALUES " + "(100001, " + "ADDRESS(888, 'Main_Street', " + "'Rancho_Alegre', 'CA', " + "'94049'), " + "COF_ARRAY('Colombian', " + "'French_Roast', 'Espresso', " + "'Colombian_Decaf', " + "'French_Roast_Decaf'}, " + "SELECT OID FROM MANAGERS " + "WHERE MGR_ID = 000001)"; stmt.executeUpdate(insertMgr);
However, because you are going to send several 但是,由于您将发送多个INSERT INTO
statements, it will be more efficient to send them all together as a batch update, as in the following code example:INSERT INTO
语句,因此将它们作为批处理更新一起发送将更有效,如以下代码示例所示:
package com.oracle.tutorial.jdbc; import java.sql.*; public class InsertStores { public static void main(String args[]) { JDBCTutorialUtilities myJDBCTutorialUtilities; Connection myConnection = null; if (args[0] == null) { System.err.println( "Properties file " + "not specified " + "at command line"); return; } else { try { myJDBCTutorialUtilities = new JDBCTutorialUtilities(args[0]); } catch (Exception e) { System.err.println( "Problem reading " + "properties file " + args[0]); e.printStackTrace(); return; } } Connection con = null; Statement stmt = null; try { con = myJDBCTutorialUtilities.getConnection(); con.setAutoCommit(false); stmt = con.createStatement(); String insertStore1 = "INSERT INTO STORES VALUES (" + "100001, " + "ADDRESS(888, 'Main_Street', " + "'Rancho_Alegre', 'CA', " + "'94049'), " + "COF_ARRAY('Colombian', " + "'French_Roast', " + "'Espresso', " + "'Colombian_Decaf', " + "'French_Roast_Decaf'), " + "(SELECT OID FROM MANAGERS " + "WHERE MGR_ID = 000001))"; stmt.addBatch(insertStore1); String insertStore2 = "INSERT INTO STORES VALUES (" + "100002, " + "ADDRESS(1560, 'Alder', " + "'Ochos_Pinos', " + "'CA', '94049'), " + "COF_ARRAY('Colombian', " + "'French_Roast', " + "'Espresso', " + "'Colombian_Decaf', " + "'French_Roast_Decaf', " + "'Kona', 'Kona_Decaf'), " + "(SELECT OID FROM MANAGERS " + "WHERE MGR_ID = 000001))"; stmt.addBatch(insertStore2); String insertStore3 = "INSERT INTO STORES VALUES (" + "100003, " + "ADDRESS(4344, " + "'First_Street', " + "'Verona', " + "'CA', '94545'), " + "COF_ARRAY('Colombian', " + "'French_Roast', " + "'Espresso', " + "'Colombian_Decaf', " + "'French_Roast_Decaf', " + "'Kona', 'Kona_Decaf'), " + "(SELECT OID FROM MANAGERS " + "WHERE MGR_ID = 000002))"; stmt.addBatch(insertStore3); String insertStore4 = "INSERT INTO STORES VALUES (" + "100004, " + "ADDRESS(321, 'Sandy_Way', " + "'La_Playa', " + "'CA', '94544'), " + "COF_ARRAY('Colombian', " + "'French_Roast', " + "'Espresso', " + "'Colombian_Decaf', " + "'French_Roast_Decaf', " + "'Kona', 'Kona_Decaf'), " + "(SELECT OID FROM MANAGERS " + "WHERE MGR_ID = 000002))"; stmt.addBatch(insertStore4); String insertStore5 = "INSERT INTO STORES VALUES (" + "100005, " + "ADDRESS(1000, 'Clover_Road', " + "'Happyville', " + "'CA', '90566'), " + "COF_ARRAY('Colombian', " + "'French_Roast', " + "'Espresso', " + "'Colombian_Decaf', " + "'French_Roast_Decaf'), " + "(SELECT OID FROM MANAGERS " + "WHERE MGR_ID = 000003))"; stmt.addBatch(insertStore5); int [] updateCounts = stmt.executeBatch(); ResultSet rs = stmt.executeQuery( "SELECT * FROM STORES"); System.out.println("Table STORES after insertion:"); System.out.println("STORE_NO " + "LOCATION " + "COF_TYPE " + "MGR"); while (rs.next()) { int storeNo = rs.getInt("STORE_NO"); Struct location = (Struct)rs.getObject("LOCATION"); Object[] locAttrs = location.getAttributes(); Array coffeeTypes = rs.getArray("COF_TYPE"); String[] cofTypes = (String[])coffeeTypes.getArray(); Ref managerRef = rs.getRef("MGR"); PreparedStatement pstmt = con.prepareStatement( "SELECT MANAGER " + "FROM MANAGERS " + "WHERE OID = ?"); pstmt.setRef(1, managerRef); ResultSet rs2 = pstmt.executeQuery(); rs2.next(); Struct manager = (Struct)rs2.getObject("MANAGER"); Object[] manAttrs = manager.getAttributes(); System.out.print(storeNo + " "); System.out.print( locAttrs[0] + " " + locAttrs[1] + " " + locAttrs[2] + ", " + locAttrs[3] + " " + locAttrs[4] + " "); for (int i = 0; i < cofTypes.length; i++) System.out.print( cofTypes[i] + " "); System.out.println( manAttrs[1] + ", " + manAttrs[2]); rs2.close(); pstmt.close(); } rs.close(); } catch(BatchUpdateException b) { System.err.println("-----BatchUpdateException-----"); System.err.println("SQLState: " + b.getSQLState()); System.err.println("Message: " + b.getMessage()); System.err.println("Vendor: " + b.getErrorCode()); System.err.print("Update counts: "); int [] updateCounts = b.getUpdateCounts(); for (int i = 0; i < updateCounts.length; i++) { System.err.print(updateCounts[i] + " "); } System.err.println(""); } catch(SQLException ex) { System.err.println("SQLException: " + ex.getMessage()); System.err.println("SQLState: " + ex.getSQLState()); System.err.println("Message: " + ex.getMessage()); System.err.println("Vendor: " + ex.getErrorCode()); } finally { if (stmt != null) { stmt.close(); } JDBCTutorialUtilities.closeConnection(con); } } } }