Person_t
Person_t
のサブタイプとしてEmployee_t
Person_t
のサブタイプとしてStudent_t
Student_t
のサブタイプとしてPartTimeStudent_t
また、次の表も作成されます。
Person_t
とそのサブタイプのオブジェクトを保持するためのperson_tab
次のSQLファイルinhdemo1.sql
では、オブジェクト型と表が生成されてから、表に値が挿入されます。
connect scott/tiger; rem ** Always drop your objects in reverse dependency order drop table person_tab; drop type PartTimeStudent_t; drop type Student_t; drop type Employee_t; drop type Person_t; rem ** Create the TYPES, TYPED TABLES and TABLES we need rem ** Create a Person_t ADT CREATE TYPE Person_t AS OBJECT ( ssn NUMBER, name VARCHAR2(30), address VARCHAR2(100)) NOT FINAL; / rem ** Create a Person_t subtype Employee_t CREATE TYPE Employee_t UNDER Person_t ( empid NUMBER, mgr VARCHAR2(30)); / rem ** Create a Person_t subtype Student_t CREATE TYPE Student_t UNDER Person_t ( deptid NUMBER, major VARCHAR2(30)) NOT FINAL; / rem ** Create a Student_t subtype PartTimeStudent_t CREATE TYPE PartTimeStudent_t UNDER Student_t ( numhours NUMBER); / rem ** Create a typed table for person_t objects CREATE table person_tab of person_t; rem ** Insert 2 Employee_t objects into the person_t typed table insert into person_tab values (Employee_t(123456, 'Alison Laurence', '100 Geary Street, San Francisco, CA 94013', 1001, 'CEO')); insert into person_tab values (Employee_t(234567, 'William Bates', '123 Main Street, Anytown, WA 97818', 1002,'CFO')); rem ** Insert 2 Student_t objects into the person_t typed table insert into person_tab values (Student_t(20001, 'Van Gates', '1825 Aikido Way, Los Angeles, CA, 45300', 20, 'English')); insert into person_tab values (Student_t(20002, 'Bill Wallace', '12 Shugyo Blvd, Los Angeles, CA, 95100', 30, 'Computer Science')); rem ** Insert 1 PartTimeStudent_t object into the person_t typed table insert into person_tab values (PartTimeStudent_t(20003, 'Jean Claude', '874 Richmond Street, New York, NY 45100', 40, 'Music',20)); commit;
例で使用したintypeファイルinhdemo1.typ
のリストを次に示します。
case=same type person_t type employee_t type student_t type parttimestudent_t
プリコンパイラ・ファイルinhdemo1.pc
のリストを次に示します。
/***************************************************************************** * * This is a simple Pro*C/C++ program designed to illustrate how to * access type inheritance objects. * * To build the executable: * * 1. Execute the SQL script, inhdemo1.sql in SQL*Plus to create: * - 4 object types person_t, employee_t as a subtype of person_t, * student_t as a subtype of person_t and parttimestudent_t as * a subtype of student_t. * - 1 typed table person_tab to hold "person_t" and its subtype objects * * 2. Run OTT: (The following command should appear on one line) * ott intype=inhdemo1.typ hfile=inhdemo1.h outtype=out.typ * code=c userid=scott/tiger * * 3. Precompile using Pro*C/C++: * proc inhdemo1 intype=out.typ * 4. Compile/Link (This step is platform specific) * ****************************************************************************/ /* Include files */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sqlda.h> #include <sqlca.h> /* SQL Communications Area */ #include <sql2oci.h> /* SQLLIB interoperability routines for OCI8 */ #include "inhdemo1.h" /* OTT-generated header with C typedefs for the */ /* database types "person" and "address" */ /* Macros */ #define ARRAY_SIZE 10 #define NAME_LENGTH 31 #define ADDR_LENGTH 101 /* Global variables */ char *uid="scott/tiger"; int i; int count; VARCHAR dynstmt[100]; main() { printf("\n*** STARTING OBJECT TYPE INHERITANCE DEMO ***\n"); EXEC SQL WHENEVER SQLERROR DO sql_error("ORACLE error--\n"); EXEC SQL connect :uid; printf("Connected successfully.\n"); exec sql select count(*) into :count from person_tab; printf("\nThere are %d entries in table person_tab.\n", count); do_fetch_all(); /* Fetch person_t objects */ do_fetch_employee(); /* Fetch employee_t objects */ do_fetch_student(); /* Fetch only student_t objects */ do_fetch_parttimestudent(); /* Fetch parttimestuden_t objects */ do_fetch_student_employee(); /* Fetch student_t and employee_t objects */ printf("\nFetching only student_t objects with dynamic sql:\n"); strcpy((char *)dynstmt.arr, "SELECT value(p) from person_tab p where value(p) is of (only student_t)"); do_dynamic_fetch(); /* Fetch student_t object with dynamic sql */ printf("\nFetching student_t and its subtype objects with dynamic sql:\n"); strcpy((char *)dynstmt.arr, "SELECT treat(value(p) as student_t) from person_tab p where value(p) is of(student_t)"); do_dynamic_fetch(); /* Fetch student_t object with dynamic sql */ printf("\n*** END OF OBJECT TYPE INHERITANCE DEMO ***\n"); exit(EXIT_SUCCESS); } void printPerson(person) person_t *person; { int writtenSSN=-1; text writtenName[NAME_LENGTH]; text writtenAddr[ADDR_LENGTH]; EXEC SQL OBJECT GET SSN, NAME, ADDRESS FROM :person INTO :writtenSSN, :writtenName, :writtenAddr; printf("\nSSN=%10d\nNAME=%s\nAddr=%s\n", writtenSSN, writtenName, writtenAddr); } void printEmployee(employee) employee_t *employee; { int writtenID=-1; text writtenMgr[NAME_LENGTH]; printPerson(employee); EXEC SQL OBJECT GET EMPID, MGR FROM :employee INTO :writtenID, :writtenMgr; printf("EMPID=%10d\nMGR=%s\n", writtenID, writtenMgr); } void printStudent(student) student_t *student; { int writtendeptid=-1; text writtenMajor[NAME_LENGTH]; printPerson(student); EXEC SQL OBJECT GET DEPTID, MAJOR FROM :student INTO :writtendeptid, :writtenMajor; printf("DEPTID=%10d\nMAJOR=%s\n", writtendeptid, writtenMajor); } void printPartTimeStudent(parttimes) parttimestudent_t *parttimes; { int written_numhours=-1; printStudent(parttimes); EXEC SQL OBJECT GET NUMHOURS FROM :parttimes INTO :written_numhours; printf("NUMHOURS=%10d\n", written_numhours); } /* Declare error handling function. */ sql_error(msg) char *msg; { char err_msg[128]; size_t buf_len, msg_len; EXEC SQL WHENEVER SQLERROR CONTINUE; printf("\n%s\n", msg); buf_len = sizeof (err_msg); sqlglm(err_msg, &buf_len, &msg_len); printf("%.*s\n", msg_len, err_msg); EXEC SQL ROLLBACK RELEASE; exit(EXIT_FAILURE); } /***************************************************************************** * The following function shows how to select person_t objects ****************************************************************************/ do_fetch_all() { person_t *personArray[ARRAY_SIZE]; person_t_ind *personArray_ind[ARRAY_SIZE]; printf("\nFetching person_t objects:\n"); exec sql declare c1 cursor for select value(p) from person_tab p; exec sql allocate :personArray:personArray_ind; exec sql open c1; exec sql whenever not found goto :done; while(sqlca.sqlcode==0) { exec sql fetch c1 into :personArray:personArray_ind; if (sqlca.sqlcode == 1403) goto done; for (i=0; i < ARRAY_SIZE; i++ ) printPerson(personArray[i]); } done: for (i=0; i < sqlca.sqlerrd[2] % ARRAY_SIZE; i++) printPerson(personArray[i]); printf("Total number of person_t objects fetched: %d.\n", sqlca.sqlerrd[2]); exec sql close c1; exec sql free :personArray:personArray_ind; } /***************************************************************************** * The following function shows how to select person_t subtype employee_t * objects ****************************************************************************/ do_fetch_employee() { employee_t *empArray[ARRAY_SIZE]; employee_t_ind *empArray_ind[ARRAY_SIZE]; printf("\nFetching employee_t objects:\n"); exec sql allocate :empArray:empArray_ind; exec sql declare c2 cursor for select value(p) from person_tab p where value(p) is of (employee_t); exec sql open c2; exec sql whenever not found goto :done_emp; while(sqlca.sqlcode==0) { exec sql fetch c2 into :empArray:empArray_ind; for (i=0; i < ARRAY_SIZE; i++ ) printEmployee(empArray[i]); } done_emp: for (i=0; i < sqlca.sqlerrd[2] % ARRAY_SIZE; i++) printEmployee(empArray[i]); printf("Total number of employee_t objects fetched: %d.\n", sqlca.sqlerrd[2]); exec sql close c2; exec sql free :empArray:empArray_ind; } /***************************************************************************** * The following function shows how to select person_t subtype student_t * objects ****************************************************************************/ do_fetch_student() { student_t *studentArray[ARRAY_SIZE]; student_t_ind *studentArray_ind[ARRAY_SIZE]; printf("\nFetching student_t objects:\n"); exec sql declare c3 cursor for select value(p) from person_tab p where value(p) is of (student_t); exec sql allocate :studentArray:studentArray_ind; exec sql open c3; exec sql whenever not found goto :done_student; for (;;) { exec sql fetch c3 into :studentArray:studentArray_ind; for (i=0; i < ARRAY_SIZE; i++ ) printStudent(studentArray[i]); } done_student: for (i=0; i < sqlca.sqlerrd[2] % ARRAY_SIZE; i++) printStudent(studentArray[i]); printf("Total number of student_t objects fetched: %d.\n", sqlca.sqlerrd[2]); exec sql close c3; exec sql free :studentArray:studentArray_ind; } /***************************************************************************** * The following function shows how to select student_t subtype * parttimestudent objects ****************************************************************************/ do_fetch_parttimestudent() { parttimestudent_t *parttimestudentArrayArray[ARRAY_SIZE]; parttimestudent_t_ind *parttimestudentArrayArray_ind[ARRAY_SIZE]; printf("\nFetching parttimestudent_t objects:\n"); exec sql declare c4 cursor for select value(p) from person_tab p where value(p) is of (parttimestudent_t); exec sql allocate :parttimestudentArrayArray:parttimestudentArrayArray_ind; exec sql open c4; exec sql whenever not found goto :done_parttimestudent; while(sqlca.sqlcode==0) { exec sql fetch c4 into :parttimestudentArrayArray:parttimestudentArrayArray_ind; for (i=0; i < ARRAY_SIZE; i++ ) printPartTimeStudent(parttimestudentArrayArray[i]); } done_parttimestudent: for (i=0; i < sqlca.sqlerrd[2] % ARRAY_SIZE; i++) printPartTimeStudent(parttimestudentArrayArray[i]); printf("Total number of parttimestudent_t objects fetched: %d.\n", sqlca.sqlerrd[2]); exec sql close c4; exec sql free :parttimestudentArrayArray:parttimestudentArrayArray_ind; } /***************************************************************************** * The following function shows how to select person_t subtypes student_t * and employee_t objects ****************************************************************************/ do_fetch_student_employee() { person_t *personArray[ARRAY_SIZE]; person_t_ind *personArray_ind[ARRAY_SIZE]; printf("\nFetching only student_t and employee_t objects:\n"); exec sql declare c5 cursor for select value(p) from person_tab p where value(p) is of (only student_t, employee_t); exec sql allocate :personArray:personArray_ind; exec sql open c5; exec sql whenever not found goto :done_student_employee; while(sqlca.sqlcode==0) { exec sql fetch c5 into :personArray:personArray_ind; for (i=0; i < ARRAY_SIZE; i++ ) printPerson(personArray[i]); } done_student_employee: for (i=0; i < sqlca.sqlerrd[2] % ARRAY_SIZE; i++) printPerson(personArray[i]); printf("Total number of stuent_t and employee_t objects fetched: %d.\n", sqlca.sqlerrd[2]); exec sql close c5; exec sql free :personArray:personArray_ind; } /***************************************************************************** * The following function shows how to select person_t subtype student_t * objects using dynamic sql. ****************************************************************************/ do_dynamic_fetch() { student_t *student; student_t_ind *student_ind; exec sql allocate :student:student_ind; dynstmt.len = (unsigned short)strlen((char *)dynstmt.arr); EXEC SQL PREPARE S FROM :dynstmt; EXEC SQL DECLARE C CURSOR FOR S; EXEC SQL OPEN C; exec sql whenever not found do break; for (;;) { EXEC SQL FETCH C INTO :student:student_ind; printStudent(student); } printf("\nQuery returned %d row%s.\n", sqlca.sqlerrd[2], (sqlca.sqlerrd[2] == 1) ? "" : "s"); EXEC SQL CLOSE C; exec sql free :student:student_ind; }