LVTN - Xay dung giao dien lap trinh OCI.doc

105 649 0
LVTN - Xay dung giao dien lap trinh OCI.doc

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

Xay dung giao dien lap trinh OCI

Trang 1

PHẦN I : CÁC KHÁI NIỆM CƠ BẢN

CHƯƠNG I : GIỚI THIỆU OCI VÀ NHỮNG ĐẶC TÍNH CỦA NÓI-Oracle Call Inteface(OCI)

SQL là ngôn ngữ lập trình không có cấu trúc Chương trình viết trong nó dùng tập dữ liệu để hoạt động nhưng sẽ không xác định những hoạt động gì được thực thi , hoặc những hoạt động đó thực thi như thế nào SQL dễ học và dễ dùng để giải quyết CSDL Nó cụng là một ngôn ngữ chuẩn dùng để truy cập và thao dữ liệu trong các quan hệ hiện đại và quan hệ hướng đối tượng trong các hệ thống CSDL

Tuy nhiên hầu hết các ngôn ngữ có cấu trúc như C , C++ thì việc thực thi của hầu hết các câu lệnh phụ thuộc vào những câu lệnh trước đó hoặc những câu lệnh lồng bên trong nó và những câu lệnh điều khiển như lặp , rẽ nhánh mà không có trong SQL Những ngôn ngữ có cấu trúc phức tạp hơn SQL nhưng chúng mềm dẻo và mạnh hơn SQL

OCI cho phép phát triển những ứng dụng mà trong đó có sự liên kết khả năng truy cập dữ liệu của SQL và C OCI hổ trợ tất cảcác định nghĩa dữ liệu SQL , thao tác dữ liệu , truy vấn , các điều khiển thuận lợi mà đã có sẳn trong Oracle8 Server

PL/SQL cũng có nhiều thuận lợi vì nó là mở rộng từ Oracle theo thủ tục đến SQL Theo đó các ứng dụng có thể phát triển mềm dẻo và mạnh hơn các ứng dụng chỉ viết bằng SQL Vì vậy OCI cung cấp các thuận lợi trong việc truy cập và thao tác các đối tượng trong Oracle 8 Server

OCI là một phần mềm giao tiếp cho phép thao tác dữ liệu và sơ đồ CSDL Oracle Hình 1-1 cho thấy việc dịch và liên kết một chương trình OCI tương tự như việc dịch và liên kết một ứng dụng không phải là CSDL Không cần bước xử lý trước hoặc dịch trước

Hình 1-1 : Quá trình phát triển OCI

Chú ý : Trong một số phần cứng chuẩn cần một số thư viện khác thêm vào thư viện OCI để liên kết các chương trình OCI đúng đắn hơn Cần kiểm tra tài liệu về hệ thống Oracle của bạn để biết cần phải thêm những thư viện nào cần thêm vào.

II- Các phát biểu SQL

Trang 2

Một trong những việc chính của SQL là xử lý các phát biểu Các phát biểu khác nhau cần những bước xử lý khác nhau Điều này rất quan trọng trong việc mã hoá ứng dụng OCI Oracle8 thừa nhận 8 loại phát biểu sau :

ª Ngôn ngữ định nghĩa dữ liệu (DDL) ª Các phát biểu điều khiển

ª Điều khiển thực thi ª Điều khiển hệ điều hành ª Điều khiển hệ thống

ª Ngôn ngữ thao tác dữ liệu (DML) ª Truy vấn

Ghi chú: các truy vấn được phân loại như các phát biểu DML nhưng các ứng dụng OCI xử lý truy vấn khác nhau Vì vậy chúng phải được suy nghĩ một cách riêng biệt

ª PL/SQL ª SQL nhúng

1 Ngôn ngữ định nghĩa dữ liệu

Các phát biểu DDL quản lý sơ dồ các đối tượng trong CSDL Các phát biểu DDL tạo ra các bảng mới , xoá các bảng cũ , thiết lập sơ đồ các đốitượng khác Vì vậy chúng diều khiển truy cập đến một sơ đồ các đối tượng Ví dụ :

CREATE TABLE employees

GRANT UPDATE , INSERT ,DELETE ON employees TO joe

Các phát biểu DDL cũng cho phép bạn làm việc với các object trong Oracle8 Server các phát biểu sau sẽ tạo ra một bảng các object

CREATE TYPE person_t AS OBJECT( name VARCHAR2(30),

ssn VARCHAR2(12), address VARCHAR2(50)) CREATE TABLE person_tab OF person_t

2 Các phát biểu điều khiển

Các ứng dụng OCI giải quyết các điều khiển thực thi , điều khiển hệ điều hành , diều khiển hệ thống tương tự như các phát biểu DML

3 Ngôn ngữ thao tác dữ liệu

Các phát biểu DML có thể thay dữ liệu trong các bảng CSDL Chẳng hạn các phát biểu DML dung để :

 Thêm các hàng vào một bảng

 Cập nhật các giá trị của các cột tồn tại trong các hàng

Trang 3

 Xoá các hàng trong một bảng  Khoá một bảng trong CSDL

 Giải quyết quá trình thực thi cho một phát biểu SQL

Các phát biểu DML có thể yêu cầu một ứng dụng cung cấp dữ liệu cho CSDL , là đầu vào được đóng gói (binding)

Binding

Hầu hiết các phát biểu DML và một số truy vấn yêu cầu một chương trình đưa dữ liệu vào Oracle như là một phần của các phát biểu SQL hoặc PL/SQL Khi chương trình được dịch cần phải biết dữ liệu là hằng hay dạng chữ Ví dụ phát biểu SQL sau sẽ thêm một employee vào CSDL

Một phát biểu cứng nhắc như vậy sẽ có một vài hạn chế Bạn phải thay đổi phát biểu và dịch lại chương trình mỗi khi thêm employee mới vào CSDL Để chương trình mềm dẻo hơn bạn có thể viết chương trình để user nhập dữ liệu mỗi khi chương trình chạy

Khi chuẩn bị cho một phát biểu SQL hoặc khối PL/SQL mà dữ liệu được cung cấp vào lúc chạy Ví dụ , phát biểu SQL có 5 nơi giữ dữ liệu đại diện cho 5 đầu vào dữ liệu (bắt đầu bằng ":")

INSERT INTO emp VALUES

Bạn có thể dùng nơi giữ dữ liệu đại diện cho các biến đầu vào trong các phát biểu DELETE , INSERT , SELECT , UPDATE hoặc khối PL/SQL ở bất kỳ vị trí nào của phát biểu , chúng có thể là biểu thức hoặc giá trị dạng chữ Đối với khối PL/SQL các nơi giữ dữ liệu có thể đại diện cho các biến đầu ra Tên của chúng không được dùng để đặt tên cho các đối tượng khác của Oracle như table hoặc column

đối với mỗi nơi giữ dữ liệu trong phát biểu SQL hoặc khối PL/SQL bạn phải gọi một thủ tục OCI mà nhận địa chỉ của biến chỉ đến nơi chứa dữ liệu Khi phát biểu thực thi , Oracle nhận dữ liệu mà chương trình đặt trong input , bind , biến và gởi nó đến server cùng với phát biểu SQL đó

4 Các truy vấn

Truy vấn là phát biểu nhận dữ liệu từ một CSDL Một truy vấn có thể trả về không , một , hoặc nhiều hàng dữ liệu Tất cả các truy vấn bắt đầu bằng từ khóa SELECT

Các truy vấn truy cập dữ liệu trong các bảng và chúng được phân loại cùng với các phát biểu DML Tuy nhiên các ứng dụng OCI xử lý các truy vấn khác nhau , do vậy chúng phải được xác định riêng biệt

Các truy vấn yêu câàu chương trình cung cấp dữ liệu đến CSDL sử dụng các biến đầu vào (bind) như ví dụ sau :

SELECT name

WHERE empno= :empnumber

Trong phát biểu SQL trên , :empnumber là một nơi giữ dữ liệu đại diện cho một giá trị sẽ được cung cấp bởi ứng dụng đó

Khi xử lý một truy vấn , một ứng dụng OCI cần định nghĩa các biến output để nhận các giá trị trả về Trong phát biểu trên cần định nghĩa một biến output để nhận giá trị name trả về

Trang 4

Các phát biểu sẽ trả dữ liệu liệu về từ CSDL đến ứng dụng của bạn Khi xử lý một truy vấn bạn phải định nghĩa một biến output hoặc một mảng các biến output cho mỗi phát biểu SELECT mà bạn muốn nhận dữ liệu từ nó Bước định nghĩa sẽ tạo ra sự kết hợp để xác định nơi chứa kết quả trả về và theo định dạng gì

Bạn cần phải định nghĩa hai output , một để nhận giá trị trả về từ cột name , một để nhậngiá trị trả về từ cột ssn

5 PL/SQL

PL/SQL là các mở rộng theo hướng thủ tục của SQL PL/SQL xử lý các công việc phức tạp hơn các truy vấn và các phát biểu SQL PL/SQL cho phép nhóm một số phát biểu thành một khối đơn và thực thi như một đơn vị Đó là :

 Một hoặc nhiều phát biểu SQL  Các khai báo biến

 Các phát biểu phân công

 Các phát biểu điều khiển thủ tục như : IF…THEN…ELSE , LẶP  Ngoại trừ handing

Có thể dùng khối PL/SQL trong chương trình để :  Gọi các thủ tục và hàm

 Dịch các phát biểu điều khiển thủ tục cùng với các phát biểu SQL để thực thi như một đơn vị

 Truy cập các thuộc tính PL/SQL đặc biệt như record , table , con trỏ các vòng lặp , ngoại trừ handing

 Sử dụng các biến con trỏ

 Truy cập và thao tác các đối tượng trong một Oracle8 server

Ví dụ PL/SQL sau cho thấy một phát biểu SQL để nhận những giá trị từ một bảng employees Ví dụ này giải thích cách sử dụng nơi giữ dữ liệu trong các phát biểu PL/SQL

Với ý nghĩa đó các nơi giữ dữ liệu không phải là các biến PL/SQL mà chúng chỉ tượng trưng cho các biến đầu vào khi phát biểu được xử lý Chúng cần để giao tiếp với các biến của C trong chương trình của bạn

6 SQL nhúng

OCI xử lý các phát biểu như là các câu của văn bản mà một ứng dụng truyền đến Oracle thực thi Các trình biên dịch trước của Oracle (Pro*C/C++ , Pro*COBOL , Pro* FORTRAN) cho phép lập trình viên nhúng các phát biểu SQL trực tiếp vào mã chương trình ứng dụng của họ Bước dịch trước là cần thiết để tạo ra một ứng dụng có thể thực thi

Trang 5

III Các từ đặc biệt của OCI

Các từ đặc biệt để chỉ các phần khác nhau của một phát biểu SQL Ví dụ một phát biểu SQL

bao gồm các phần sau : + Một lệnh SQL : SELECT

+ Hai select-list item : customer và address

+ Một tên của bảng trong mệnh đề FROM : customers

+ Hai cột trong mệnh đề WHERE : bus_type và sales_volume

+ Một giá trị đầu vào dạng chữ trong mệnh đề WHERE : 'SOFTWARE'

+ Một nơi giữ dữ liệu tượng trưng cho một biến đầu vào trong phần thứ hai của mệnh đề WHERE : :sales

Khi phát triển một ứng dụng OCI bạn gọi địa chỉ của các biến vào/ra trong chương trình Đa

chỉ của nơi giữ dữ liệu đại diện cho dữ liệu vào gọi là bind operation Địa chỉ của các biếnđể nhận select-list items gọi là define operation Đối với PL/SQL đều được gọi làoperation

IV Đối tượng hổ trợ trong OCI

Oracle server có những thuận lợi để làm việc với kiểu đối tượng và các đối tượng Một

object type là một cấu trúc dữ liệu mô tả một phần tử của thế giới thực do user định nhĩa Ví

dụ , một CSDL có thể chứa một định nghĩa của đối tượng mà đối tượng đó bao gồm các thuộc tính first-name , last-name , age mô tả những đặc trưng về định danh của con người trong thế giới thực

Định nghĩa object type là cớ sở cho việc tạo các oject mà mô tả các thực thể của object type Sử dụng object type như là định nghĩa cấu trúc , một đối tượng người được tạo ra với các thuộc tính 'Jonh' , Bonivento' , '30' Các object type có thể chứa các method

OCI của Oracle8 bao gồm các hàm mà có nhiều khả năng điều khiển các oject trong Oracle server Đặc biệt là các khả năng sau được thêm vào OCI :

+ Hổ trợ việc thực thi các phát biểu SQL thao tác dữ liệu và thông tin sơ đồ

+ Hổ trợ việc tham chiếu đến các đối tượng và thực thể như các biến đầu vào của phát biểu SQL

+ Hổ trợ việc tham chiếu đến các đối tượng và thực thể như các biến đầu ra cho các phát biểu SQL

+ Hổ trợ việc tham chiếu đến các đối tượng và thực thể từ một CSDL

+ Hổ trợ việc mô tả những thuộc tính của một phát biểu SQL mà nó trả về là các thực thể và các tham chiếu

+ Hổ trợ việc mô tả các thủ tục hoặc hàm của PL/SQL mà có các tham số hoặc kết là đối tượng

Thêm vào đó OCI hổ trợ cho việc thao tác trên các object sau khi chúng được truy cập bởi các phát biểu SQL

V Các loại hàm của OCI

OCI bao gồm 4 tập hàm chính :

Trang 6

1 OCI relational function : quản lý truy cập dữ liệu và xử lý các phát biểu SQL

2 OCI navigational function : thao tác các đối tượng nhận được từ một Oracle8 server

3 OCI datatype mapping and munipulation function : thao tác trên các thuộc tính dữ liệu của các kiểu Oracle8

4 OCI external procedure function : dùng để viết C gọi từ PL/SQL

VI Những đặc tính mới của Release 8.0

R 8.0 có những đặc tính mới và những thuận lợi cho việc thực hiện :  Tăêng các chu trình client-side và giảm các yêu cầu server-side  Phát biểu SELECT trả về tập các hàng

 API truy cập đến các đối tượng và dữ liệu có liên quan  Giảm số chuyến đi vòng tròn trên mạng

 Có khả năng điều khiển các cột LOB

 Một tập API gọi thực hiện các thao tác trên LOB và trên FILE  Cải tiến các khả năng của NLS (National Language Support)

 Có sự duy chuyển đường dẫn trong OCI và có một số khả năng trộn lẫn việc gọi cũ và mới trong một ứng dụng

 Cải tiến hổ trợ cho nhiều môi trường

 Các chức năng thêm vào cung cấp việc truy cập qua lại các object trong một Oracle8 server

VII.Tại sao phải sử dụng OCI ?

Nói chung có nhiều phương pháp truy cập vào một Oracle database như sử dụng ODBC , SQL *Plus … Nhưng OCI giúp truy cập trực tiếp vào Oracle database tiết kiệm được thời gian truy cập Vấn đề thời gian truy cập càng trở nên có ý nghĩa đối với một database lớn

Tuy nhiên các hàm OCI rất phức tạp(có nhiều thông số ) trở không thân thiện đối với người dùng Muốn sử dụng được OCI đòi hỏi người dùng phải am hiểu khá tỉ mỉ về nó Vì thế mục đích của đề tài này là xây dựng một giao diện lập trình thân thiện hơn mà người dùng chỉ cần thao tác một số bước cơ bản thì có thể thực hiện truy cập nhanh chóng và dễ dàng

VIII Một số khái niệm

1 Database server : là khóa để giải quyết vấn đề quản lý thông tin , quản số lượng lớn dữ

liệu và cho phép nhiều user truy cập đồng thời cùng một dữ liệu

Một Oracle server bao gồm : một Oracle server instance và một Oracle database

2 Oracle instance : là sự liên kết giữa các background process và vùng nhớ toàn cục

(System Global area) vùng nhớ dùng chung cho các dữ liệu của user Một Oracle instance có hai loại process :

 user process : thực thi mã của chương trình ứng dụng

 oracle process : thực thi các công việc của user process và background process nhằm quản lý công việc của oracle server

3 Oracle database : là một hợp các dữ liệu được xem như một đơn vị , chứa và nhận các

thông tin có liên quan với nhau Một oracle database có thể mở(acessable) hoặc đóng(unacessable)

4 Cấu trúc của Oracle database : bao gồm

 Logical structure

Trang 7

 Physical structure : có 3 loại file + data file : chứa dữ liệu

+ redo log file : ghi nhận các thay đổi data nhằm ngăn chặn các lỗi + control file : dùng để nhận diện database và redo log file

5 Cursor(hay handle) : oracle dùng các vùng dành riêng (private SQL areas) để thi hành

các câu lệnh SQL và lưu trữ thông tin của quá trình Một cursor là một cấu trúc PL/SQL cho phép định danh các vùng này và truy cập thông tin trong nó

6 Oracle process : là các process mà sẽ được gọi bởi các process khác để thực hiện công

việc theo yêu cầu của các process khác này Có 2 loại :

 Server process : nhận các yêu cầu của các user process được nối kết đến Nó giao tiếp với các user process và tác động vào Oracle để mang về các kết quả theo yêu cầu cho user

 Background process : Oracle tạo một tập các background process cho mỗi instance Nhằm đồng bộ việc thực hiện I/O và giám sát các Oracle process từ đó làm tăng tính xử lý song song để thực thi công việc tốt hơn

7 Program interface :là cơ cấu mà một user process giao tiếp một server process

8 Transaction : là một đơn vị công việc luận lý bao gồm nhiều SQL statement Một

transaction bắt đầu với SQL statement có thể thực thi đầu tiên và kết thúc khi nó được commit hoặc rallback

Một transaction kết thúc khi xảy ra một trong số các điều sau :  Sử dụng commit statement hoặc rallback statement

 Thực thi DDL statement Nếu transaction hiện tại chứa bất kỳ DML(such as CREATE, DROP, RENAME, ALTER) statement nào thì đầu tiên Oracle sẽ commit transaction hiện tại rồi thực thi và commit DDL như một transaction mới

 Disconnect từ Oracle

 Một user process kết thúc không bình thường

Sau khi kết thúc một transaction SQL statement có thể thực thi tự động bắt đầu transaction tiếp theo

tầm quan trọng của transaction : Oracle duy trì tính nhất quán dữ liệu dựa vào các transaction Các transaction cho phép ta điều khiển linh hoạt khi làm việc với dữ liệu và bảo vệ sự toàn vẹn dữ liệu ngay cả trong trường hợp gặp sự cố hệ thống

Commit transaction : nghĩa là tạo những thay đổi thường xuyên bới các SQL statement trong

transaction đó

Trước khi một transaction sữa chữa dữ liệu được commit thì xảy ra các d-iều sau :

 Oracle tạo ra các rollback segment record trong vùng đệm rollback segment của SGA(system global area) để chứa các giá trị dữ liệu cũ đã bị thay đổi bởi các SQL statement của transaction

 Oracle đã tạo ra các redo leg trong redo log buffer của SGA Những thay đổi này có thể được ghi vào đĩa trước khi commit transaction

 Các thay đổi được đưa đến database buffer và chúng có thể đi đến đĩa trước khi một transaction thực sự được commit

Khi một transaction được commit xảy ra các điều sau :

Trang 8

 Bảng transaction bên trong nối kết với các bảng ghi phân đoạn rollback(rollback segment records) mà transaction đã được commit để ghi vào bảng unique system change number(SCN) của transaction đó

 Process log writer ghi các redo log và SCN vào redo log file Đây sự kiện cơ bản để thiết lập commit transaction

 Oracle mở khóa trên các row và table  Oracle đánh dấu transaction là "complete"

Rollback transaction : không tạo bất kỳ thay đổi dữ liệu nào mà đã được thực hiện bởi SQL

statement trong một uncommit transaction Oracle cho phép rollback toàn bộ một uncommit transaction hoặc từ một savepoint

IX Giới thiệu Net8

Net8 là lớp phần mềm được sử dụng để giao tiếp giữa client và server hoặc giữa các server Các user process và server process trên các máy khác nhau giao tiếp với nhau thông qua Net8

Net8 là một cơ cấu các protocol thực hiện việc phân bố xử lý và phân bố database Các protocol định nghĩa cách truyền và nhận data trên một mạng

Trong đề tài này việc truy cập oracle database cũng nhờ Net8 để truyền và nhận dữ liệu Hình dưới là kiến trúc của Net8 và chương trình ứng dụng sử dụng thư viện OCI để truy cập vào Oracle database

Trang 9

CHƯƠNG II : CÁC BƯỚC CƠ BẢN LẬP TRÌNH OCI I Cấu trúc chương trình OCI

Nói chung mục tiêu của một ứng dụng OCI là nối kết đến Oracle Server , chọn trước một số loại trao đổi data thực hiện việc xử lý data Mỗi ứng dụng OCI được thực hiện theo trình tự các bước như hình 2-1:

Hình 2-1 : Lưu đồ chương trình OCI cơ bản

Trên đây là các bước của một chương trình OCI tổng quát Tuy nhiên tùy thuộc vào chức năng của chương trình (quản lý nhiều giao tiếp , sử dụng object ,…) thì có thể cần thêm một số bước

Quá trình OCI chỉ được khởi tạo một lần , một ứng dụng có thể tạo nhiều môi trường như được minh họa ở hình 2-2 :

Initialize Process

Trang 10

II Các cấu trúc của data OCI

Handle và Descriptor là hai cấu trúc không trong suốt được định nghĩa trong các ứng dụng OCI và có thể được chỉ định trực tiếp thông qua các cách gọi được chỉ định rõ ràng , hoặc chỉ định ẩn bởi các hảm OCI

Handle và Descriptor chứa thông tin liên quan đến data , các nối kết hoặc cách thực hiện của ứng dụng

III Handle

Hầu hết Oracle8 OCI gọi danh sách tham số của chúng hoặc nhiều handle một handle là một pointer không trong suốt trỏ đến một vùng lưu trữ được chỉ định bởi thư viện OCI Một handle có thể được sử dụng để chứa phạm vi hoặc thông tin nối kết , hoặc có thể chứa thông

Free Handles &

Data StructuresData StructuresFree Handles &

Trang 11

tin về các hàm OCI hoặc data Handle có thể lập trình ứng dụng dễ hơn , bởi vì có thư viện để quản lý data này

Hầu hết các ứng OCI cần truy cập thông tin được lưu trữ trong handle để truy cập thông tin

này ta dùnh hai hàm OCI OCIAttrGet() và OCIAttrSet()

Bảng dưới đây đưa ra danh sách các handle được định nghĩa cho OCI Mỗi kiểu handle , kiểu data C và kiểu handle hằng số được đưa ra

Table 2-1 OCI Handle Types

1 Chỉ định và hủy bỏ handle

Ứng dụng của bạn chỉ định các handle (trừ bind và define handle) thừa nhận môi trường handle riêng biệt Thông qua enviroment handle như một tham số handle chỉ định việc gọi Việc chỉ định handle là rõ ràng

Bind và define handle được chỉ thị với sự thừa nhận một phát biểu handle và chứa thông tin về phát biểu được mô tả bởi các handle đó

Bind và define handle hoàn toàn được chỉ định bởi thư việc OCI

Trang 12

Tất cả các handle do user chỉ định trừ enviroment handle phải được chỉ định bởi việc gọi hàm

OCIHandle() Enviroment handle được chỉ định và khởi tạo bằng việc gọi hàmOCIEnvInit() mà nó cần cho mọi ứng dụng OCI.

Một ứng dụng OCI phải giải phóng các handle khi chúng không còn cần thiết thông qua hàm

OCIHanleFree() Khi một handle cha bị giải phóng , tất cả các handle con có liên kết với

cũng bị hủy bỏ và không được sử dụng nữa Ví dụ , khi một phát biểu handle bị giải phóng thì bất kỳ bind và define handle có liên kết với nó cũng bị hủy bỏ

Handle tránh dùng biến toàn cục Handle cũng dự đoán lỗi dễ hơn Error handle được để trả về các lỗi

2 Enviroment handle

Enviroment handle xác định một ngữ cảnh mà các hàm OCI được gọi trong đó Mỗi enviroment handle chứa một vùng cashe cho phép điều khiển vùng nhớ nhanh chóng theo một môi trường thống nhất Khi có nhiều tuyến dùng chung một môi trường thì chúng sẽ khóa truy câp vùng cashe

Enviroment handle được chuyển đến OCIHandleAllocation() như tham số parenth để chỉ

định tất cả các kiểu handle khác , trừ bind và define handle

Trang 13

Error handke được truyền như một tham số trong hầu hết việc gọi hàm OCI Error handle quản lý thông tin về các lỗi xảy ra trong một hoạt động của OCI Nếu một lỗi xảy ra khi gọi

hàm , error handle được truyền đến OCIErrorGet() để thu được thông tin thêm về lỗi xảy ra

Chỉ định error handle là bước đầu tiê trong một ứng dụng OCI

4 Service context và associated handle

Một service context handle định nghĩa những thuộc tính mà xác định ngữ cảnh hoạt động của các lời gọi OCI đến server

Bạn phải chỉ định và khởi tạo service context handle thông qua các hàm

OCIHandleAllocation() hoặc OCILogon() trước khi sử dụng nó

Sevice context quản lý 3 handle :

 Server handle : nhận dạng nguồn dữ liệu

 user session handle : định nghĩa các vai trò , quyền của một user và ngữ cảnh hoạt động mà các hàm được gọi thực thi

 transaction handle : định nghĩa giao dịch mà các quá trình hoạt động của SQL đuợc thực hiện Phạm vi giao dịch bao gồm thông tin trạng thái user session , trạng thái định sẳn (fetch state ) và sự đóng gói nhanh (packe instantiation )

Các ứng dụng chỉ điều khiển một user session cho mỗi nối kết CSDL , tại một thơi điểm có

thể gọi OCILogon() để chỉ định service context và associated handle của nó

Trong các ứng dụng yêu cầu quản lý session phức tạp , service context phải được chỉ định rõ ràng , server handle và user session handle phải đặt rõng ràng trong service context thông

qua gọi hàm OCIServerAttach() và OCISessionBegin() riêng Một ứng dụng tốt cần xác định

giao dịch rõ ràng hoặc sự giao dịch tìm ẩn được tạo ra khi ứng dụng thay đổi CSDL

5 Statement handle , Bind handle và define handle

Một statement handle là ngữ cảnh nhận dạng phát biểu SQL hay PL/SQL và các thuộc tính liên kết của nó

Thông tin về biến input đã nói trong phần bind handle Thư viện OCI chỉ định một bind

handle cho mỗi phạm vi chứa bởi hàm OCIBindByName() hoặc OCIBindByPos() User

không cần phải chỉ định bind handle Chúng được chỉ định rõ ràng bằng lời gọi bind (bind call)

Để lưu data trả về bởi một truy vấn được cải tiến và lưu trữ theo sự định rõ của các define handle Thư viện OCi chỉ định một define handle cho mỗi biến output bằng hàm

OCIdefineByPos() User không cần chỉ định define handle Chúng được chỉ định rõ bằng lới

gọi define

6 describe handle

Để sử dụng describe ta gọi hàm OCIDescribeAny() Lời gọi này chứa thông tin về gis3n đồ

các object trong một CSDL (function , procedure) Lời gọi này nhận một describe handle như một tham số của nó, thông tin về object được mô tả trong đó Khi lời gọi hoàn thành describe handle được định vị với thông tin về object Ư&1ng OCI có thể chứa thông tin mô tả thông qua các thuộc tính của tham số mô tả

7 Security handle

8 Complex object retrieval (COR) handle

Được dùng cho một số ứng dụng OCI làm việc với các object trong một Oracle8 server Handle này chứa mô tả COR (COR Descritor ) cung cấp một số lệnh để OCI thu được các object mà được tham chiếu bởi các object khác

Trang 14

9 Các thuộc tính handle

Tất cả các OCI handle có những thuộc tính rõ ràng Những thuộc tính này htực hiện lưu trữ

data trong handle Dùng hàm OCIAttrGet() để đọc những thuộc tính handle , dùng hàmOCIAttrSet() để set thuộc tính

Ví dụ : các phát biểu sau set username trong transaction handle bằng cách viết thuộc tính OCI_ATTR_USERNAME

text username[] = "scott";

err = OCIAttrSet ((dvoid*) mysessp, OCI_HTYPE_SESSION, (dvoid*) username, (ub4) strlen(username), OCI_ATTR_USERNAME,

(OCIError *) myerrhp);

Tiếp theo việc set các tham số giải thích việc sử dụng OCIAttrGet() để đọc mã hàm của hàm OCI cuối cùng được xử lý trong một handle (trong trường hợp này là bind handle )

ub4 fcode = 0; OCIBind *mybndp;

err = OCIAttrGet( (dvoid*) mybndp, OCI_HTYPE_BIND, (dvoid*) &fcode, (ub4) 0, OCI_ATTR_FNCODE,(OCIError *) myerrhp);

Một số hàm OCI yêu cầu các thuộc tính handle phải được set trước một giá trị trước khi hàm Ví dụ , khi hàm OCISessionBegin() được gọi để thiết lập việc login của user thì username và password được đưa vào user session handle trước khi lời gọi hàm được tạo thành

Những hàm OCI khác hữu dụng để trả về data trong các thuộc tính của handle sau khi hàm hoàn tất chẳng hạn khi gọi hàm OCIStmtExcute() để thực thi một truy vấn SQL thì thông tin mô tả liên quan đến select-list items được trả về trong statement handle

10 Chỉ định vùng nhớ cho user

Kni gọi hàm OCIEnvInit() thì enviroment handle được khởi tạo đồng thời chỉ định handle chung (OCIHandleAlloc())và chỉ định descriptor /locator (OCIDescritorAlloc()) sẽ gọi một tham số xtramem_sz trong danh sách tham số của chúng Tham số này được dùng để định rõ tổng vùng nhớ của user sẽ được chỉ định cho handle đó

Tiêu biểu , mộtứng dụng sử dụng tham số này để chỉ định một cấu trúc định nghĩa ứng dụng mà có thời gian sống như handle

Cấu trúc này được sử dụng cho ứng dụng "bookeeping" hoặc chứa thông tin ngữ cảnh

Sử dụng tham số xtramem_sz có nghĩa là ứng dụng không cần chỉ định rõ và phân phối vùng nhớ cũng như mỗi handle được chỉ định và được phân phối Vùng nhớ này được chỉ định song song với handle cũng như việc giải phóng handle trong các cấu trúc data của user

IV Descriptors and Locators

OCI descriptors và Locator là các cấu trúc data không trong suốt quản lý các thông tin data rõ ràng OCI có 6 loại descriptor và locator được trình bày trong bảng 2-2 cùng với kiểu data của C và kiểu hằng của OCI mà nó chỉ định descriptor trong lời gọi đến hàm OCIDescriptoAlloc() Hàm OCIDescriptorAlloc() giải phóng các descriptor và locator

Table 2-2 Descriptor Types

Trang 15

OCILobLocator LOB datatype locator OCI_DTYPE_LOB

OCIComplexObjectComp complex object descriptor OCI_DTYPE_COMPLEXOBJECTCOMP

OCISnapshot : được dùng trong việc thực thi các phát biểu

OCILOBLocator : được sử dụng cho LOB (OCI_DTYPE_LOB) hoặc FILE (OCI_DTYPE_FILE)

OCIParam : được sử dụng cho các lời gọi mô tả

OCIRowid : đuợc sử dụng cho binding hoặc defining các giá trị ROWID OCIComplexObjectComp : được sử dụng cho thu các object phức hợp 1 OCISnapshot descriptor

Là một tham số tùy chọn để thực thi lời gọi hàm OCIStmtExcute() Nó ngụ ý rằng một truy vấn được thực thi tại một thời điểm tương phản với một database snapshot Một database snapshot mô tả trạng thái của một database tại một thời điểm

Có thể chỉ định một snapshot descriptor bằng lời gọi OCIDescriptorAlloc() thông qua tham số kiểu OCI_DTYPE_SNAP

2 LOB Datatype Locator

Một LOB (large object) là một kiểu data của Oracle có thể lê đến 4Gbytes data dạng nhị phân (BLOB) hoặc dạng ký tự (CLOB) Trong một database , một cấu trúc data không trong suốt gọi đến LOB Locator được lưu trong cột LOb của một của database hoặc thuộc tính LOB của một object Locator như một pointer trỏ đến giá trị LOB thực mà được chứa trong một vị trí riêng biệt

OCI LOB Locator được sử dụng để thực hiện các hoạt động của OCI tương ứng với một LOB (BLOB , CLOB) Các hàm OCI không nhận các giá trị LOB thực như các tham số , tất cả các lời gọi hoạt động trên cơ sở LOB locator Descriptor này , OCI Lob Locator cũng được sử dụng trong các hoạt động trên FILE

Chú ý : hai kiều LOB locator không được hoán đổi nhau khi liên kết hoặc định nghĩa một BLOB hặc CLOB , ứng dụng nhận locator hợp lệ khi chỉ định việc sử dụng OCI_DTYPE_LOB Tương tự đối với BFILE , ứng dụng phải chỉ định locator sử dụng OCI_DTYPE_FILE khi liên kết và định nghĩa

Một ứng dụng OCI có thể thu được một locator từ server bằng cách đưa ra một phát biểu SQL chứa cột LOB hoặc thuộc thuộc tính như là một phần tử trong select-list Trong ví dụ này OCI đầu tiên sẽ chỉ định LOB locator sau đó sử dụng nó để định nghĩa một biến output Tương tự , một LOB locator được sử dụng như một phần của một hoạt động liên kết để tạo một sự kết hợp giữa một LOB và một nơi chứa (placeholder)

Trong một phát biểu SQL :Kiểu data locator (OCI Lob Locator) là kiểu data không có hiệu lực khi nối kết với Oracle server

3 Parameter Descriptor

Các ứng dụng OCI sử dụng các parameter descriptor để thu được thông tin về các cột select-list hoặc giản đồ các object Thông tin này được thu thông qua một hoạt động mô tả

Trang 16

Parameter descriptor là một kiểu descriptor không chỉ định việc sử dụng OCIDescriptorAlloc() Bạn chỉ có thể thu được nó như một thuộc tính mô tả, phát biểu hoặc liên kết để thu được đối tượng phức hợp thông qua định rõ vị trí của tham số khi gọi OCIParametetGet()

4 ROWID descriptor

ROWID descriptor được sử dụng bởi các ứng dụng mà cần cần phục hồi và sử dụng các Oracle ROWID Kích thước và cấu trúc của ROWID đã bị thay đổi từ Oracle7 sang Oracle8 và nó không trong suốt đối với user Để làm việc với một ROWID sử dụng Oracle8 OCI , một ứng dụng có thể định nghĩa một ROWID descriptor với một vị trí trong select-list của SQL và thu được một ROWID vào descriptor Descriptor này sau đó được ràng buộc đến một biến input trong phát biểu INSERT hoặc mệnh đề WHERE

5 Complex object descriptor

Để sử dụng các object chương trình phải được khởi tạo trong chế độ OCI_OBJECT dùng hàm

OCIInitialize()

6 Chỉ định vùng nhớ cho user

Lời gọi hàm OCIDescriptorAlloc() có tham số xtramem_sz trong select-list Tham số này được dùng để định rõ vùng nhớ cho user được chỉ định cùng với locator hoặc descriptor tiêu biểu , một ứng dụng sử dụng tham số này để chỉ định một cấu trúc ứng dụng được định nghĩa có thời gian sống như descriptor hoặc locator Cấu trúc này được sử dụng cho ứng dụng "bookeeping" hoặc lưu trữ thông tin ngữ cảnh

Sử dụng tham số xtramem_sz có nghĩa là ứng dụng không cần chỉ định rõ ràng và phân phối vùng nhớ cũng như mỗi descriptor hoặc locator phải được chỉ định và phân phối Vùng nhớ này được chỉ định cùng với locator hoặc descriptor cũng như giải phóng descriptor hoặc locator khỏi cấu trúc data của user

Hàm OCIHandleAlloc() có một tham số giống như việc sử dụng vùng nhớ cho user mà có thời gian sống như handle

Hàm OCIEnvInit() có một tham số giống như việc sử dụng vùng nhớ cho user mà có thời gian sống như enviroment handle

V Các bước lập trình OCI

Mỗi bước bạn thực hiện trong một ứng dụng OCI được mô tả chi tiết hơn trong các phần sau Một vài bướclà tùy ý Chẳng hạn bạn không cần phải mô tả hoặc định nghĩa select-list items nếu phát biểu không phải là một truy vấn

Các phần sau mô tả các bước được yêu cầu đối với một ứng dụng Oracle8 OCI : Có 3 bước chính để khởi tạo môi trường OCI :

1 Khởi tạo một quá trình OCI

Quá trình khởi tạo OCIInitialize() phải được gọi trước khi gọi các hàm OCI khác Tham số mode định rõ ứng dụng chạy trong một môi trường liên kết (mode=OCI_THREAD) hoặc sẽ tạo ứng dụng các objedt(mode=OCI_OBJECT) Khởi tạo chế độ object nếu ứng dụng liên kết và định nghĩa các object hoặc ứng dụng sử dụng các object navigation của OCI

Vì vậy chương trình chọn để sử dụng hoặc những thuộc tính này (mode=OCI_DEFAULT) hoặc cả hai chọn lựa độc lập (mode=(OCI_THREAD | OCI_OBJECT))

User định rõ hàm OCIInitialize() để định nghĩa các hàm quản lý bộ nhớ

2 Chỉ định các handle và descriptor

Trang 17

Sử dụng hàm OCIHandleAlloc() để chỉ định các handle , trong trường hợp OCI đã chỉ định handle thì không cần dùng hàm này(chẳng hạn dùng hàm OCIDefineByPos() thì OCI chỉ định handle).

Tùy theo chức năng của ứng dụng mà một số handle trong các handle sau được chỉ định :  error handle (tùy chọn)

 service context handle (bắt buộc)  statement handle (bắt buộc)  describe handle (tùy chọn)  server handle (bắt buộc)  user session handle (bắt buộc)  transaction handle (tùy chọn)

 complex object retrieval handle (tùy chọn)

3.Khởi tạo , nối kết vào tạo session

Sau khi gọi hàm OCIInitialize() phải gọi hàm OCIEnvInit() để khởi tạo environment handle Lúc này có hai tùy chọn

Tùy chọn 1 : Single User, Single Connection

Ứng dụng chỉ quản lý một single user session cho mỗi nối kết database tại một thời điểm với username và password cụ thể

Ví dụ :

OCILogon(envhp, errhp, &svchp, "scott", nameLen, "tiger", passwdLen, "oracle8", dbnameLen)

Kết thúc nối kết bởi hàm OCILogoff()

Trong trường hợp này service context, server và user session handles là chỉ đọc

Tùy chọn 2 :Multiple Sessions hoặc Connections

Sử dụng khi ứng dụng quản lý nhiều user session trên một nối kết database Phải sử dụng các hàm

 OCIServerAttach() :để tạo đường truy cập nguồn dữ liệu

 OCISessionBegin() : cho phép user có thể làm việc trên server đó

4.Xử lý SQL

5.Commit hoặc Rollback

Để ghi nhận thay đổi đến database dùng hàm OCITransCommit() Ứng dụng có thể tạo transaction tường minh hoặc không tường minh

Để rollback một transaction dùng hàm OCITransRollback() Nếu ứng dụng disconnect từ Oracle mà không phải logout và không gọi hàm OCITransCommit() thì các transaction tích cực được tự động rollback

6.Kết thúc ứng dụng

Phải gọi các hàm sau đây ở bước kết thúc ứng dụng OCI: 1 OCISessionEnd() : để xoá user session cho mỗi session

2 OCIServerDetach() :xoá đường truy cập vào mỗi dữ liệu nguồn 3 OCIHandleFree() :giải phóng các handle

Hoặc

4 Xoá environment handle(các handle liên kết với nó đực giải phóng tự động)

Trang 18

ƠNG III : CÁC KIỂU DỮ LIỆU

Giá trị dữ liệu được lưu bên database theo định dạng riêng được gọi là kiểu dữ liệu bên trong (internal datatype) Ví dụ : CHAR , NUMBER , DATE

Chương trình ứng dụng không làm việc với kiểu dữ liệu bên trong mà chỉ làm việc với kiểu dữ liệu của một ngôn ngữ lập trình cụ thể Khi có sự truyền dữ liệu giữa OCI client program và database table thì thư viện OCI sẽ chuyển đổi từ internal datatype sang external datatype External datatype là các kiểu dữ liệu của một ngôn ngữ lập trình , nó được định nghĩa trong các file header

Table 3-1 Internal Oracle Datatypes

Internal Oracle Datatype Maximum Internal Length Datatype Code

User-defined type (object type,

Null-terminated

Trang 19

LONG 8 char[n] SQLT_LNG

ROWID

NAMED

Table 3-4 Format of the DATE Datatype

Trang 20

typedef int eword; typedef unsigned int uword; typedef signed int sword; #else

#define eword int

#define uword unsigned int #define sword signed int

Trang 21

#endif

#define EWORDMAXVAL ((eword) INT_MAX) #define EWORDMINVAL ((eword) 0)

#define UWORDMAXVAL ((uword)UINT_MAX) #define UWORDMINVAL ((uword) 0)

#define SWORDMAXVAL ((sword) INT_MAX) #define SWORDMINVAL ((sword) INT_MIN) #define MINEWORDMAXVAL ((eword) 32767) #define MAXEWORDMINVAL ((eword) 0) #define MINUWORDMAXVAL ((uword) 65535) #define MAXUWORDMINVAL ((uword) 0) #define MINSWORDMAXVAL ((sword) 32767) #define MAXSWORDMINVAL ((sword) -32767)

typedef unsigned char ub1; typedef signed char sb1; #else

#define eb1 char

#define ub1 unsigned char #define sb1 signed char #endif

#define EB1MAXVAL ((eb1)SCHAR_MAX) #define EB1MINVAL ((eb1) 0)

Trang 22

#define SB1MAXVAL ((sb1)SCHAR_MAX) #define SB1MINVAL ((sb1)SCHAR_MIN) #define MINEB1MAXVAL ((eb1) 127) #define MAXEB1MINVAL ((eb1) 0) #define MINUB1MAXVAL ((ub1) 255) #define MAXUB1MINVAL ((ub1) 0) #define MINSB1MAXVAL ((sb1) 127) #define MAXSB1MINVAL ((sb1) -127) #define UB1BITS CHAR_BIT

#define UB1MASK ((1 << ((uword)CHAR_BIT)) - 1) typedef unsigned char OraText;

#ifndef LUSEMFC # define text OraText #endif

#ifndef lint

typedef short eb2; typedef unsigned short ub2; typedef signed short sb2; #else

#define eb2 short

#define ub2 unsigned short #define sb2 signed short #endif

#define EB2MAXVAL ((eb2) SHRT_MAX) #define EB2MINVAL ((eb2) 0)

#define UB2MAXVAL ((ub2)USHRT_MAX) #define UB2MINVAL ((ub2) 0)

#define SB2MAXVAL ((sb2) SHRT_MAX) #define SB2MINVAL ((sb2) SHRT_MIN) #define MINEB2MAXVAL ((eb2) 32767) #define MAXEB2MINVAL ((eb2) 0) #define MINUB2MAXVAL ((ub2) 65535) #define MAXUB2MINVAL ((ub2) 0) #define MINSB2MAXVAL ((sb2) 32767) #define MAXSB2MINVAL ((sb2)-32767) #if defined(A_OSF)

Trang 23

#ifndef lint

typedef int eb4; typedef unsigned int ub4; typedef signed int sb4; #else

#define eb4 int

#define ub4 unsigned int #define sb4 signed int #endif

#define EB4MAXVAL ((eb4) INT_MAX) #define EB4MINVAL ((eb4) 0)

#define UB4MAXVAL ((ub4) UINT_MAX) #define UB4MINVAL ((ub4) 0)

#define SB4MAXVAL ((sb4) INT_MAX) #define SB4MINVAL ((sb4) INT_MIN)

#define MINEB4MAXVAL ((eb4) 2147483647) #define MAXEB4MINVAL ((eb4) 0) #define MINUB4MAXVAL ((ub4) 4294967295) #define MAXUB4MINVAL ((ub4) 0) #define MINSB4MAXVAL ((sb4) 2147483647) #define MAXSB4MINVAL ((sb4)-2147483647) #else

#ifndef lint

typedef long eb4; typedef unsigned long ub4; typedef signed long sb4; #else

#define eb4 long

#define ub4 unsigned long #define sb4 signed long #endif

#define EB4MAXVAL ((eb4) LONG_MAX) #define EB4MINVAL ((eb4) 0)

#define UB4MAXVAL ((ub4)ULONG_MAX) #define UB4MINVAL ((ub4) 0)

#define SB4MAXVAL ((sb4) LONG_MAX) #define SB4MINVAL ((sb4) LONG_MIN) #define MINEB4MAXVAL ((eb4) 2147483647) #define MAXEB4MINVAL ((eb4) 0)

Trang 24

#define MINUB4MAXVAL ((ub4) 4294967295) #define MAXUB4MINVAL ((ub4) 0) #define MINSB4MAXVAL ((sb4) 2147483647) #define MAXSB4MINVAL ((sb4)-2147483647) #endif

#ifndef lint

typedef unsigned long ubig_ora; typedef signed long sbig_ora; #else

#define ubig_ora unsigned long #define sbig_ora signed long #endif

#define UBIG_ORAMAXVAL ((ubig_ora)ULONG_MAX) #define UBIG_ORAMINVAL ((ubig_ora) 0)

#define SBIG_ORAMAXVAL ((sbig_ora) LONG_MAX) #define SBIG_ORAMINVAL ((sbig_ora) LONG_MIN) #define MINUBIG_ORAMAXVAL ((ubig_ora) 4294967295) #define MAXUBIG_ORAMINVAL ((ubig_ora) 0) #define MINSBIG_ORAMAXVAL ((sbig_ora) 2147483647) #define MAXSBIG_ORAMINVAL ((sbig_ora)-2147483647) #define UBIGORABITS (UB1BITS * sizeof(ubig_ora))

#define UB8ZERO ((ub8)0) #define UB8MINVAL ((ub8)0)

#define UB8MAXVAL ((ub8)18446744073709551615) #define MAXUB8MINVAL ((ub8)0)

#define MINUB8MAXVAL ((ub8)18446744073709551615)

Trang 25

#if defined(PMAX) && defined( STDC ) # define CONST const

# ifdef M88OPEN # define CONST const # else

# if defined(SEQ_PSX) && defined( STDC ) # define CONST const

Trang 27

CHƯƠNG IV : XỬ LÝ PHÁT BIỂU SQL

Sơ đồ các bước xử lý phát biểu SQL

Các bước xử lý SQL:

Trang 28

Gọi hàm OCIStmtPrepare() Đây là giai đoạn chuẩn bị cục bộ , ứng dụng có thể dùng hàm OCIAttrGet() (tham số attrtype=OCI_ATTR_STMT_TYPE ) xác định loại phát biểu gì được thực thi

Ở giai đoạn này có thể chuẩn bị phát biểu để thực thi trên nhiều servers cùng một lúcbằng cách liên kết statement handle với các context handle của riêng từng server Khicó liên kết mới được tạo thành thì toàn bộ thông tin về mối liên kết hiện tại giữa servicecontext và statement handle bị mất

Table 4-1 OCI_ATTR_STMT_TYPE Values and Statement Types

Để chương trình trở nên mềm dẻo hơn , chẳng hạn cung cấp dữ liệu vào lúc chạy chương trình , ta thực hiện công việc liên kết nơi chứa dữ liệu với biến chương trình gọi là binding Ví dụ : với phát biểu

INSERT INTO emp(empno) VALUES :num

Ta phải liên kết địa chỉ của biến trong chương trình với nơi chứa ":num" trong phát biểu Binding một nơi chứa là thực hiện một hoặc nhiều bước Đối với kiểu dữ liệu vô hướng đơn hoặc mảng bind thì chỉ cần sử dụng hàm OCIBindByName() hoặc OCIBindByPos()

Liên kết được tạo bởi tên của nơi chứa dữ liệu trong phát biểu gọi là named bind (sử dụng hàm OCIBindByName()) , còn liên kết được tạo bởi vị trí của nơi chứa bắt đầu từ số 1 gọi positional bind (sử dụng hàm OCIBindByPos()) Trong ví dụ trên named bind là ":num" , còn positional bind là 1.

Trong trường hợp cần nạp nhiều giá trị dữ liệu vào database mà chỉ cần một lời gọi hàm đến OCIStmtExecute() phải dùng mảng giao tiếp (array interface) ,khi đó bind một array với một nơi chứa dữ liệu đầu vào và mảng này được nạp cùng lúc vào database dước sự điều khiển của tham số iters

Chú ý rằng các output variable của PL/SQL phải sửng binding chứ không phải defining Bind mảng tĩnh sử dụng hàm OCIBindByPos() hoặc OCIBindByName() rồi sau đó sử dụng hàm OCIBindArrayOfStruct() Khi bind mảng tĩnh phải sử dụng mảng các cấu trúc , đây là đặc tính mới của Oracle8 OCI để hoạt động trên nhiều dòng và nhiều cột Mảng các cấu trúc do người lập trình định nghĩa và khi đó người lập trình phải xác định tham số nhảy (skip parameter)

Trang 29

OCI hổ trợ mệnh đề RETURNING cho các phát biểu INSERT ,UPDATE , DALETE để nhận dữ liệu trả về mà không phát biểu khác

Ví dụ :

Với phát biểu

INSERT INTO table1 VALUES (:1, :2, :3,) RETURNING col1, col2, col3

INTO :out1, :out2, :out3

Sau khi dữ liệu được insert thì chúng được trả về thông qua các biến liên kết với các nơi chứa dữ liệu đầu ra.

Phát biểu tiếp theo sẽ cập các giá trị ở các cột col1 ,col2 ,col3 rồi sau đó trả về các giá trị sau khi chúng được sửa đổi

UPDATE table1 SET col1 = col1 + :1, col2 = :2, col3 = :3 WHERE col1 >= :low AND col1 <= :high

RETURNING col1, col2, col3 INTO :out1, :out2, :out3

Phát biểu DELETE sẽ xoá các dòng thoả điều kiện trong mệnh đề WHERE rồi sau đó trả về các giá trị này để kiểm tra

DELETE FROM table1 WHERE col1 >= :low AND col2 <= :high RETURNING col1, col2, col3

INTO :out1, :out2, :out3

Các bước bind các biến trong mệnh đề RETURNING :

1 Bind các nơi chứa trong chế độ OCI_DATA_AT_EXEC dùng hàm OCIBindByPos hoặc OCIBindByName rồi sau đó gọi hàm OCIBindDynamic()

2 Cung cấp hàm bind đầu ra được xem như là tham số ocbfp trong hàm OCIBindDynamic() để nhận dữ liệu trả về

3 Cung cấp hàm giả trả về giá trị NULL khi gọi được xem như là tham icbfp trong hàm OCIBindDynamic()

4 Tham số piecep trong hàm OCIBindDynamic() phải là OCI_ONE_PIECE 5 Không có các bind giống nhau trong phát biểu với mệnh đề RETURNING

III Thực thi phát biểu

Sử dụng hàm OCIStmtExecute() để thực thi một phát biểu đã được prepare Khi truy vấn được thực thi thì ứng có thể cần chuyển đổi dữ liệu sang định dạng của một ngôn ngữ lập trình cụ thể và dữ liệu được trả về trong các biến output hoặc vùng đệm Để nhận dữ liệu trả về cần phải defining một biến output cho mỗi phần tử trong select-list của truy vấn

Đối với phát biểu SELECT nếu các biến output được định nghĩa trước khi gọi hàm OCIStmtExecute() thì phải chỉ rõ số dòng cần nhận trực tiếp vào vùng đệm output thông qua tham số iters

Đối với các phát biểu không phải là truy vấn (INSERT chẳng hạn) thì tham số iters điều khiển phát biểu được bao nhiêu lần

IV Mô tả các phần tử trong danh sách chọn(select-list)

Nếu ứng dụng xử lý một truy vấn mà không biết thông tin về các phần tử trong select-list Trong trường hợp này cần mô tả để nhận datatype và chiều dài của cột

Ví dụ : với truy vấn SELECT * FROM emp;

Trang 30

Ta cần phải mô tả nó

Khi mô tả phải gọi hàm OCIStmtExcute() trong chế độ OCI_DESCRIBE_ONLY , ở chế độ này không thực thi phát biểu nhưng sẽ trả về thông tin của các phần tử trong select-list  Mô tả không tường minh : để nhận thông tin của các phần tử trong select-list phải gọi

hàm OCIParamGet() cho mỗi phần tử với tham số pos bắt đầu từ 1 cho đến khi OCI_NO_DATA được trả về Một khi tham số descritor được chỉ định thì gọi hàm OCIAttrGet() trên descritor đó để nhận datatype và chiều dài lớn nhất của dữ liệu (riêng kiểu NUMBER thì maxsize=22 được trả về)

Sau đây là ví dụ về mô tả phát biểu (đã được prepare)không tường minh :

parm_status = OCIParamGet(stmthp, OCI_HTYPE_STMT, errhp, &mypard, (ub4) counter); /* Loop only if a descriptor was successfully retrieved for current position, starting at 1 */ while (parm_status==OCI_SUCCESS)

/* Retrieve the data type attribute */

checkerr(errhp, OCIAttrGet((dvoid*) mypard, (ub4) OCI_DTYPE_PARAM, (dvoid*) &dtype,(ub4 *) 0, (ub4) OCI_ATTR_DATA_TYPE, (OCIError *) errhp ));

/* Retrieve the column name attribute */

checkerr(errhp, OCIAttrGet((dvoid*) mypard, (ub4) OCI_DTYPE_PARAM, (dvoid**) &col_name,(ub4 *) &col_name_len, (ub4) OCI_ATTR_NAME, (OCIError *) errhp )); printf("column=%s datatype=%d\n\n", col_name, dtype);

fflush(stdout);

/* increment counter and get next descriptor, if there is one */counter++;parm_status = OCIParamGet(stmthp, OCI_HTYPE_STMT, errhp, &mypard, (ub4) counter);}

 Mô tả tường minh : Xem ví dụ :

/* initialize svchp, stmhp, errhp, rowoff, iters, snap_in, snap_out */

Trang 31

/* set the execution mode to OCI_DESCRIBE_ONLY Note that setting the mode to OCI_DEFAULT does an implicit describe of the statement in addition to executing the

/* Get the number of columns in the query */

checkerr(errhp, OCIAttrGet(stmhp, OCI_HTYPE_STMT, &numcols, 0, OCI_ATTR_PARAM_COUNT, errh));

/* go through the column list and retrieve the data type of each column We start from pos = 1 */

for (i = 1; i <= numcols; i++){ /* get parameter for column i */

checkerr(errhp, OCIParamGet(stmhp, OCI_HTYPE_STMT, errh, &colhd, i)); /* get data-type of column i */

checkerr(errhp, OCIAttrGet(colhd, OCI_DTYPE_PARAM, &type[i-1], 0, OCI_ATTR_DATA_TYPE, errh)); }

Để nhận dữ liệu trả về phải define một biến output cho mỗi phần tử trong select-list Định nghĩa một biến output là thực hiện một hoặc nhiều bước , dùng hàm OCIDefineByPos() là bước cơ sở

Khi dùng array interface thì ta phải gọi hàm OCIDefineByPos() rồi sau đó gọi hàm OCIDefineArrayOfStruct() (phải thiết lập tham nhảy và chỉ định bao nhiêu dòng được nhận bằng cách thiết lập tham số iters trong hàm OCIStmtExecute()) hoặc hàm OCIDefineObject()(đối với named datatype)

Để nhận một chuỗi dữ liệu động vào lúc thực thi thì dùng hàm OCIDefineByPos() rồi sau đó dùng hàm OCIDefineDynamic()

VI.Nhận dữ liệu

Nếu ứng dụng xử lý truy vấn mà cần nhận dữ liệu trả về sau khi phát biểu được thực thi thì dùng hàm OCIStmtFetch() Nếu ứng dụng chỉ rõ số dòng cần nhận trực tiếp vào biến trong các hoạt động define thì không cần dùng hàm này

Trang 32

PHẦN II : CÁC KHÁI NIỆM VỀ OBJECT TRONG OCI

CHƯƠNG V : TỔNG QUAN VỀ LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG TRONG OCI

OCI cho phép truy cập các object từ một Oracle8 server thông qua các phát biểu SQL Thông qua các hàm object navigational của OCI một ứng dụng có thể thực hiện các chức

năng sau : 1 Tạo , truy cập , khóa , xóa ,copy , nạp các object

2 Tham chiếu đến các object và các meta-object của chúng

3 Nhận và thiết lập giá trị các thuộc tính của object một cách động

Ở đây các phát biểu SQL phải sử dụng các hàm về object để tham chiếu và thao tác trên nó Cấu trúc cơ bản của một chương trình theo hướng đối tượng

1 Khởi tạo môi trường lập trình OCI trong chế độ object(OCI_OBJECT) 2 Chỉ định các handle cần thiết và connect đến một server

3 Prepare phát biểu SQL ,đây là bước cục bộ

4 Liên kết phát biểu đã được prepare với một database server và thực thi phát biểu

5 Nhận kết quả trả về Ở bước này sau khi object được pinned thì có thể thực hiện được các việc sau :

 Thao tác trên các thuộc tính của object và đánh dấu nó là "dirty"  Từ một REF có thể tham chiếu đến các object khác

 Truy thông tin về kiểu và thuộc tính  Nhận được một sơ đồ object phức hợp  Nạp các object được thay đổi đến server

6 Commit transaction , bước này ngầm định nạp tất cả các object đã được thay đổi đến server và ghi nhận những thay đổi này

7 Giải phóng các statement handle và các phát biểu (đã được prepare) mà không được sử dụng lại hoặc thực thi lại

Các bước này sẽ được trình bày chi tiết trong các chương sau

CHƯƠNG VI : OBJECT-RILATIONAL DATATYPEI_Ánh xạ kiểu dữ liệu của Oracle8 sang C

Oracle8 có nhiều kiểu dữ liệu được định nghĩa trước mà dựa vào đó ta có thể tạo ra các bảng và các kiểu khác Các kiểu object mở rộng khả năng của oracle bằng việc cho phép tạo các kiểu dữ liệu một cách chính xác Ví dụ sau tạo ra kiểu địa chỉ do user định nhgĩa và một bảng object chứa các thực thể của kiểu này :

CREATE TYPE address AS OBJECT

CREATE TABLE address_table OF address;

Kiểu address được sử dụng để tạo ra một bảng có một object : CREATE TABLE employees

(name varchar2(30), birthday date,

home_addr address);

Trang 33

Một ứng dụng OCI trước tiên biểu diễn các object theo định dạng của ngôn ngữ C Bằng cách sử dụng OTT(Oject Type Translator) để đưa ra cáùu trúc C mô tả các kiểu do user định nghĩa Các phần tử này có các kiểu thực hiện việc ánh xạ sang các kiểu của Oracle8

Bảng 9-1 là danh sách các kiểu của Oracle mà có thể sử dụng như là các kiểu thuộc tính của object và các ánh xạ C

Table 9-1 C Language Mappings of Object Type Attributes

Ngoài ra kiểu OCIInd dùng để chỉ các thuộc tính null của objectPhương pháp ánh xạ các kiểu OCI

Oracle có một số hổ trợ khi ánh xạ các kiểu được định nghĩa trước :

- Thực tế các kliểu dữ liệu như OCINumber là không trong suốt đối với ứng dụng của client , có một tập các hàm được định nghĩa trước để thao tác dữ liệu Điều này cho phép mô tả bên trong thay đổi để tương thích với các nâng cấp trong tương lai

- Việc thực thi là không thay đổi đối với các định hướng đối tuợng chuẩn mà các class che giấu và chỉ khi có hoạt động yêun cầu mới được phô bày

- Việc thực thi như vậy có một số thuận lợi cho lập trình viên Một chương trình C có các biền của Oracle thì không mất tính chính xác Để làm điều này trong Oracle7 dùng phát biểu "SELECT … FROMDUAL" còn trong Oracle8 sử dụng hàm OCINumber*()

II Thao tác các kiểu dữ liệu C với OCI

Xét ví dụ đơn giản cộng hai số nguyên kết quả lưu vào biến thứ 3

Trang 34

integer int_1,int_2,sum; …………

Ngôn ngữ C cung cấp một tập các phép toán trên kiểu integer Tuy nhiên các kiểu dữ liệu C

trong bảng 9-1 là không đơn giản như C cổ điển Các kiểu OCIString và OCINumber là các

cấu trúc do Oracle định nghĩa Không thể cộng hai OCINumber và chứa vào OCINumber thứ 3 Ví dụ sau là không hợp lệ :

OCINumber num_1,num_2,sum; …………

Các hàm ánh xạ và thao tác kiểu dữ liệu OCI cho phép thực hiện các phép toán trên các kiểu

dữ liệu mới này Ví dụ dùng hàm OCINumberAdd để cộng 2 OCINumber :

OCINumber num_1,num_2,sum; ………

Table 9-2 Datatype Mapping and Manipulation Function Groups

Tính chính xác của các phép toán trên kiểu Number

Các number của Oracle có 38 số thập phân Tất cả các phép toán number chính xác ngoại trừ :

- Các hàm lượng giác ngược chính xác đến 28 số thập phân

- Các hàm siêu việt , bao gồm các hàm lượng giác , chính xác đến 37 số thập phân - Chuyển đổi các kiểu con trỏ thực thích hợp với kiểu con trỏ thực không vượt quá 38 số thập phân

III Kiểu Date(OCIDate)

Kiểu Date được ánh xạ sang C là kiểu OCIDate là một cấu trúc không trong suốt Các thành phần của cấu trúc Date mô tả năm , tháng , ngày , giờ và giây Để truy các thành phần của kiểu này phải dùng các hàm thích hợp

Kiểu OCIDate có thể được giới hạn và định nghĩa trực tiếp sử dụng mã kiểu SQLT_ODT

Trang 35

1 Các hàm chuyển đổi date

Table 9-3 Date Conversion Functions

2 Các hàm ấn định và lấy ra

3 Các hàm tính toán và so sánh

Table 9-5 Date Arithmetic and Comparison Functions

4 Các hàm truy cập thông tin kiểu Date

Table 9-6 Date Information Accessor Functions

5 Các hàm kiểm tra tính hiệu lực của Date

Table 9-7 Date Validity Checking Functions

6 Ví dụ

Trang 36

Ví dụ sau cho thấy thao trên một thuộc tính của OCIDate như thế nào sử dụng các lời gọi OCI

#define FMT "DAY, MONTH DD, YYYY" #define LANG "American"

OCIDate last_day, next_day;

text buf[100], last_day_buf[100], next_day_buf[100]; ub4 buflen = sizeof(buf);

/* For this example, assume the OCIEnv and OCIError have been * initialized as described in Chapter 2 */

/* Pin tim person object in the object cache See Chapter 6 for * information about pinning For this example, assume that * tim is pointing to the pinned object */

/* set the start date of tim */

OCIDateSetTime(&tim->start_date,8,0,0); OCIDateSetDate(&tim->start_date,1990,10,5) /* check if the date is valid */

if (OCIDateCheck(err, &tim->start_date, &invalid) != OCI_SUCCESS) /* error handling code */

if (invalid)

/* error handling code */

/* get the last day of start_date's month */

if (OCIDateLastDay(err, &tim->start_date, &last_day) != OCI_SUCCESS) /* error handling code */

/* get date of next named day */

if (OCIDateNextDay(err, &tim->start_date, "Wednesday", strlen("Wednesday"), &next_day) != OCI_SUCCESS) /* error handling code */

/* convert dates to strings and print the information out */ /* first convert the date itself*/

buflen = sizeof(buf);

if (OCIDateToText(err, &tim->start_date, FMT, sizeof(FMT)-1, LANG,

/* error handling code */

Trang 37

/* now the last day of the month */ buflen = sizeof(last_day_buf);

if (OCIDateToText(err, &last_day, FMT, sizeof(FMT)-1, LANG, sizeof(LANG)-1, &buflen, last_day_buf) != OCI_SUCCESS) /* error handling code */

/* now the first Wednesday after this date */ buflen = sizeof(next_day_out);

if (OCIDateToText(err, &next_day, FMT, sizeof(FMT)-1, LANG, sizeof(LANG)-1, &buflen, next_day_buf) != OCI_SUCCESS) /* error handling code */

/* print out the info */ printf("For: %s\n", buf);

printf("The last day of the month is: %s\n", last_day_buf); printf("The next Wednesday is: %s\n", next_day_buf); The output will be:

For: Monday, May 13, 1996

The last day of the month is: Friday, May 31 The next Wednesday is: Wednesday, May 15

IV Number(OCINumber)

OCINumber là kiểu không trong suốt mô tả các kiểu số NUMBER , FLOAT , DECIMAL Mã kiểu SQLT_VNU

Các hàm thao tác trên OCINumber được liệt kê trong các bảng sau Từ "number" chỉ đến một giá trị kiểu OCINumber

1 Các hàm tính toán

Table 9-8 Number Arithmetic Functions

OCINumberRound() round a number to a specified decimal place

OCINumberTrunc() truncate a number to a specified decimal place

2 Các hàm chuyển đổi

Trang 38

Table 9-9 Number Conversion Functions

3 Các hàm logarit và mũ

Table 9-10 Exponential and Logarithmic Functions

4 Các hàm lượng giác

Table 9-11 Trigonometric Functions

5 Các hàm ấn định và so sánh

Table 9-12 Number Assignment and Comparison Functions

Trang 39

OCINumberSetZero() initialize number to zero

/* For this example, assume OCIEnv and OCIError are initialized */ /* For this example, assume that steve, scott and jason are pointing to person objects which have been pinned in the object cache */

if (status != OCI_SUCCESS) /* handle error from OCINumberFromInt */; /* initialize scott's salary to be same as steve */

OCINumberAssign(err, stevesal, scottsal);

/* initialize jason's salary to be 20% more than steve's */ dnum = 1.2;

status = OCINumberFromReal(err, &dnum, DBL_DIG, &ornum);

if (status != OCI_SUCCESS) /* handle error from OCINumberFromReal */; status = OCINumberMul(err, stevesal, &ornum, debsal);

if (status != OCI_SUCCESS) /* handle error from OCINumberMul */; /* give scott a 50% raise */

Trang 40

dnum = 1.5;

status = OCINumberFromReal(err, &dnum, DBL_DIG, &ornum);

if (status != OCI_SUCCESS) /* handle error from OCINumberFromReal */; status = OCINumberMul(err, scottsal, &ornum, scottsal);

if (status != OCI_SUCCESS) /* handle error from OCINumberMul */; /* double steve's salary */

status = OCINumberAdd(err, stevesal, stevesal, stevesal);

if (status != OCI_SUCCESS) /* handle error from OCINumberAdd */; /* get steve's salary in integer */

status = OCINumberToInt(err, stevesal, sizeof(inum), OCI_NUMBER_SIGNED, &inum);

if (status != OCI_SUCCESS) /* handle error from OCINumberToInt */; /* inum is set to 24000 */

/* get jason's salary in double */

status = OCINumberToReal(err, debsal, sizeof(dnum), &dnum);

if (status != OCI_SUCCESS) /* handle error from OCINumberToReal */;

if (status != OCI_SUCCESS) /* handle error from OCINumberToText */; printf("scott's salary = %s\n", buffer);

/* compare steve and scott's salary */

status = OCINumberCmp(err, stevesal, scottsal, &result);

if (status != OCI_SUCCESS) /* handle error from OCINumberCmp */; /* result is positive */

/* read jason's new salary from string */

status = OCINumberFromText(err, "48\Q000.00", 9, "99G999D99", 9, "NLS_NUMERIC_CHARACTERS='.\Q'", 27, debsal);

if (status != OCI_SUCCESS) /* handle error from OCINumberFromText */; /* jason's salary is now 48000.00 */

V String có chiều dài thay đổi hoặc cố định (OCIString)

Chiều dài chuỗi có thể thay đổi hoặc cố định được hiện thực trong C là OCIString* Chiềudài chuỗi không bao gồm ký tự null

Mã kiểi là SQLT_VST1 String Function

Table 9-13 String Functions

OCIStringAssignText() assign text string to string

OCIStringAllocSize() get allocated size of string memory in bytes

Ngày đăng: 24/08/2012, 22:03

Hình ảnh liên quan

Hình 1- 1: Quá trình phát triển OCI - LVTN - Xay dung giao dien lap trinh OCI.doc

Hình 1.

1: Quá trình phát triển OCI Xem tại trang 1 của tài liệu.
Hình 2-1: Lưu đồ chương trình OCI cơ bản - LVTN - Xay dung giao dien lap trinh OCI.doc

Hình 2.

1: Lưu đồ chương trình OCI cơ bản Xem tại trang 9 của tài liệu.
Oracle8 có nhiều kiểu dữ liệu được định nghĩa trước mà dựa vào đó ta có thể tạo ra các bảng và các kiểu khác  - LVTN - Xay dung giao dien lap trinh OCI.doc

racle8.

có nhiều kiểu dữ liệu được định nghĩa trước mà dựa vào đó ta có thể tạo ra các bảng và các kiểu khác Xem tại trang 32 của tài liệu.
Khi bảng được copy lại CSDL thì chỉ số tức thì bị mất .Các hoạt động xóa được thực hiện trên các phần tử của bảng  - LVTN - Xay dung giao dien lap trinh OCI.doc

hi.

bảng được copy lại CSDL thì chỉ số tức thì bị mất .Các hoạt động xóa được thực hiện trên các phần tử của bảng Xem tại trang 44 của tài liệu.
VIII. REF( OCIRef) - LVTN - Xay dung giao dien lap trinh OCI.doc

ef.

Xem tại trang 44 của tài liệu.
t là bảng object chứa object bị khóa ,r là REF nhận dạng object. - LVTN - Xay dung giao dien lap trinh OCI.doc

t.

là bảng object chứa object bị khóa ,r là REF nhận dạng object Xem tại trang 59 của tài liệu.
III. Các hàm OCI Navigation - LVTN - Xay dung giao dien lap trinh OCI.doc

c.

hàm OCI Navigation Xem tại trang 62 của tài liệu.
Hình 11-2 :một ví dụ object graph - LVTN - Xay dung giao dien lap trinh OCI.doc

Hình 11.

2 :một ví dụ object graph Xem tại trang 62 của tài liệu.
Trong mô hình object vận chuyển dữ liệu được mô tả như là một graph của object liên kết với nhau bởi các tham chiếu  - LVTN - Xay dung giao dien lap trinh OCI.doc

rong.

mô hình object vận chuyển dữ liệu được mô tả như là một graph của object liên kết với nhau bởi các tham chiếu Xem tại trang 94 của tài liệu.
Hình 14-1 Classification of Instances by Type and Lifetime - LVTN - Xay dung giao dien lap trinh OCI.doc

Hình 14.

1 Classification of Instances by Type and Lifetime Xem tại trang 95 của tài liệu.
Phân biệt các thực thể khác nhau được đưa ra ở bảng sau: - LVTN - Xay dung giao dien lap trinh OCI.doc

h.

ân biệt các thực thể khác nhau được đưa ra ở bảng sau: Xem tại trang 95 của tài liệu.
CHƯƠNG XI I: ÁNH XẠ KIỂU DỮ LIỆU OCI VÀ CÁC HÀM THAO TÁC I.Giới thiệu - LVTN - Xay dung giao dien lap trinh OCI.doc

i.

ới thiệu Xem tại trang 98 của tài liệu.
Mộtsố hàm trả về các giá trị khác trong bảng 15-1 .Khi sử dụng những hàm này phải có một nơi chứa để trả về một giá trị trực tiếp từ lời gọi hàm hơn là thông qua một tham số OUT  - LVTN - Xay dung giao dien lap trinh OCI.doc

ts.

ố hàm trả về các giá trị khác trong bảng 15-1 .Khi sử dụng những hàm này phải có một nơi chứa để trả về một giá trị trực tiếp từ lời gọi hàm hơn là thông qua một tham số OUT Xem tại trang 98 của tài liệu.

Từ khóa liên quan

Tài liệu cùng người dùng

Tài liệu liên quan