Hướng dẫn php oracle query example - ví dụ truy vấn oracle php

  • Bấm để xem Chính sách khả năng truy cập của chúng tôi
  • Bỏ qua nội dung

Một thủ tục được lưu trữ tập luyện với Oracle và PHPBY Harry Fueckspublished tháng 11 năm 2005
by Harry Fuecks
Published November 2005

Một thủ tục được lưu trữ là một chương trình cư trú tại Oracle. Hầu hết các quy trình được lưu trữ được viết bằng PL/SQL, mặc dù với cơ sở dữ liệu Oracle 10G Phát hành 2 và sau đó bạn có thể viết chúng bằng Java, .NET hoặc các ngôn ngữ khác dưới dạng các quy trình bên ngoài.

Các thủ tục được lưu trữ thường nhóm một loạt các hoạt động liên quan đằng sau một API duy nhất. Thông thường, các hoạt động được thực hiện bởi một quy trình được lưu trữ sẽ là kết hợp các câu lệnh SQL, để tìm nạp và sửa đổi dữ liệu, cũng như các câu lệnh PL/SQL hoạt động trên dữ liệu đó, như vậy thực hiện một số tính toán toán học, xác thực chi tiết các giá trị và xử lý các điều kiện lỗi mà họ có thể Hãy thuận lợi trong việc cải thiện hiệu suất, bằng cách giảm số lượng "chuyến đi tròn" giữa chương trình gọi và cơ sở dữ liệu, cũng như đơn giản hóa logic quản lý dữ liệu trong máy khách.

Nếu bạn xem xét mã thường được yêu cầu để quản lý mối quan hệ nhiều đến nhiều giữa các bảng, việc thực hiện cập nhật dữ liệu hiện có thường có thể liên quan đến ba truy vấn riêng biệt. Bằng cách gói gọn quy trình đó trong một quy trình được lưu trữ duy nhất, lưu lượng truy cập giữa máy khách và cơ sở dữ liệu bị giảm trong khi một hoạt động thường yêu cầu nhiều bước trong mã máy khách bị giảm xuống một cuộc gọi cơ sở dữ liệu.

Tiện ích mở rộng PHP OCI8 cung cấp hỗ trợ để gọi các quy trình được lưu trữ, cho phép bạn liên kết các tham số với câu lệnh Quy trình theo cách tương tự như câu lệnh SQL bình thường, cũng như truy cập vào các bộ sưu tập kết quả và bộ sưu tập Oracle. Howto này cung cấp các ví dụ về các hoạt động chung với các quy trình được lưu trữ.

Đầu vào và đầu ra thủ tục được lưu trữ

Khi gọi một thủ tục được lưu trữ của Oracle, tất cả dữ liệu đầu vào và đầu ra được truyền dưới dạng đối số cho thủ tục. Điều này có thể gây nhầm lẫn như trước tiên, nếu bạn đã quen với ngữ nghĩa gọi chức năng PHP với một số đối số và có nó trả về một giá trị, nhưng dễ thấy nhất. Cho chữ ký thủ tục được lưu trữ sau:

 
 
 
0

Khi gọi thủ tục này, tên đối số đầu tiên sẽ chứa giá trị đầu vào bạn cung cấp theo thời gian gọi, trong khi lời chào sẽ được quy trình tạo ra như một giá trị "trả về" để sử dụng sau khi thủ tục hoàn thành.

Đọc các đặc điểm kỹ thuật

Mặc dù một cuộc thảo luận về lập trình PL/SQL nằm ngoài phạm vi của điều này, nhưng kiến ​​thức sâu sắc về PL/SQL là không cần thiết miễn là bạn gần như quen thuộc với cách một quy trình được lưu trữ và có thể đọc thông số kỹ thuật giao diện.

Khi tìm kiếm nguồn của một thủ tục được lưu trữ, nó sẽ bắt đầu bằng cách xác định các tham số mà nó chấp nhận, ví dụ:

 
 PROCEDURE edit_entry(
 status_out OUT NUMBER,
 status_msg_out OUT VARCHAR2,
 id_inout IN OUT INTEGER,
 title_in IN VARCHAR2,
 text_out OUT CLOB,
 categories_in IN list_of_numbers
 );
 

Tên của thủ tục này là

 
 
 
1. Trong dấu ngoặc đơn được xác định danh sách các đối số bạn có thể chuyển sang thủ tục, được phân tách bằng dấu phẩy. Đối với mỗi tham số trong danh sách, bạn sẽ thấy tên được sử dụng để tham chiếu giá trị của nó trong chính quy trình (bạn không cần sử dụng cùng tên trong tập lệnh PHP của mình), chế độ của tham số (xem bên dưới) và loại thông số.

Vì vậy, đối với tham số đầu tiên trong ví dụ này:

 
 
 
2

Tên nội bộ là

 
 
 
3 Chế độ là
 
 
 
4 và loại là
 
 
 
5 là loại dữ liệu Oracle gốc.

Sau đó trong tập lệnh, bạn sẽ thấy tham số

 
 
 
6.

 
 
 
7

có chế độ

 
 
 
8 và loại
 
 
 
9

Ở cuối danh sách là tham số

 
 CREATE OR REPLACE PROCEDURE 
 sayHello (name IN VARCHAR2, greeting OUT VARCHAR2) 
 AS
 BEGIN
 greeting := 'Hello ' || name;
 END;
 /
 
0:

 
 CREATE OR REPLACE PROCEDURE 
 sayHello (name IN VARCHAR2, greeting OUT VARCHAR2) 
 AS
 BEGIN
 greeting := 'Hello ' || name;
 END;
 /
 
1

Ở đây loại là người dùng được xác định (nhiều hơn về loại đó sau).

Chế độ tham số

Chế độ của tham số mô tả hướng của "luồng" dữ liệu từ người gọi đến quy trình:

  • ________ 22 Trình phép tham số với chế độ này được cung cấp bởi người gọi.
  • ________ 23 Tham số có thể được gán một giá trị theo quy trình và trả lại cho người gọi.
  • ________ 18 Tham số có thể được sử dụng theo cả hai "hướng"; nghĩa là, người gọi có thể cung cấp một giá trị cho tham số này và quy trình cũng có thể sửa đổi giá trị của tham số.

Tham số không phải là tùy chọn.

Khi một thủ tục được gọi từ PHP, bạn phải liên kết một biến PHP với tất cả các tham số mà nó xác định. Bạn có thể không phải gán các giá trị cho các biến PHP, ngay cả khi chúng là tham số đầu vào, nếu không có giá trị nào được gán cho loại vô hướng, Oracle sẽ coi nó là giá trị null.

Điều đáng chú ý là các thủ tục được lưu trữ có thể bị "quá tải" trong Oracle. Nói cách khác, có thể có hai thủ tục có cùng tên nhưng với chữ ký tham số khác nhau. Cái nào được gọi là sẽ phụ thuộc vào số lượng và các loại tham số bạn liên kết trong PHP.

Các loại phức tạp

Các tham số được sử dụng bởi một quy trình được lưu trữ không chỉ giới hạn ở các loại vô hướng như Varchar2 và Integer. Cũng có thể truyền và nhận các loại dữ liệu phức tạp, chẳng hạn như danh sách các giá trị hoặc con trỏ kết quả tương ứng với tập hợp các hàng được chọn từ một bảng.

Nói chung, bạn thường sẽ nhận lại con trỏ từ một quy trình được lưu trữ, nếu có các hàng dữ liệu để lặp lại, trong khi nếu bạn cần truyền một danh sách các giá trị, bạn thường sẽ sử dụng một bộ sưu tập. Các ví dụ dưới đây minh họa những điều này trong PHP.

Invoker so với quyền của Definer.

Oracle phân biệt giữa "người mời" (người dùng thực hiện một quy trình được lưu trữ) và "người xác định" (người dùng theo đó câu lệnh

 
 CREATE OR REPLACE PROCEDURE 
 sayHello (name IN VARCHAR2, greeting OUT VARCHAR2) 
 AS
 BEGIN
 greeting := 'Hello ' || name;
 END;
 /
 
5 đã được ban hành).

Theo mặc định, các thủ tục được lưu trữ được thực thi với các quyền của người xác định, ngay cả khi Invoker là một người dùng khác. Điều đó có nghĩa là tất cả quyền truy cập vào các bảng, ví dụ, trong quy trình sẽ là người kiểm soát bởi các quyền của người Definer để Invoker chỉ cần quyền thực thi thủ tục, không phải quyền đối với các bảng mà nó sử dụng.

Mô hình này có thể được thay đổi với các từ khóa

 
 CREATE OR REPLACE PROCEDURE 
 sayHello (name IN VARCHAR2, greeting OUT VARCHAR2) 
 AS
 BEGIN
 greeting := 'Hello ' || name;
 END;
 /
 
6 như là một phần của định nghĩa thủ tục. Với bộ chỉ thị này, các quyền được yêu cầu khi thực hiện một thủ tục được lưu trữ được giải quyết trong thời gian chạy chống lại người dùng hiện tại thực hiện thủ tục.

Một cách sử dụng có thể cho phương pháp này là kiểm tra một quy trình sửa đổi dữ liệu trong bảng mà không thực sự sửa đổi dữ liệu trực tiếp. Trong trường hợp này, người dùng gọi định nghĩa một bảng trong lược đồ của riêng họ có cùng tên với một tên được truy cập từ trong một thủ tục họ muốn thực thi và thủ tục hành động chống lại bảng cục bộ thay vì cái có sẵn cho người xác định.

Gọi các thủ tục được lưu trữ từ PHP

Về mặt câu lệnh SQL, bạn sẽ thực thi từ PHP để gọi một thủ tục, bạn thường sẽ tổ chức cuộc gọi trong một khối Oracle

 
 CREATE OR REPLACE PROCEDURE 
 sayHello (name IN VARCHAR2, greeting OUT VARCHAR2) 
 AS
 BEGIN
 greeting := 'Hello ' || name;
 END;
 /
 
7, được gọi là một khối ẩn danh. Ví dụ:

 
 
 

Sau đó, bạn liên kết các tham số với các biến PHP với các cuộc gọi đến OCI_BIND_BY_NAME ().

Nếu thủ tục

 
 CREATE OR REPLACE PROCEDURE 
 sayHello (name IN VARCHAR2, greeting OUT VARCHAR2) 
 AS
 BEGIN
 greeting := 'Hello ' || name;
 END;
 /
 
8 được xác định bởi câu lệnh DDL sau:

 
 CREATE OR REPLACE PROCEDURE 
 sayHello (name IN VARCHAR2, greeting OUT VARCHAR2) 
 AS
 BEGIN
 greeting := 'Hello ' || name;
 END;
 /
 

Lưu ý rằng bạn có thể chạy câu lệnh trên bằng dòng lệnh SQL*Plus. Lưu câu lệnh vào một tệp (Sayhello.sql). Tiếp theo, đăng nhập bằng SQL*Plus:

 
 CREATE OR REPLACE PROCEDURE 
 sayHello (name IN VARCHAR2, greeting OUT VARCHAR2) 
 AS
 BEGIN
 greeting := 'Hello ' || name;
 END;
 /
 
9

Sau đó tạo quy trình bằng lệnh bắt đầu:

 
 
 
0

Tập lệnh PHP sau đây gọi quy trình:

 
 
 

Ví dụ gói blog.

Để minh họa một số khía cạnh khó khăn hơn của các quy trình được lưu trữ, ở đây bạn sẽ sử dụng gói sau, được gọi là

 
 
 
1 cung cấp API để tìm nạp và sửa đổi các mục trong một ứng dụng viết blog giả thuyết. Các gói là một cách để gói gọn các quy trình, chức năng và dữ liệu bên trong không gian tên của riêng họ với phạm vi riêng của chúng, giữ cho chúng bị cô lập với các quy trình khác trong không gian tên cơ sở dữ liệu toàn cầu. Khi gọi một thủ tục trong một gói, một khoảng thời gian được sử dụng để tách tên gói khỏi tên thủ tục.

Gói

 
 
 
2 được chỉ định với:

 
 CREATE OR REPLACE PACKAGE blog AS
 
 TYPE cursorType IS REF CURSOR RETURN blogs%ROWTYPE;
 
 /*
 Fetch the latest num_entries_in from the blogs table, populating
 entries_cursor_out with the result
 */
 PROCEDURE latest(
 num_entries_in IN NUMBER,
 entries_cursor_out OUT cursorType
 );
 
 /*
 Edit a blog entry. If id_inout is NULL, results in an INSERT, otherwise
 attempts to UPDATE the existing blog entry. status_out will have the value
 1 on success, otherwise a negative number on failure with status_msg_out
 containing a description
 categories_in is a collection where list_of_numbers is described by
 TYPE list_of_numbers AS VARRAY(50) OF NUMBER;
 */
 PROCEDURE edit_entry(
 status_out OUT NUMBER,
 status_msg_out OUT VARCHAR2,
 id_inout IN OUT INTEGER,
 title_in IN VARCHAR2,
 text_out OUT CLOB,
 categories_in IN list_of_numbers
 );
 
 END blog;
 /
 

Gói cung cấp hai quy trình:

 
 
 
3 trả về con trỏ kết quả chứa các mục blog
 
 
 
4 nhiều nhất; và
 
 
 
5 cho phép các mục blog mới được chèn cũng như sửa đổi các mục blog hiện có. Nếu một giá trị được cung cấp cho tham số
 
 
 
6, quy trình sẽ cố gắng cập nhật mục blog tương ứng với ID đó. Nếu không, nó sẽ chèn một mục blog mới và điền vào
 
 
 
6 với khóa chính của hàng mới. Quy trình này cũng chấp nhận một đối tượng CLOB, tương ứng với phần thân của mục blog và một đối tượng thu thập tương ứng với một danh sách các danh mục mà mục nhập nên được nộp theo. Loại bộ sưu tập
 
 
 
8 được tham chiếu ở đây được xác định bởi:

 
 
 
9

Cơ thể của gói được hiển thị dưới đây. Các ý kiến ​​sẽ cho bạn một ý tưởng về những gì nó làm mà không cần hiểu sâu sắc về PL/SQL:

 
 CREATE OR REPLACE PACKAGE BODY blog AS
 
 /*------------------------------------------------*/
 PROCEDURE latest(
 num_entries_in IN NUMBER,
 entries_cursor_out OUT cursorType
 ) AS
 
 BEGIN
 
 OPEN entries_cursor_out FOR
SELECT * FROM blogs WHERE rownum < num_entries_in
ORDER BY date_published DESC;

END latest;

/*------------------------------------------------*/
PROCEDURE edit_entry(
status_out OUT NUMBER,
status_msg_out OUT VARCHAR2,
id_inout IN OUT INTEGER,
title_in IN VARCHAR2,
text_out OUT CLOB,
categories_in IN list_of_numbers
) AS

ENTRY_NOT_FOUND EXCEPTION;
entry_found INTEGER := 0;

BEGIN

/* Default status to success */
status_out := 1;

/* If id_inout has a value then attempt to UPDATE */
IF id_inout IS NOT NULL THEN

/* Check the id exists - raise ENTRY_NOT_FOUND if not */
SELECT COUNT(*) INTO entry_found
FROM blogs b WHERE b.id = id_inout;
IF entry_found != 1 THEN RAISE ENTRY_NOT_FOUND; END IF;

/* Update the blogs table returning the CLOB field */
UPDATE blogs b SET b.title = title_in, b.text = EMPTY_CLOB()
WHERE b.id = id_inout RETURNING b.text INTO text_out;

/* Remove any existing relationships to categories
- new categories inserted below */
DELETE FROM blogs_to_categories WHERE blog_id = id_inout;

status_msg_out := 'Blog entry ' || id_inout || ' updated';

/* id_inout was null so INSERT new record */
ELSE

INSERT INTO blogs b ( b.id, b.title, b.date_published, b.text )
VALUES ( blog_id_seq.nextval, title_in, SYSDATE, EMPTY_CLOB() )
RETURNING b.id, b.text INTO id_inout, text_out;

status_msg_out := 'Blog entry ' || id_inout || ' inserted';

END IF;

/* Now handle assignment to categories.
Loop over the categories_in collection,
inserting the new category assignments */
FOR i IN 1 .. categories_in.count
LOOP
INSERT INTO blogs_to_categories (blog_id,category_id)
VALUES (id_inout,categories_in(i));
END LOOP;

status_msg_out := status_msg_out || ' - added to '
|| categories_in.count || ' categories';

EXCEPTION
/* Catch the exception when id_inout not found */
WHEN ENTRY_NOT_FOUND THEN
status_out := -1001;
status_msg_out := 'No entry found in table blogs with id = '
|| id_inout;
/* Catch any other exceptions raised by Oracle */
WHEN OTHERS THEN
status_out := -1;
status_msg_out := 'Error: ' || TO_CHAR (SQLCODE) || SQLERRM;

END edit_entry;

END blog;
/
 

Cấu trúc bảng cơ bản mà các quy trình đang sử dụng là:

 
 
 CREATE SEQUENCE blog_id_seq
 INCREMENT BY 1;
 /
 CREATE TABLE blogs (
 id NUMBER PRIMARY KEY,
 title VARCHAR2(200),
 date_published DATE,
 text CLOB
 );
 /
 CREATE SEQUENCE category_id_seq
 INCREMENT BY 1;
 
 CREATE TABLE categories (
 id NUMBER PRIMARY KEY,
 name VARCHAR2(30) UNIQUE
 );
 /
 CREATE TABLE blogs_to_categories (
 blog_id INTEGER NOT NULL
 REFERENCES blogs(id),
 category_id INTEGER NOT NULL
 REFERENCES categories(id),
 PRIMARY KEY (blog_id, category_id)
 );
 /
 

Các thủ tục lưu trữ và con trỏ tham chiếu

Nhìn vào quy trình

 
 CREATE OR REPLACE PACKAGE blog AS
 
 TYPE cursorType IS REF CURSOR RETURN blogs%ROWTYPE;
 
 /*
 Fetch the latest num_entries_in from the blogs table, populating
 entries_cursor_out with the result
 */
 PROCEDURE latest(
 num_entries_in IN NUMBER,
 entries_cursor_out OUT cursorType
 );
 
 /*
 Edit a blog entry. If id_inout is NULL, results in an INSERT, otherwise
 attempts to UPDATE the existing blog entry. status_out will have the value
 1 on success, otherwise a negative number on failure with status_msg_out
 containing a description
 categories_in is a collection where list_of_numbers is described by
 TYPE list_of_numbers AS VARRAY(50) OF NUMBER;
 */
 PROCEDURE edit_entry(
 status_out OUT NUMBER,
 status_msg_out OUT VARCHAR2,
 id_inout IN OUT INTEGER,
 title_in IN VARCHAR2,
 text_out OUT CLOB,
 categories_in IN list_of_numbers
 );
 
 END blog;
 /
 
0, bạn sẽ thấy nó trả về một con trỏ tham chiếu để lặp qua hàng trong bảng blog của tôi.

Để làm việc với một con trỏ trong PHP, hai bước bổ sung được yêu cầu, so với việc truy cập các hàng trực tiếp từ câu lệnh

 
 CREATE OR REPLACE PACKAGE blog AS
 
 TYPE cursorType IS REF CURSOR RETURN blogs%ROWTYPE;
 
 /*
 Fetch the latest num_entries_in from the blogs table, populating
 entries_cursor_out with the result
 */
 PROCEDURE latest(
 num_entries_in IN NUMBER,
 entries_cursor_out OUT cursorType
 );
 
 /*
 Edit a blog entry. If id_inout is NULL, results in an INSERT, otherwise
 attempts to UPDATE the existing blog entry. status_out will have the value
 1 on success, otherwise a negative number on failure with status_msg_out
 containing a description
 categories_in is a collection where list_of_numbers is described by
 TYPE list_of_numbers AS VARRAY(50) OF NUMBER;
 */
 PROCEDURE edit_entry(
 status_out OUT NUMBER,
 status_msg_out OUT VARCHAR2,
 id_inout IN OUT INTEGER,
 title_in IN VARCHAR2,
 text_out OUT CLOB,
 categories_in IN list_of_numbers
 );
 
 END blog;
 /
 
1. Bước đầu tiên là chuẩn bị tài nguyên con trỏ trong PHP, sử dụng hàm OCI_NEW_CURSOR (), sau đó bạn sử dụng để liên kết với tham số thích hợp. Bước thứ hai, sau khi bạn đã thực thi câu lệnh SQL, đang gọi oci_execute () trên tài nguyên con trỏ.

Tập lệnh PHP sau đây minh họa quy trình này:

 
 
 

Các thủ tục được lưu trữ và LOB

Các đối tượng dài của Oracle có thể được truyền đến và từ các thủ tục được lưu trữ theo cách khá giống với SQL bản địa.

Ví dụ sau đây cho thấy một cuộc gọi đến thủ tục

 
 CREATE OR REPLACE PACKAGE blog AS
 
 TYPE cursorType IS REF CURSOR RETURN blogs%ROWTYPE;
 
 /*
 Fetch the latest num_entries_in from the blogs table, populating
 entries_cursor_out with the result
 */
 PROCEDURE latest(
 num_entries_in IN NUMBER,
 entries_cursor_out OUT cursorType
 );
 
 /*
 Edit a blog entry. If id_inout is NULL, results in an INSERT, otherwise
 attempts to UPDATE the existing blog entry. status_out will have the value
 1 on success, otherwise a negative number on failure with status_msg_out
 containing a description
 categories_in is a collection where list_of_numbers is described by
 TYPE list_of_numbers AS VARRAY(50) OF NUMBER;
 */
 PROCEDURE edit_entry(
 status_out OUT NUMBER,
 status_msg_out OUT VARCHAR2,
 id_inout IN OUT INTEGER,
 title_in IN VARCHAR2,
 text_out OUT CLOB,
 categories_in IN list_of_numbers
 );
 
 END blog;
 /
 
2 bằng Clob. Trong ví dụ này, không có giá trị nào được gán cho tham số
 
 CREATE OR REPLACE PACKAGE blog AS
 
 TYPE cursorType IS REF CURSOR RETURN blogs%ROWTYPE;
 
 /*
 Fetch the latest num_entries_in from the blogs table, populating
 entries_cursor_out with the result
 */
 PROCEDURE latest(
 num_entries_in IN NUMBER,
 entries_cursor_out OUT cursorType
 );
 
 /*
 Edit a blog entry. If id_inout is NULL, results in an INSERT, otherwise
 attempts to UPDATE the existing blog entry. status_out will have the value
 1 on success, otherwise a negative number on failure with status_msg_out
 containing a description
 categories_in is a collection where list_of_numbers is described by
 TYPE list_of_numbers AS VARRAY(50) OF NUMBER;
 */
 PROCEDURE edit_entry(
 status_out OUT NUMBER,
 status_msg_out OUT VARCHAR2,
 id_inout IN OUT INTEGER,
 title_in IN VARCHAR2,
 text_out OUT CLOB,
 categories_in IN list_of_numbers
 );
 
 END blog;
 /
 
3 để nó sẽ tương ứng với việc chèn một mục blog mới:

 
 
 save('This is the body of the test entry') ) {
 // Rollback the procedure
 oci_rollback($conn);
 die ("Error saving lob\n");
 }
 
 // Everything OK so commit
 oci_commit($conn);
 print $status_msg."\n";
 ?>
 

Như tập lệnh này minh họa, một vấn đề chính là cách xử lý các giao dịch khi xử lý các LOB. Ở đây bạn đã chọn để ủy thác tất cả các xử lý giao dịch cho tập lệnh PHP, vì cập nhật LOB là một quy trình hai giai đoạn.

Lưu ý rằng, theo mặc định, Oracle cho phép bạn chỉ có một giao dịch chạy tại một thời điểm trong bất kỳ phiên nào. Điều đó có nghĩa là các câu lệnh cam kết hoặc rollback được ban hành trong một quy trình bạn đang gọi từ PHP sẽ ghi đè các cuộc gọi bạn thực hiện cho oci_commit () hoặc oci_rollback (). Bạn có thể thay đổi hành vi này bằng cách sử dụng các giao dịch tự trị, được kích hoạt với Pragma

 
 CREATE OR REPLACE PACKAGE blog AS
 
 TYPE cursorType IS REF CURSOR RETURN blogs%ROWTYPE;
 
 /*
 Fetch the latest num_entries_in from the blogs table, populating
 entries_cursor_out with the result
 */
 PROCEDURE latest(
 num_entries_in IN NUMBER,
 entries_cursor_out OUT cursorType
 );
 
 /*
 Edit a blog entry. If id_inout is NULL, results in an INSERT, otherwise
 attempts to UPDATE the existing blog entry. status_out will have the value
 1 on success, otherwise a negative number on failure with status_msg_out
 containing a description
 categories_in is a collection where list_of_numbers is described by
 TYPE list_of_numbers AS VARRAY(50) OF NUMBER;
 */
 PROCEDURE edit_entry(
 status_out OUT NUMBER,
 status_msg_out OUT VARCHAR2,
 id_inout IN OUT INTEGER,
 title_in IN VARCHAR2,
 text_out OUT CLOB,
 categories_in IN list_of_numbers
 );
 
 END blog;
 /
 
4 được đặt trong một định nghĩa thủ tục. Ví dụ, bạn có thể sử dụng các giao dịch tự trị như một phần của gói ghi nhật ký mà bạn gọi từ các thủ tục khác; Cách tiếp cận này sẽ cho phép bạn đăng nhập thông tin về các cuộc gọi thủ tục được lưu trữ mà không can thiệp vào các giao dịch chạy trong một phiên.

Các thủ tục và bộ sưu tập được lưu trữ

Bộ sưu tập cung cấp một cơ chế để chuyển một loại dữ liệu phức tạp vào một quy trình được lưu trữ. Trong ứng dụng viết blog của bạn, một mục blog có thể được nộp theo nhiều danh mục, tương ứng với mối quan hệ nhiều đến nhiều giữa các bảng "Blog" và "danh mục".

Một loại bộ sưu tập trong Oracle phải được xác định trên toàn cầu trong cơ sở dữ liệu và trong ví dụ này, bạn đang sử dụng định nghĩa sau:

 
 
 
9

cho phép bạn gán một mục blog cho tối đa 50 danh mục trong một lần, bằng cách chuyển một thể hiện của loại này cho thủ tục

 
 CREATE OR REPLACE PACKAGE blog AS
 
 TYPE cursorType IS REF CURSOR RETURN blogs%ROWTYPE;
 
 /*
 Fetch the latest num_entries_in from the blogs table, populating
 entries_cursor_out with the result
 */
 PROCEDURE latest(
 num_entries_in IN NUMBER,
 entries_cursor_out OUT cursorType
 );
 
 /*
 Edit a blog entry. If id_inout is NULL, results in an INSERT, otherwise
 attempts to UPDATE the existing blog entry. status_out will have the value
 1 on success, otherwise a negative number on failure with status_msg_out
 containing a description
 categories_in is a collection where list_of_numbers is described by
 TYPE list_of_numbers AS VARRAY(50) OF NUMBER;
 */
 PROCEDURE edit_entry(
 status_out OUT NUMBER,
 status_msg_out OUT VARCHAR2,
 id_inout IN OUT INTEGER,
 title_in IN VARCHAR2,
 text_out OUT CLOB,
 categories_in IN list_of_numbers
 );
 
 END blog;
 /
 
2.

Trong PHP, một bộ sưu tập được thể hiện bằng cách thu thập OCI lớp PHP được xác định trước. Các phiên bản của lớp này được tạo bằng cách gọi hàm OCI_New_Collection (). Đối tượng

 
 CREATE OR REPLACE PACKAGE blog AS
 
 TYPE cursorType IS REF CURSOR RETURN blogs%ROWTYPE;
 
 /*
 Fetch the latest num_entries_in from the blogs table, populating
 entries_cursor_out with the result
 */
 PROCEDURE latest(
 num_entries_in IN NUMBER,
 entries_cursor_out OUT cursorType
 );
 
 /*
 Edit a blog entry. If id_inout is NULL, results in an INSERT, otherwise
 attempts to UPDATE the existing blog entry. status_out will have the value
 1 on success, otherwise a negative number on failure with status_msg_out
 containing a description
 categories_in is a collection where list_of_numbers is described by
 TYPE list_of_numbers AS VARRAY(50) OF NUMBER;
 */
 PROCEDURE edit_entry(
 status_out OUT NUMBER,
 status_msg_out OUT VARCHAR2,
 id_inout IN OUT INTEGER,
 title_in IN VARCHAR2,
 text_out OUT CLOB,
 categories_in IN list_of_numbers
 );
 
 END blog;
 /
 
7 cung cấp các phương thức sau:

  • Nối: Đẩy một phần tử vào phần cuối của bộ sưu tập
  • Bài tập: Thêm một phần tử vào bộ sưu tập từ bộ sưu tập hiện có
  • Miễn phí: Giải phóng một tài nguyên liên quan đến xử lý bộ sưu tập
  • Getelem: Lấy một phần tử từ một vị trí chỉ mục cụ thể trong bộ sưu tập
  • Tối đa: Trả về số lượng phần tử tối đa trong bộ sưu tập
  • Kích thước: Trả về kích thước hiện tại của bộ sưu tập
  • Trim: Xóa một số yếu tố từ cuối bộ sưu tập

Ở đây bạn chỉ quan tâm đến việc sử dụng phương thức phụ lục, vì vậy bạn có thể đính kèm danh sách ID danh mục vào cuộc gọi thủ tục. Trong ví dụ dưới đây, bạn sẽ cập nhật mục blog hiện có được tạo trong ví dụ trước bằng cách chuyển ID của nó cho

 
 CREATE OR REPLACE PACKAGE blog AS
 
 TYPE cursorType IS REF CURSOR RETURN blogs%ROWTYPE;
 
 /*
 Fetch the latest num_entries_in from the blogs table, populating
 entries_cursor_out with the result
 */
 PROCEDURE latest(
 num_entries_in IN NUMBER,
 entries_cursor_out OUT cursorType
 );
 
 /*
 Edit a blog entry. If id_inout is NULL, results in an INSERT, otherwise
 attempts to UPDATE the existing blog entry. status_out will have the value
 1 on success, otherwise a negative number on failure with status_msg_out
 containing a description
 categories_in is a collection where list_of_numbers is described by
 TYPE list_of_numbers AS VARRAY(50) OF NUMBER;
 */
 PROCEDURE edit_entry(
 status_out OUT NUMBER,
 status_msg_out OUT VARCHAR2,
 id_inout IN OUT INTEGER,
 title_in IN VARCHAR2,
 text_out OUT CLOB,
 categories_in IN list_of_numbers
 );
 
 END blog;
 /
 
8 cũng như danh sách ID danh mục:

 
 append(2);
 $Categories->append(4);
 $Categories->append(5);
 
 // Bind the collection to the parameter
 oci_bind_by_name($stmt,':categories',$Categories,-1,OCI_B_SQLT_NTY);
 
 oci_execute($stmt, OCI_DEFAULT);
 
 if ( !$status ) {
 oci_rollback($conn);
 die ("$status_msg\n");
 }
 
 if ( !$textLob->save('This is the body of the test entry [v2]') ) {
 oci_rollback($conn);
 die ("Error saving lob\n");
 }
 
 oci_commit($conn);
 print $status_msg."\n";
 ?>
 
 

Sự kết luận

Bây giờ bạn đã thấy các ví dụ về cách gọi các thủ tục được lưu trữ từ PHP, cả với các quy trình đơn giản chỉ liên quan đến các loại dữ liệu vô hướng và các quy trình phức tạp hơn sử dụng LOB, con trỏ và bộ sưu tập. Bạn cũng nên có đủ sự hiểu biết về các định nghĩa thủ tục được lưu trữ để có thể đọc thông số kỹ thuật PL/SQL của họ, cho phép bạn gọi chúng một cách chính xác từ PHP và liên kết đúng các loại.

Harry Fuecks [http://www.phppatterns.com] là một nhà phát triển và nhà văn PHP nổi tiếng, kể từ khi phát hiện ra PHP vào năm 1999. Ông đã xuất bản nhiều bài báo PHP giới thiệu và trung gian thông qua trang web. Mạng của nhà phát triển web, cũng như viết tuyển tập PHP (sitePoint).

Tại sao Oracle

  • Báo cáo phân tích
  • ERP dựa trên đám mây tốt nhất
  • Kinh tế đám mây
  • Cùng chịu trách nhiệm
  • Đa dạng và Hòa nhập
  • Thực hành bảo mật

Học

  • Điện toán đám mây là gì?
  • CRM là gì?
  • Docker là gì?
  • Kubernetes là gì?
  • Python là gì?
  • SaaS là ​​gì?

Có gì mới

  • Tin tức
  • Nền tảng ứng dụng Oracle
  • Oracle hỗ trợ Ukraine
  • Oracle Red Bull Racing
  • Sự bền vững của Oracle
  • Nền tảng kinh nghiệm nhân viên

    • © 2022 Oracle
    • Quyền riêng tư/Không bán thông tin của tôi/Do Not Sell My Info
    • Lựa chọn quảng cáo
    • Sự nghiệp