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_NOLOCATIONCOF_TYPESMGRThe 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 = 000001The 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);
}
}
}
}